Considering the behavior of dynamic and lexical bound variables, I understand the output of symbol-value
in the following code (dynamically bound variable a
is shadowed by a lexical bound variable a
(that explanation is wrong, see edit below)):
(defvar a 1)
(let ((a 2))
(list a (symbol-value 'a)))
; => (2 2)
But when using progv
to create a similar environment, symbol-value
gives a different result:
(progv '(x) '(1)
(let ((x 2))
(list x (symbol-value 'x))))
; => (2 1)
Why is (symbol-value 'x)
returning 1
in the second example?
final edit accompanying the accepted answer: throughout comments at Rainer Joswig's answer I learnt that (let ((a 2)) ... )
does not bind a lexical variable, but shadows the value of the former dynamic binding. Also Martin Buchmann pointed out, in a comment, that symbol-value
ignores lexical variables.
The PROGV
special form creates dynamic bindings, but does not declare the variable to be special for enclosed forms.
Thus we need to declare the LET
binding of the variable x
to be special:
CL-USER 27 > (progv '(x) '(1)
(let ((x 2))
(declare (special x))
(list x (symbol-value 'x))))
(2 2)
DEFVAR
OTOH declares its variable to be special. Globally and there is no direct way to undo that declaration.