This question is an extension of Common Lisp scoping (dynamic vs lexical)
I have read and (hopefully) understood the concepts of scoping and extent in Common Lisp (link: https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node43.html), but I am unable to get my head around the following three examples. All examples are run on a fresh lisp session in SBCL/Slime/Emacs.
Example 1: Prints 5 & 5
(defvar x 100)
(defun fun1 (x)
(print x)
(fun2))
(defun fun2 ()
(print x))
(fun1 5)
Example 2: Prints 5 & 100
(defun fun1 (x)
(print x)
(fun2))
(defun fun2 ()
(print x))
(defvar x 100)
(fun1 5)
Example 3: Prints 5 & 5 & 100
(defvar x 100)
(defun fun1 (x)
(print x)
(fun2))
(defun fun2 ()
(print x))
(defvar x 100)
(fun1 5)
x
I understand why fun1 always prints 5 (due to lexical scope, but please correct if I'm wrong). What I don't understand is why fun2 prints 5 in Example 1, 100 in Example 2 and again 5 in Example 3?
- Example 1: x, a variable with indefinite scope, is set to 5 in fun1 and accordingly fun2 access this value. Is this a correct interpretation?
- Example 2: x is set to 100 by defvar, but why is not being re-set to 5 when fun1 is called? I thought the bindings took place when the functions are called or is it when they are defined? It appears that x is not yet bound when fun1 is defined, and therefore the binding of x in fun1 (which is lexically scoped) is not seen by the rest of the program and then the "global" binding takes place with the subsequent defvar. Is the behaviour x in the function call then due to lexical shadowing in fun1 but no dynamic shadowing for fun2? I.e. there are two different instances of x here since fun1 defined its x first and did not see a "global" x at the time.
- Example 3: It appears here that since x is set globally first, both fun1 and fun2 are referencing the same instance of x and hence its value is updated during fun1 and applied also during fun2 (both are 5)? Furthermore I get 100 when I ask for the value of x at the end (why? when fun2 is returning 5?)
It has something to do with the following extract from Guy Steel's Common Lisp book, but I cannot get my head around it:
"Constructs that use lexical scope effectively generate a new name for each established entity on each execution. Therefore dynamic shadowing cannot occur (though lexical shadowing may). This is of particular importance when dynamic extent is involved."
Is the following statement always true (source: https://courses.engr.illinois.edu/cs421/sp2010/lectures/dynamicscope.pdf):
The binding rule in Lisp is this: a use of a name is bound to the most recent declaration of that name that is still live.
I'm starting to understand some of the parts, but cannot get a wholistic understanding of all three parts, so it would be very helpful if you could help.