For completeness, I asked a Common Lisper about CL dynamic variables. Here is how CL dynamic variables work:
All correct.
In addition to defvar and defparameter (which are almost synonymous) you can also make ad-hoc dynamic variables with (declare (special my-var)):
(defun special-test () (labels ((print-value-of-foo () (declare (special foo)) (print foo))) (let ((foo 123)) (declare (special foo)) (print-value-of-foo))))
(defvar a nil)
(defun special-test-2 () (labels ((print-value-of-a () (print a) ;; These would not work since b and c are lexical: ;; ;;(print b) ;;(print c) )) (multiple-value-bind (a b c) (values 1 2 3) (print-value-of-a))))
CLHS: http://www.lispworks.com/documentation/HyperSpec/Body/d_specia.htm#special
CL also has a standard concept of dynamic extent (dynamic scope is for bindings; dynamic extent is for values), as well as a declaration to go with it: http://www.lispworks.com/documentation/HyperSpec/Body/d_dynami.htm#dynamic-extent
E.g. with-open-file (http://www.lispworks.com/documentation/HyperSpec/Body/m_w_open.htm): "The stream object to which the stream variable is bound has dynamic extent; its extent ends when the form is exited."