[racket] Macro Problem

From: Eric Tanter (etanter at dcc.uchile.cl)
Date: Thu Jul 8 19:26:01 EDT 2010

btw I forgot to say that the macro stepper of drscheme is great to see this at work. If you try on your example, you'll see that the 'return' identifier in (lambda (return) ...) is not the same color as the 'return' identifier in your test.

-- Éric


On Jul 8, 2010, at 6:59 PM, Eric Tanter wrote:

> That's an hygiene issue: syntax-rules is hygienic, meaning (in that case) that a binding instance introduced by the macro does not capture instances in the original code. 
> 
> You need to circumvent hygiene to do what you're after; for this, you need to use syntax-case.
> 
> You can look at chapter 36 of PLAI:
> http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs
> 
> -- Éric
> 
> 
> On Jul 8, 2010, at 6:42 PM, Manu wrote:
> 
>> Hello
>> 
>> I am having a problem with the following macro:
>> 
>> (define-syntax lambda-r
>>  (syntax-rules ()
>>    ((_ args exp ...)
>>     (lambda args
>>       (call-with-current-continuation
>>        (lambda (return)
>>            exp ... ))))))
>> 
>> it's meant to define a lambda-r form, which wraps a lambda in call/cc, so I can use a "return-like" operator.
>> 
>> The following is an example of using lambda-r:
>> 
>> 
>> (define test-return
>>  (lambda-r ()
>>            (let ((input (read)))
>>              (if (number? input)
>>                  (if (> input 0)
>>                      (begin 
>>                        (display "positive")
>>                        (return input))                        ;; if input is > 0 this should escape out of the procedure
>>                      (display "negative or zero"))
>>                  (display "not a number"))
>>              (display "no return")                         ;; if input is > 0 this shouldn't get displayed
>>              )))
>> 
>> I get the following error when I run the previous example (and enter a positive integer):
>> 
>> => reference to undefined identifier: return
>> 
>> The puzzling thing is that if I run the macro expansion (as shown by the Macro Stepper), it works !
>> Here is the macro expansion:
>> 
>> (define test-return
>>  (lambda ()
>>    (call-with-current-continuation
>>     (lambda (return)
>>       (let ((input (read)))
>>         (if (number? input)
>>           (if (> input 0)
>>             (begin (display "positive") (return input))
>>             (display "negative or zero"))
>>           (display "not a number"))
>>         (display "no return"))))))
>> 
>> 
>> What I am missing ?
>> 
>> Thanks
>> 
>> M
>> _________________________________________________
>> For list-related administrative tasks:
>> http://lists.racket-lang.org/listinfo/users
> 
> _________________________________________________
>  For list-related administrative tasks:
>  http://lists.racket-lang.org/listinfo/users



Posted on the users mailing list.