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