Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between LET and SETQ?

I'm programming on Ubuntu using GCL. From the documentation on Common Lisp from various sources, I understand that let creates local variables, and setq sets the values of existing variables. In cases below, I need to create two variables and sum their values.

Using setq

(defun add_using_setq ()   (setq a 3)  ; a never existed before , but still I'm able to assign value, what is its scope?   (setq b 4)  ; b never existed before, but still I'm able to assign value, what is its scope?   (+ a b)) 

Using let

(defun add_using_let ( )   (let ((x 3) (y 4)) ; creating variables x and y      (+ x y))) 

In both the cases I seem to achieve the same result; what is the difference between using setq and let here? Why can't I use setq (since it is syntactically easy) in all the places where I need to use let?

like image 939
Vijay Rajanna Avatar asked Sep 28 '13 13:09

Vijay Rajanna


People also ask

What does SETQ mean?

(The ' q ' in setq means quote .) With set , the expression would look like this: (set 'carnivores '(lion tiger leopard)) Also, setq can be used to assign different values to different variables.

What is the difference between SETQ and Setf?

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.

What is SETQ in Lisp?

(setq var1 form1 var2 form2 ...) is the simple variable assignment statement of Lisp. First form1 is evaluated and the result is stored in the variable var1, then form2 is evaluated and the result stored in var2, and so forth. setq may be used for assignment of both lexical and dynamic variables.

What is let in Lisp?

The let expression is a special form in Lisp that you will need to use in most function definitions. let is used to attach or bind a symbol to a value in such a way that the Lisp interpreter will not confuse the variable with a variable of the same name that is not part of the function.


1 Answers

setq assigns a value to a variable, whereas let introduces new variables/bindings. E.g., look what happens in

(let ((x 3))   (print x)      ; a   (let ((x 89))     (print x)    ; b     (setq x 73)       (print x))   ; c   (print x))     ; d   3   ; a 89  ; b 73  ; c 3   ; d 

The outer let creates a local variable x, and the inner let creates another local variable shadowing the inner one. Notice that using let to shadow the variable doesn't affect the shadowed variable's value; the x in line d is the x introduced by the outer let, and its value hasn't changed. setq only affects the variable that it is called with. This example shows setq used with local variables, but it can also be with special variables (meaning, dynamically scoped, and usually defined with defparameter or defvar:

CL-USER> (defparameter *foo* 34) *FOO* CL-USER> (setq *foo* 93) 93 CL-USER> *foo* 93 

Note that setq doesn't (portably) create variables, whereas let, defvar, defparameter, &c. do. The behavior of setq when called with an argument that isn't a variable (yet) isn't defined, and it's up to an implementation to decide what to do. For instance, SBCL complains loudly:

CL-USER> (setq new-x 89)  ; in: SETQ NEW-X ;     (SETQ NEW-X 89) ;  ; caught WARNING: ;   undefined variable: NEW-X ;  ; compilation unit finished ;   Undefined variable: ;     NEW-X ;   caught 1 WARNING condition 89 

Of course, the best ways to get a better understanding of these concepts are to read and write more Lisp code (which comes with time) and to read the entries in the HyperSpec and follow the cross references, especially the glossary entries. E.g., the short descriptions from the HyperSpec for setq and let include:

  • SETQ

    Assigns values to variables.

  • LET

    let and let* create new variable bindings and execute a series of forms that use these bindings.

You may want to read more about variables and bindings. let and let* also have some special behavior with dynamic variables and special declarations (but you probably won't need to know about that for a while), and in certain cases (that you probably won't need to know about for a while) when a variable isn't actually a variable, setq is actually equivalent to setf. The HyperSpec has more details.

There are some not-quite duplicate questions on Stack Overflow that may, nonetheless, help in understanding the use of the various variable definition and assignment operators available in Common Lisp:

  • setq and defvar in lisp
  • What's difference between defvar, defparameter, setf and setq
  • Assigning variables with setf, defvar, let and scope
  • In Lisp, how do I fix "Warning: Assumed Special?" (re: using setq on undefined variables)
  • Difference between let* and set? in Common Lisp
like image 141
Joshua Taylor Avatar answered Oct 27 '22 06:10

Joshua Taylor