On 02/01/2012 09:45 AM, Rüdiger Asche wrote:
Hi there,
I'm trying to get a grip on macros. Here is a very simple Racket expression
(1):
(letrec [(a 2)
(b 3)
(afn (lambda (x) (+ x a)))
(bfn (lambda (x) (+ x b)))]
(afn (bfn 2)))
Now I need a syntactic abstraction for afn and bfn. The following will do in
first approximation (2):
(define-syntax-rule (absfn varname) (lambda (x) (+ x varname)))
(letrec [(a 2)
(b 3)
(afn (absfn a))
(bfn (absfn b))]
(afn (bfn 2)))
However, it will fail due to scoping rules in the following example (3):
(define-syntax-rule (absfn varname) (lambda (x) (+ (+ x localc) varname)))
(letrec [(a 2)
(b 3)
(localc 4)
(afn (absfn a))
(bfn (absfn b))]
(afn (bfn 2)))
In other words, my syntactic extension absfn needs to be embedded in the namespace of the
sorrounding expression (or as a "dumb" macro which simply does lexical
replacement without considering scoping, but needless to say such a macro would be
unhygienic).
I suspect that letrec-syntax was meant for that purpose, but I can't figure out
how the parameters to define-syntax-rule would translate to those of
letrec-syntax.
Does anyone have sample code for how to get (3) above to work?
Thanks!
The easiest way is to use internal definitions instead:
(let ()
(define a 2)
(define b 3)
(define localc 4)
(define-syntax-rule (absfn varname)
(lambda (x) (+ (+ x localc) varname)))
(define afn (absfn a))
(define bfn (absfn b))
(afn (bfn 2)))
Another way is to use letrec-syntaxes+values, as Matthias answered.
Ryan
____________________
Racket Users list:
http://lists.racket-lang.org/users