[plt-scheme] How to introduce a variable binding into a macro?

From: Jon Rafkind (workmin at ccs.neu.edu)
Date: Sat Sep 1 02:34:39 EDT 2007

Grant Rettke wrote:
> Hi I am looking at simple macros.
>
> Here is a macro to create a one argument function.
>
> (define-syntax =>
>   (syntax-rules {}
>     {(_ var body)
>      (λ (var) body)}))
>
> (define foo1 (=> x (+ x x)))
>
> I would like to abstract that for creating one arguments functions,
> where x is the variable bound to the argument of the function. I would
> like to be able to refer to that variable in the body of the function
> itself.
>
> First I tried this:
>
> (define-syntax \x
>   (syntax-rules {}
>     {(_ body)
>      (λ (x) body)}))
>
> (define foo2 (\x (+ x x)))
>
> That doesn't work as (I'm guessing) the body doesn't have 'x' within
> its scope. I would like to bind the argument of that function as x and
> introduce it to the scope of its body. The error message just says
> 'bad syntax'.
>
>   
define-syntax produces hygenic macros which means they do not introduce
any unwanted variables in scopes outside of the macro itself. To
introduce new identifiers you have to force the macro to be unhygenic
and one way to do that is with syntax-local-introduce.

(define-syntax (\x stx)
  (syntax-case stx ()
    ((_ body)
     (with-syntax ((x (syntax-local-introduce #'x)))
       #'(lambda (x) body)))))

(define q (\x (+ x x)))

(printf "~a\n" (q 3))
==> 6

There might be a more compact way of writing that, I dunno.


Posted on the users mailing list.