In: Computer Science
Dynamic scope is an alternative to passing parameters or mutating global variables. The values of local variables can be “passed” from function to function through dynamically embedded scopes. For the following lines of Lisp, state your guess for the output before running it, and then run it. Explain what you see by drawing a call stack trace:
(defvar *x* 0)
(defun main () (foo) (print *x*))
(defun foo () (let ((*x* 1)) (bar) (print *x*)))
(defun bar () (incf *x*) (bazz))
(defun bazz () (incf *x*) (baz))
(defun baz () (incf *x*))
(main)
The code first prints 4 and then 0. Here is the call stack trace:
X = 0
Entered main ()
Entered foo()
LET X = 1 ------- creates a new binding for X, applicable only while inside foo ()
Entered bar ()
X incremented to 2
Entered bazz ()
X incremented to 3
Entered baz ()
X incremented to 4
Exited baz ()
Exited bazz ()
Exited bar ()
print X ------------------------> prints as 4, the value of the global variable at this time
Exited foo (value of X assigned via LET on entering foo is no longer applicable)
<Implicitly, X takes on the older value before entering foo> X = 0
print X ----------------------> prints as 0
Exited main ()