[racket] help: how to make eval see local bindings?
This sounds a bit confused. Allow me to tease out a clarification.
1. If you write a macro like this:
(define-syntax mym
(syntax-rules ()
[(_ input ...)
(let* ([x 10])
(lambda (stuff)
input ... ;; line 2
x))]))
'hygiene' gives you a couple of different things:
-- the x and the stuff introduced in the macro doesn't accidentally interfere with free variables in input ... on line 2
-- the let* and the lambda are guaranteed to refer to the meaning in place where you define the macro
2. So when you run this expression in the context of mym
(let ([x 42]) ;; line 9
((mym (displayln x)) ;; line 7
'random-argumnent))
you see
-- the output 42 from the displayln on line 7
-- the result 10 from the line below line 2
3. It is rare that mym needs to generate code involving the x on line 9 WITHOUT specifying the x in an input position for mym.
QUESTION: can you explain why you'd want to do so?
POSSIBLE ANSWER: you may wish to break hygiene then.
4. It is equally rare that you want let* or lambda to mean what the context of the macro call says they are.
IF THIS IS WHAT YOU WANT, can you provide more details.
On Jul 11, 2011, at 11:04 AM, Maurizio Giordano GMAIL wrote:
> On Mon, 2011-07-11 at 13:43 +0100, Noel Welsh wrote:
>> On Mon, Jul 11, 2011 at 1:26 PM, Maurizio Giordano GMAIL
>> <maurizio.giorda at gmail.com> wrote:
>>> PS. my lambda is generated by a macro (define-syntax) ...
>>> this is why I use eval to generate the corresponding procedure.
>>
>> If this is the case I don't think you need to use eval. You either
>> need to write your macro in a hygenic way -- it accepts as parameters
>> all the identifiers in the enclosing environment that is should
>> reference -- or you should explicitly break hygiene. If you're new-ish
>> to Racket the preceeding sentence probably won't make any sense, so
>> feel free to ask for more help!
>>
>> Cheers,
>> N.
>
> Hi Nole,
> Yes, I am an absolute new-ish to racket... I would like to know more
> about writing a macro by "explicitly break hygiene".
> I supposed I didn't need to use eval... but for me it is
> the easiest way to "build" a lambda-code and then evaluate it.
>
> I want to give you more details about my problem.
> I have a macro like this:
>
> (define-syntax mymacro
> (syntax-rules (mymacro)
> [(mymacro input ...)
> (let* (...)
> (eval `(lambda (cntx)
> ... ; a code generated according to macro
> "input ..."
> (+ x 2) ; that contains references to an outside "x"
> symbol
> ...
> ))]))
>
> Note that I cannot foresee which extern symbols are referenced by the
> generated lambda.
> This macro returns a procedure.
> if I use my macro in a "let" construct, of course I have a "reference to
> an undefined identifier":
>
> (let* ((x 1)
> (f (mymacro ...)))
> (f 2))
> reference to undefined identifier: x
>
> So, coming back to my question: since the eval is called within the
> "let"
> scope, is it possible to make it aware of the bindings of the "let"?
> Do you know alternative mechanism to do that?
>
> TIA,
> Cheers,
>
> Maurizio.
>
> _________________________________________________
> For list-related administrative tasks:
> http://lists.racket-lang.org/listinfo/users