I know that "eval" evaluates the argument without
visibility of the local environment where it is called.
so the following code has this error:
> (let ((x 1)) (eval '(+ x 1))
reference to undefined identifier: x
On contrary, if "x" is defined in the top environment, I have:
> (define x 2)
> (let ((x 1)) (eval '(+ x 1))
4
So the eval sees the global environment.
Can someone tell me if it possible to evaluate a
quoted expression in such a way all local bindings
(the "let" bindings" are visible to the eval?
In my case I need to eval a quoted lambda which uses
variables that "should" bound in the local environment ...
this is the code:
> (let ((x 1)
(f (eval '(lambda (y) (+ x y)))))
(f 2))
reference to undefined identifier: x
PS. my lambda is generated by a macro (define-syntax) ...
this is why I use eval to generate the corresponding procedure.
TIA,
Maurizio Giordano
_________________________________________________
For list-related administrative tasks:
http://lists.racket-lang.org/listinfo/users
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.
I'm not sure what you're trying to do, but leaving out both the eval and the
quote would seem to be what you want:
(let ((x 1)
(f (lambda (y) (+ x y))))
(f 2))
I don't know how that relates to your macro.
-- hendrik
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.
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.
(define-syntax mym
(syntax-rules ()
[(_ input ...)
(let* ([x 10]) ; at this time, I don't know if lambda will use "x", if "x" is bounded
; and (if bounded) which is the binding
(lambda (stuff)
input ... ;; line 2
x))]))
Now let's describe my project.(define-syntax replace
(syntax-rules (replace)
[(replace input ...)
(let* (...)
(eval `(lambda (cntx) ; the code of the "gamma-rule"
...
))]))
Now the problem... In the previous example I can define a rule like
this:Have you tried just returning the lambda as is from the macro?
> <btn_viewmy_160x25.png>
Now I don't understand at all why you want to use eval in the macro.
If the right-hand side just returned the lambda that you have there,
it would automatically capture the variables in the context of the
gama rule.
Have you tried just returning the lambda as is from the macro?
Hi Matthias, hi schemers,2011/7/11 Matthias Felleisen <matt...@ccs.neu.edu>
Now I don't understand at all why you want to use eval in the macro.
If the right-hand side just returned the lambda that you have there,
it would automatically capture the variables in the context of the
gama rule.Have you tried just returning the lambda as is from the macro?I tried but it doesn't work! Here you find a sample of what you suggest:---------------(define-syntax mymacro(syntax-rules (prova)[(mymacro input ...)(lambda (z) (list input ...) (+ z extern-var))]))> (let* ((extern-var 2) (f (mymacro x y))) (f 1))reference to undefined identifier: extern-var
Here is what I meant:
#lang racket
(define-syntax-rule(mm x)(lambda (w) (displayln `(,x)) (+ w x)))
(define f(let ([a 10])(mm a)))
(f 42)
Hi Matthias,
... I will play with your example (it is better than all the words I spent with my looong
description:Ok, fine!
Here is what I meant:
#lang racket
(define-syntax-rule(mm x)(lambda (w) (displayln `(,x)) (+ w x)))Let me define my function in a inner scope:
(define f(let ([a 10])(mm a)))
(f 42)
> (let ((othervar 2)
(f (mm (+ 1 othervar))))
> (f 1)
it should print 4 but it gives the undefined identifier error.
If I define "othervar" globally (top env) it works (of course!).