I read a relevant post on binding, however still have questions.
Here are the following examples I found. Can someone tell me if the conclusions are correct?
Dynamic Binding of x in (i):
(defun j ()
(let ((x 1))
(i)))
(defun i ()
(+ x x))
> (j)
2
Lexical Binding of x in i2:
(defun i2 (x)
(+ x x))
(defun k ()
(let ((x 1))
(i2 2)))
> (k)
4
No Global Lexical Variables in ANSI CL so Dynamic Binding is performed:
(setq x 3)
(defun z () x)
> (let ((x 4)) (z))
4
Dynamic Binding, which appears to bind to a lexically scoped variable:
(defvar x 1)
(defun f (x) (g 2))
(defun g (y) (+ x y))
> (f 5)
7
Based on the above tests, CL first tries lexical binding. If there is no lexical match in the environment, then CL tries dynamic binding. It appears that any previously lexically scoped variables become available to dynamic binding. Is this correct? If not, what is the behavior?
This is actually undefined behavior in Common Lisp. The exact consequences of using undefined variables (here in function
i) is not defined in the standard.As you see, the Lisp interpreter (!) complains at runtime.
Now:
SETQsets an undefined variable. That's also not fully defined in the standard. Most compilers will complain:LispWorks
or SBCL
No,
xis globally defined to be special byDEFVAR. Thusfcreates a dynamic binding forxand the value ofxin the functiongis looked up in the dynamic environment.Basic rules for the developer
*around them, so that it is always visible when using them, that dynamic binding&lookup is being used. This also makes sure that one does NOT declare variables by accident globally as special. One(defvar x 42)andxwill from then on always be a special variable using dynamic binding. This is usually not what is wanted and it may lead to hard to debug errors.