If we define a function something like
(defun foo(x)
(setf x somevalue))
Is x defined as a local variable or global? using setf/q is setting the value to be global.
if it is global can anyone tell me how to define a local variable in lisp other than let?
Thanks!
Consider the following example
(let ((x 0))
(defun foo (y)
(when (equal x 0) (setq x y))
(when (< x y) (setq x y))
x))
when I am giving some input to foo like (foo 2) , it is returning 2 and if we execute the function again with (foo 1) it still returns 2 and (foo 3) returns 3.This is what i actually want it do.But the question is how is this possible, because if I try to access the variable x outside the function from the clisp terminal, I am unable to.If I am accessing the function again, it seems to retain the previous value of x.
thank you!
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:
is equivalent to
Note also that indeed reading your code fragment it’s possible that
xis in a sense a “global variable” because it could have been declared special: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 orlet.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:
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
setqandsetf. Things are a bit tricky here because you need to understand lower levels of Lisp to see whysetqis needed. If you are using Common Lisp then you should simply forget aboutsetqand always usesetf.setfis a macro that will expand tosetqwhen needed (however alsosetqcan change intosetfwhen 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”:this function returns a function that will keep adding the passed value to an internal totalizer:
the output will be 13 (10 + 3), 22 (13 + 9) and 33 (22 + 11).
The anonymous function “captured” the local variable
xand can use it even after exiting theadderfunction. 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).