[racket] Advice on a macro for mutating structs
You could fake it:
(require (for-syntax syntax/parse))
;; Syntax SyntaxList SyntaxList -> [Listof (list String Syntax Syntax)]
;; create association list mapping field names to getters and setters [option]
(define-for-syntax (field-association-list sn getters setters)
(define sn-str (+ (string-length (symbol->string (syntax->datum sn))) 1))
(define getters-lst (syntax->list getters))
(define setters-lst (syntax->list setters))
(for/list ((x getters-lst) (y setters-lst))
`(,(substring (symbol->string (syntax->datum x)) sn-str) ,x ,y)))
(define-syntax (increment! stx)
(syntax-parse stx
[(_ s sn:id fn:id i)
(with-syntax ([(_ _ _ getters setters _) (extract-struct-info (syntax-local-value #'sn))])
(define gets-sets (field-association-list #'sn #'getters #'setters))
(define get-set-f (assoc (symbol->string (syntax-e #'fn)) gets-sets))
(cond
[(boolean? get-set-f) (raise-syntax-error #f "unknown field-name: ~a" stx)]
[else
(define-values (_ getter setter) (apply values get-set-f))
(if (boolean? setter)
(raise-syntax-error #f (format "~s not mutable" (syntax-e #'fn)) stx)
#`(#,setter s (+ (#,getter s) i)))]))]
[(increment! s sn fn) #'(increment! s sn fn 1)]))
On Jul 28, 2011, at 3:08 PM, Tom McNulty wrote:
>
> On 2011-07-28, at 12:43 PM, Eli Barzilay wrote:
>
>> 7 minutes ago, Matthias Felleisen wrote:
>>>
>>> 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.
>>
>> Ah, you're right.
>>
>>
>>> 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:
>
> Matthias: Sorry I worded that poorly. I was looking to retrieve the accessors and mutators from the structure and field names in the macro, but that information is not retained.
>
>>
>> That's how Tom started, and I didn't follow the intention of using the
>> field name and suggested using the struct info.
>>
>> But the real thing that you (Tom) are fighting with is trying to use
>> field names, where the struct info is disregarding that and keeps
>> around just the getter and setter names.
>
> Other than possibly better error messages, I'm not sure then that the struct-info approach provides much (any?) benefit; for it still relies on knowing the accessor name. It also seems that accessors/mutators that do not follow the usual [set-]struct-field naming seem to be a rarity (certainly in my code).
>
>> Looks to me like a better
>> approach would be to use the getter names instead -- possibly with a
>> macro that makes more convenient getters?
>
> I thought about this approaching, using something similar to the key-word structures here, http://lists.racket-lang.org/users/archive/2010-December/043340.html
> but decided it'd be better to make something that works with vanilla structs.
>
>
> Thanks,
>
> - Tom.
>
>>
>> --
>> ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
>> http://barzilay.org/ Maze is Life!
>