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.