If we define a function something like
(defun foo(x)
(setf x somevalue))
Is x
defined as a local variable or global? using setf/
To draw a parallel to other languages like C, C++, Java or Python what your code changes is a "local variable" even if this is not a wording that a Lisper would use (the wording in Lisp parlance would be a local "binding").
You can create local variables by using function parameters like your example does, or using some standard forms like:
(let ((x 12)) ...)
(do ((x 0 (1+ i))) ...)
(dotimes (x 10) ...)
(loop for x from 0 to 10 do ...)
On the other hand it is possible that in your implementation all local variables are created using parameters and other forms simply are macros expanding to that. For example:
(let ((x 10)) ...)
is equivalent to
(funcall (lambda (x) ...) 10)
Note also that indeed reading your code fragment it's possible that x
is in a sense a "global variable" because it could have been declared special:
(defvar x 12)
;; ==> x
(defun bar ()
(format t "The value of x is ~a" x))
;; ==> bar
(defun foo (x)
(bar))
;; ==> foo
(foo 42)
The value of x is 42
;; ==> NIL
x
;; ==> 12
If you declare a variable "special" using (defvar ...)
it will be handled differently: it's like every time you use it as a parameter or you use it in a (let ..)
form what the code will do is saving the current value, using the new provided value and then restoring the value after you exit the function or let
.
So those variables are both "global" (because outer functions can see them) but also local (because after your function or let terminates the previous value will be restored).
The standard convention is to name special variables with "earmuffs" i.e. with an asterisk both at the start and at the end of the name like:
(defvar *x* 12)
This helps who reads your code to understand that the variable is special. Note that however this is not mandated by the language and any name can be used for a special variable.
There is nothing similar to special variables in C, C++, Java or Python.
One last note about setq
and setf
. Things are a bit tricky here because you need to understand lower levels of Lisp to see why setq
is needed. If you are using Common Lisp then you should simply forget about setq
and always use setf
.
setf
is a macro that will expand to setq
when needed (however also setq
can change into setf
when needed (symbol macros) and this is where things may get confusing for a newbie).
Your last example is a case of a "closure". When you define a function (either named or unnamed with a (lambda ...)
form) the function can "capture" the variables that are visible and use them later. A simpler case often shown is the "adder":
(defun adder (x)
(lambda (y) (incf x y)))
this function returns a function that will keep adding the passed value to an internal totalizer:
(let ((f (adder 10)))
(print (funcall f 3))
(print (funcall f 9))
(print (funcall f 11)))
the output will be 13 (10 + 3), 22 (13 + 9) and 33 (22 + 11).
The anonymous function "captured" the local variable x
and can use it even after exiting the adder
function. In languages like C, C++ or Java a local variable cannot survive when you exit the scope that defined the variable.
C++11 has unnamed functions, but still variables cannot be captured and survive the scope (they can be copied to local variables of the unnamed function, but this is not the same thing).