Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

common-lisp

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!

like image 425
Svarog Avatar asked Jul 24 '12 18:07

Svarog


2 Answers

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.

like image 51
Lex Avatar answered Nov 15 '22 07:11

Lex


DEFVAR declares its variables special. Globally, everywhere. You can also not remove this easily.

That's also the reason you should never use common names like x, i, list as variable names for DEFVAR. Make sure that you use *x*, *i* and *list* instead. Otherwise all variables, even local ones, with these common names are declared special.

like image 21
Rainer Joswig Avatar answered Nov 15 '22 07:11

Rainer Joswig