Hi,
I have in my toolbox the macro auto-hash-ref/:
, defined here. Essentially, the idea is to automatically search for a variable value in a hash table. For example:
(define ht (hash 'a 1 'b 2))
(auto-hash-ref/: ht (+ :a (* 2 :b)))
The second line of this example expands to the following:
(let ([:a (hash-ref ht 'a)]
[:b (hash-ref ht 'b)])
(+ :a (* 2 :b)))
Now I would like to wrap auto-hash-ref/:
in another macro to make function definition easier. I write the following code (everything is in Typed Racket):
(define-syntax-parse-rule (lambda/: (ht:id type:expr) body:expr)
(lambda ([ht : type])
(auto-hash-ref/: ht body)))
I try to use this macro in the following way:
(lambda/: (st (HashTable Symbol Integer)) (+ :a :b))
and I get the error (trimmed):
; :a: unbound identifier
; in: :a
I compared the final expansion (obtained via Racket Mode's macro stepper) of auto-hash-ref/:
and lambda/:
. For (auto-hash-ref/: s (+ :a :b))
I obtain
(let-values (((:a) (#%app hash-ref (#%top . s) 'a))
((:b) (#%app hash-ref (#%top . s) 'b)))
(#%app + :a :b))
For (lambda/: (st (HashTable Symbol Integer)) (+ :a :b))
I obtain
(#%expression
(lambda (st)
(let-values (((:a) (#%app hash-ref st 'a)) ((:b) (#%app hash-ref st 'b)))
(#%app + (#%top . :a) (#%top . :b)))))
I remark that :a
and :b
in the second expansion are wrapped in #%top
, which I think means that Racket looks for bindings for :a
and :b
in the wrong place.
How should I correctly write the macro lambda/:
?