http://*.com/questions/3855862/setq-and-defvar-in-lisp
defvar, let, setq的语法分析:
defvar
introduces a dynamic variable while setq
is used to assign a value to a dynamic or lexical variable. The value of a dynamic variable is looked up in the environment that calls the function, while the value of a lexical variable is looked up in the environment where the function was defined. The following example will make the difference clear:
;; dynamic variable sample
> (defvar *x* )
*X*
> (defun fx () *x*)
FX
> (fx)> (let ((*x* )) (fx)) ;; gets the value of *x* from the dynamic scope. > (fx) ;; *x* now refers to the global binding. ;; example of using a lexical variable
> (let ((y ))
(let ((fy (lambda () (format t "~a~%" y))))
(funcall fy) ;; =>
(let ((y ))
(funcall fy) ;; => , the value of lexically bound y
(setq y ) ;; => y in the current environment is modified
(funcall fy)) ;; => , the value of lexically bound y, which was
;; unaffected by setq
(setq y ) ;; => alue of the original y is modified.
(funcall fy))) ;; => , the new value of y in fy's defining environment.
Dynamic variables are useful for passing around a default value. For instance, we can bind the dynamic variable *out*
to the standard output, so that it becomes the default output of all io functions. To override this behavior, we just introduce a local binding:
> (defun my-print (s)
(format *out* "~a~%" s))
MY-PRINT
> (my-print "hello")
hello
> (let ((*out* some-stream))
(my-print " cruel ")) ;; goes to some-stream
> (my-print " world.")
world
A common use of lexical variables is in defining closures, to emulate objects with state. In the first example, the variable y
in the binding environment of fy
effectively became the private state of that function.
defvar
will assign a value to a variable only if it is not already assigned. So the following re-definition of *x*
will not change the original binding:
> (defvar *x* 400)
*X*
> *x*
100
We can assign a new value to *x*
by using setq
:
> (setq *x* 400)
400
400
> *x*
400
> (fx)
400
> (let ((*x* 500)) (fx)) ;; setq changed the binding of *x*, but its dynamic property still remains.
500
> (fx)
===========================================================================================
so, what's the difference between these functions?
===========================================================================================