[racket] Advice on a macro for mutating structs
On Jul 28, 2011, at 2:10 PM, Tom McNulty wrote:
> I was hoping that I could locate the getter (and setter) with just the field and structure type but that information doesn't seem to be possible.
I don't understand your request but if you are giving me the structure name and the structure field, you can write a context-sensitive macro:
(require (for-syntax syntax/parse))
(define-syntax (incr! stx)
(syntax-parse stx
[(_ s st:id fd:id i)
(let ([setter (datum->syntax #'st (string->symbol (format "set-~a-~a!" (syntax-e #'st) (syntax-e #'fd))))])
#`(#,setter s i))]))
(struct box ((x #:mutable)))
(define b (box 1))
(incr! b box x 2)
(displayln (box-x b))
Problem is this blows up with the wrong error message.
Also, you may wish to test failure cases like this:
(with-handlers ((exn:fail:syntax? (lambda (x) (string=? (exn-message x) "increment!: pounds not mutable"))))
(eval '(module _a racket/base
(require 'increment)
(struct vault ([dollars #:mutable] pounds [euros #:mutable]))
(increment! v vault pounds)))
(displayln "test failed"))
That way you don't have to comment them out. Abstract suitably.