Let\'s say I have a special var:
(defvar x 20)
then I do the following:
(let ((x 1)) (eval \'(+ x 1))
whi
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.
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.