eval form supposed to evaluate a given form in a null lexical environment, I don't get what I expect

common-lisp

Solution

in your example `x` is `special` which means it is bound in the dynamic environment

`y` is not special, so it is bound in the lexical environment

so at the time of the first `eval` the environments could be represented like this:

dynamic environment:  { x : 1 } -> { x : 20, ...other global variables... } -> nil
lexical environment:  nil

the symbol `x` is special so `eval` looks up `x` in the current dynamic environment and finds `x = 1`

assuming it was run in same lisp as the last example, the environment of your second `eval` looks like this:

dynamic environment: { x : 20,  ...other global variables... } -> nil
lexical environment: { y :  1 } -> nil

the symbol `y` is not special so `eval` looks up `y` in the null lexical environment -- not the current lexical environment -- and finds nothing.

this makes sense when you realize that lisp is usually compiled, and the lexical environment can be optimized down to simple `mov` instructions in some cases.

Problem

Let's say I have a special var: ``` (defvar x 20) ``` then I do the following: ``` (let ((x 1)) (eval '(+ x 1)) ``` which evaluates to 2. According to CLHS, eval "Evaluates form in the current dynamic environment and the null lexical environment". So, I would expect to get 21 instead of 2. Am I missing something? Now if I have no dynamic binding for symbol y, evaluating ``` (let ((y 1)) (eval '(+ y 1)) ``` I get condition: "The variable Y is unbound", which makes sense, since there is no dynamic binding for y. Note: I'm using SBCL 1.0.57 Appreciate your help in advance!

Original source