[plt-scheme] macro question

From: Jos Koot (jos.koot at telefonica.net)
Date: Sat Jun 7 06:13:46 EDT 2008

----- 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?

That depends on the language you are using.
Apparently you should use datum->syntax-object indeed.

Jos





> 
> 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.