Abdulaziz Ghuloum wrote:

On May 23, 2009, at 3:37 PM, Eduardo Cavazos wrote:

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.


You can write

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

which translates to a define-record-type followed by your set of additional definitions.

In addition to per field changers, I'm also interested in a record cloner and record assigner. This takes care of the cloner and assigner:

(define-syntax define-record-type++

  (syntax-rules (fields mutable)

    ( (define-record-type++ (name constructor predicate cloner assigner)
        (fields (mutable field accessor mutator)
                ...))

      (begin

        (define-record-type (name constructor predicate)
          (fields (mutable field accessor mutator)
                  ...))

        (define (cloner record)
          (constructor (accessor record)
                       ...))

        (define (assigner a b)
          (mutator a (accessor b))
          ...)) )))

And using it to make the rgba record type:

(define-record-type++ (rgba make-rgba rgba? rgba-clone rgba-assign!)
  (fields (mutable red   rgba-red   rgba-red-set!)
          (mutable green rgba-green rgba-green-set!)
          (mutable blue  rgba-blue  rgba-blue-set!)
          (mutable alpha rgba-alpha rgba-alpha-set!)))

Another variant with support for cloner, assigner, and changers:

(define-syntax define-record-type++

  (syntax-rules (fields mutable)

    ( (define-record-type++ (name constructor predicate cloner assigner)
        (fields (mutable field accessor mutator changer)
                ...))

      (begin

        (define-record-type (name constructor predicate)
          (fields (mutable field accessor mutator)
                  ...))

        (define (cloner record)
          (constructor (accessor record)
                       ...))

        (define (assigner a b)
          (mutator a (accessor b))
          ...)

        (define (changer record procedure)
          (mutator record (procedure (accessor record))))
        ...

        ) )))

And the example:

(define-record-type++ (rgba make-rgba rgba? rgba-clone rgba-assign!)
  (fields (mutable red   rgba-red   rgba-red-set!   rgba-red-change!)
          (mutable green rgba-green rgba-green-set! rgba-green-change!)
          (mutable blue  rgba-blue  rgba-blue-set!  rgba-blue-change!)
          (mutable alpha rgba-alpha rgba-alpha-set! rgba-alpha-change!)))

At about that point syntax-case start to look attractive. :-) Or some editor macros.

Some people, when confronted with a problem, think "I know, I'll use syntax-case." Now they have two problems.

;-)

Really though, all the code for handling the define-record-type syntax is in 'psyntax.expander.ss'. It's a shame that this isn't available for reuse in cases like this where there's a need to extend a macro. Or make a new macro with similarish syntax. Well, yeah, I can cut and paste...

Ed

Reply via email to