I know that when you want to make a dynamic/global binding in Lisp, you use either defparameter or defvar. I also know that you can make lexical bindings, well, almost everywhere, using defun argument lists or let statements.
What I'm wondering is what exactly it is I make when I make a statement like this where x was not declared or used anywhere else in the code:
(setf x 10 )
This appears to work fine, and x doesn't seem to behave like a lexical variable. Is it actually a dynamic global, the same as if I'd used defparameter or defvar, or is it something else entirely?
setf is actually a macro that examines an access form and produces a call to the corresponding update function. Given the existence of setf in Common Lisp, it is not necessary to have setq, rplaca, and set; they are redundant. They are retained in Common Lisp because of their historical importance in Lisp.
1. What is the difference between setf and setq? Explanation: Setq is used only for setting the values of symbols but setf can be used for anything. Setf can be used for setting value of any data-type and not only symbols.
Sets the value of a symbol or symbols to associated expressions. (setq sym expr [sym expr]...) This is the basic assignment function in AutoLISP. The setq function can assign multiple symbols in one call to the function.
Generalized variables are analogous to lvalues in the C language, where ' x = a[i] ' gets an element from an array and ' a[i] = x ' stores an element using the same notation. Just as certain forms like a[i] can be lvalues in C, there is a set of forms that can be generalized variables in Lisp.
What it actually does is unspecified in the ANSI Common Lisp standard.
Generally I prefer any CL implementation to just set the dynamically bound value or global value. It should not to do anything else. CMUCL by default seemed to think that it was a good idea to declare the symbol special then. But that was a bad idea, since there was no obvious way to get rid of a global special declaration.
So, typically I would expect something like this (here, LispWorks):
CL-USER 66 > (defun foo () (setf x44 10))
FOO
The global variable is still unbound:
CL-USER 67 > x44
Error: The variable X44 is unbound.
1 (continue) Try evaluating X44 again.
2 Specify a value to use this time instead of evaluating X44.
3 Specify a value to set X44 to.
4 (abort) Return to level 0.
5 Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.
CL-USER 68 : 1 > :top
Let's call the function:
CL-USER 69 > (foo)
10
Now it has a global value:
CL-USER 70 > x44
10
But the variable is not declared to be special (as it would be by DEFVAR
or DEFPARAMETER
). Here a lexical binding is established.
CL-USER 71 > (let ((x44 20)) (foo) x44)
20
When we declare the local variable to be special, then our function changes the binding:
CL-USER 72 > (let ((x44 20)) (declare (special x44)) (foo) x44)
10
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With