[racket] Advice on a macro for mutating structs
Thanks Matthias, thats a lot cleaner than my version.
On 2011-07-28, at 1:19 PM, Matthias Felleisen wrote:
>
> 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!
>>
>