;;;  Show the difference between static and dynamic scope
;;;  File:  Static-Dynamic.lsp

(setq ff "C:/Temp/Static-Dynamic.lsp") (terpri)

;;;  -------------------------------------------------------------

;;;  This function binds x and y
(defun static (x y) (inner1 (* 2 x) y) )

;;;  Here's a function that binds a and y
;;;  Note that x is NOT bound to anything at this point
;;;  because Common LISP uses static (lexical) scope
(defun inner1 (a y)
    (print "Static Demo:")
    (print (list "a is" a))
    (print (list "y is" y))
    ;; (print (list "x is" x))   can't work -- lexical scope
    "End Static Demo")

;;;  Demonstrate static binding
(print (static 11 33))

(terpri)

;;;  -------------------------------------------------------------

;;;  This function binds xx and yy, then it defines
;;;  two dynamic variables x and y, and initializes them
(defun dynamic (xx yy) (progv '(x y) (list xx yy) (inner2 (* 2 x) y) )) 

;;;  This function binds a and y
;;;  and it has access to the dynamically bound x
(defun inner2 (a y)
    (print "Dynamic Demo:")
    (print (list "a is" a))
    (print (list "y is" y))
    (print (list "x is" x))   ;  works fine -- dynamic scope
    "End Dynamic Demo")

;;;  Demonstrate dynamic binding
(print (dynamic 11 33))

(terpri)

;;;  -------------------------------------------------------------

;;; The execution output from this program is:
;;;
;;;    T
;;;    > (load "C:/Temp/Static-Dynamic.lsp")
;;;    ; loading "C:/Temp/Static-Dynamic.lsp"
;;;    
;;;    "Static Demo:"
;;;    ("a is" 22)
;;;    ("y is" 33)
;;;    "End Static Demo"
;;;    
;;;    "Dynamic Demo:"
;;;    ("a is" 22)
;;;    ("y is" 33)
;;;    ("x is" 11)
;;;    "End Dynamic Demo"
;;;    
;;;    T
;;;    > (exit)
