[plt-scheme] macro question

From: Michael Vanier (mvanier at cs.caltech.edu)
Date: Sat Jun 7 15:49:16 EDT 2008

Yet another argument for hygiene, as if we needed one.  I implemented your hygienic version and it 
works great.  Thanks again!

Mike

Jos Koot wrote:
> 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.