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

Reply via email to