Hello,

Today I finally had the need to explore the procedural and reflective facilities of R6RS records.

Suppose I have define this record type:

(define-record-type rgba
    (fields (mutable red)
            (mutable green)
            (mutable blue)
            (mutable alpha)))

I'd like to have a field "changer" procedure for each field. Something like this:

(define (rgba-red-change! color procedure)
  (rgba-red-set! color (procedure (rgba-red color))))

So the procedure passed to the changer accepts the old value of the field, returns the new value, and this new value is stored in the field by the changer.

To generate these changers, here's what I came up with:

 (define (field-changer rtd field-name)

   (let ((field-names (record-type-field-names rtd)))

     (let ((index (let loop ((i 0))
                    (if (eq? (vector-ref field-names i) field-name)
                        i
                        (loop (+ i 1))))))

       (let ((accessor (record-accessor rtd index))
             (mutator  (record-mutator  rtd index)))

         (lambda (record procedure)

           (mutator record (procedure (accessor record))))))))

So I can do:

(define rgba-red-change!
  (field-changer (record-type-descriptor rgba) 'red))

I think that's more or less the way to go about this. But if anyone has any suggestions, they're welcome.

Ed
PS: I coulda used vector-index from the vectors srfi, but it's not included in Ypsilon yet and this is for both Ikarus and Ypsilon.

Reply via email to