[plt-scheme] macro question

From: Jos Koot (jos.koot at telefonica.net)
Date: Sat Jun 7 07:11:16 EDT 2008

I should have added the following:
Be aware that the non hygienic macro requires the variable always to be 
called 'es'.
Use the hygienic version, which allows a variable of arbitrary name within 
the macro call.
Jos
----- Original Message ----- 
From: "Michael Vanier" <mvanier at cs.caltech.edu>
To: "Jos Koot" <jos.koot at telefonica.net>
Cc: "mzscheme Mailing List" <plt-scheme at list.cs.brown.edu>
Sent: Saturday, June 07, 2008 12:02 PM
Subject: Re: [plt-scheme] macro question


> But don't you mean datum->syntax-object, not datum->syntax?
>
> Michael Vanier wrote:
>> Thanks very much!
>>
>> Jos Koot wrote:
>>> 'es' introduced in the macro is not identified with the local variable 
>>> 'es' of the environment from which the macro is called. This is 
>>> hygienic. The hygienic behaviour avoids unintentional identifications. 
>>> Besides there might also hang around a global variable of the same name, 
>>> in which case your macro would identify 'es' with the global variable, 
>>> not the local one. Below two solutions, the first one non hygienic, the 
>>> second one hygienic by requiring the variable to be mentioned in the 
>>> macro call. In general hygienic solutions are to be preferred, I think.
>>> Jos
>>>
>>> (define-syntax (get-stack-vals stx)
>>>   (syntax-case stx ()
>>>   ((_ n (env first rest) expr ...)
>>>    #`(let*-values (((env stk) (es-values #,(datum->syntax stx 'es)))
>>>                    ((first rest) (take n stk)))
>>>        expr ...))))
>>>
>>> (define-syntax get-stack-vals
>>>   (syntax-rules ()
>>>   ((_ n (env first rest) es expr ...)
>>> ;                              ^^^
>>>    (let*-values (((env stk) (es-values es))
>>>                    ((first rest) (take n stk)))
>>>        expr ...))))
>>>
>>> ----- Original Message ----- From: "Michael Vanier" 
>>> <mvanier at cs.caltech.edu>
>>> To: "mzscheme Mailing List" <plt-scheme at list.cs.brown.edu>
>>> Sent: Saturday, June 07, 2008 11:17 AM
>>> Subject: [plt-scheme] macro question
>>>
>>>
>>>> I've run into a problem with a macro I don't know how to solve.  Here's 
>>>> the macro:
>>>>
>>>> (define-syntax get-stack-vals
>>>>   (syntax-rules ()
>>>>     ((_ n (env first rest) expr ...)
>>>>      (let*-values (((env stk) (es-values es))
>>>>                    ((first rest) (take n stk)))
>>>>        expr ...))))
>>>>
>>>> Here's a use:
>>>>
>>>> (define (do-def es)
>>>>   (get-stack-vals 2 (env first rest)
>>>>      (let ((sym (cadr first))
>>>>            (val (car first)))
>>>>        (if (symbol? sym)
>>>>            (let ((env2 (env-add env sym val)))
>>>>              (make-es env2 rest))
>>>>            (error "cannot define non-symbol: " sym)))))
>>>>
>>>> which should expand to:
>>>>
>>>> (define (do-def es)
>>>>   (let*-values (((env stk) (es-values es))
>>>>                 ((first rest) (take 2 stk)))
>>>>     (let ((sym (cadr first))
>>>>           (val (car first)))
>>>>       (if (symbol? sym)
>>>>           (let ((env2 (env-add env sym val)))
>>>>             (make-es env2 rest))
>>>>           (error "cannot define non-symbol: " sym)))))
>>>>
>>>> and apparently does, at least according to the macro stepper.  However, 
>>>> when I call do-def I get an error message: "reference to undefined 
>>>> identifier: es".  This seems odd, because es is in scope at the macro 
>>>> expansion location.  Is the es in the get-stack-vals macro bound in the 
>>>> lexical scope of that macro?  All the other external identifiers in the 
>>>> macro are bound at the top-level, so it works either way for them.  If 
>>>> this is the case, how do I get es to be bound the way I want it to be? 
>>>> I realize that I'm trying to do something a bit naughty since I'm 
>>>> assuming a binding for es will exist at all macro expansion locations; 
>>>> alternative suggestions are welcome (other than "don't give up your day 
>>>> job").
>>>>
>>>> I'm a macro newbie, so please be gentle ;-)  PLT Scheme's macro system 
>>>> is an intricate and beautiful thing that I'm just beginning to wrap my 
>>>> head around.
>>>>
>>>> Mike
>>>>
>>>>
>>>> _________________________________________________
>>>>  For list-related administrative tasks:
>>>>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>>>
>> _________________________________________________
>>  For list-related administrative tasks:
>>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme 



Posted on the users mailing list.