3

I'm trying to eval a list with variables inside a macro function that defines a variable in a lambda but the eval in it can't

(define-syntax MYVAR
    (syntax-rules ()
        [(_ varname value body ...) ((lambda (varname) body ...) value)]))

(define mylist '(list P Q))
(print mylist)
(MYVAR P 1 
    (MYVAR Q 2
        (print P Q) ;;everything prints fine in here
        (print (eval mylist))))


<eval>    ((lambda2127 (P) (MYVAR Q 2 (print P Q) (print (eval mylist)))) 1)
<eval>    ((lambda2129 (Q) (print P Q) (print (eval mylist))) 2)
<eval>    (print P Q)
<eval>    (print (eval mylist))
<eval>    (eval mylist)
<syntax>      (list P Q)
<eval>    (list P Q)    <--

=> Error: unbound variable: P

I assume eval tries to evaluate before my macro compiles but not sure,

is there a way to reuse a list and evaluate it inside a macro?

I have tried to use define-for-syntax but the same error arises

shuji
  • 7,369
  • 7
  • 34
  • 49
  • Since you didn't give an environment argument to `eval`, it evaluates in the top-level environment, not the local environment where `P` and `Q` are bound. – Barmar Feb 09 '19 at 06:28
  • 1
    The macro is irrelevant. You would have the same problem if you wrote `(let ((P 1)(Q 2)) (print (eval mylist)))`. – Barmar Feb 09 '19 at 06:31
  • What Barmar said. Eval uses the top-level environment, whereas P and Q exist in the lexical context where eval is called. Eval is just a procedure, it does not have access to the lexical context where it is called. – sjamaan Feb 27 '19 at 19:13

1 Answers1

0

I'd recommend that you try:

(MYVAR P 1
    (MYVAR Q 2
        ((print (eval 'mylist)))))

After this your output should be

(list P Q)

Why did this work? In Scheme, code is nested using parentheses.

So, for example

(print (eval (list 1 2 3)))

Scheme will try and find the definition of 1 and pass 2 and 3 as arguments.

Whereas

(print (eval '(list 1 2 3)))

Will print

(list 1 2 3)

In short, the single quote is like an escape character.

Ed The ''Pro''
  • 875
  • 10
  • 22