[plt-scheme] macro question
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