tags:

views:

2537

answers:

3

What is the difference between "set", "setq", and "setf" in Common Lisp?

+4  A: 

setq is just like set with a quoted first arg -- (set 'foo '(bar baz)) is just like (setq foo '(bar baz)). setf, on the other hand, is subtle indeed -- it's like an "indirection". I suggest http://www.n-a-n-o.com/lisp/cmucl-tutorials/LISP-tutorial-16.html as a better way to get started understanding it than any answer here can give... in short, though, setf takes the first argument as a "reference", so that e.g. (aref myarray 3) will work (as the first arg to setf) to set an item inside an array.

Alex Martelli
Makes most sense for the setq name. Easy to remember. Thanks.
CDR
+12  A: 

Originally, in Common Lisp, there were no lexical variables -- only dynamic ones. And there was no SETQ or SETF, just the SET function.

What is now written as:

(setf (symbol-value 'foo) 42)

was written as:

(set (quote foo) 42)

which was eventually abbreviavated to SETQ (SET Quoted):

(setq foo 42)

Then lexical variables happened, and SETQ came to be used for assignment to them too -- so it was no longer a simple wrapper around SET.

Later, someone invented SETF (SET Field) as a generic way of assigning values to data structures, to mirror the l-values of other languages:

x.car := 42;

would be written as

(setf (car x) 42)

For symmetry and generality, SETF also provided the functionality of SETQ. At this point it would have been correct to say that SETQ was a Low-level primitive, and SETF a high-level operation.

Then symbol macros happened. So that symbol macros could work transparently, it was realized that SETQ would have to act like SETF if the "variable" being assigned to was really a symbol macro:

(defvar hidden (cons 42 42)) (define-symbol-macro foo (car hidden))

foo => 42

(setq foo 13)

foo => 13

hidden => (13 . 42)

So we arrive in the present day: SET and SETQ are athropied remains of older dialects, and will probably be booted from eventual successors of Common Lisp.

stack programmer
Common Lisp always had lexical variables. You must be talking about some Lisp before Common Lisp.
Rainer Joswig
If SET and SETQ are to be booted from a Common Lisp successor, they will have to get some replacement. Their use in high-level code is limited, but low-level code (for example, the code SETF is implemented in) needs them.
Svante
is there a reason you chose 'car' as a field instead of something that might get confused as the car function?
drudru
+6  A: 

(set l '(1 2 3 4)) => Error - l has no value (set 'l '(1 2 3 4)) => OK

(setq l '(1 2 3 4)) => OK - make l to (quote l) and then have the usual set

(setf l '(1 2 3 4)) => OK - same as setq so far BUT

(setf (car l) 10) => Makes l '(10 2 3 4) - not duplicated by setq/set

Sourav
I find your answer to be more clear than the top voted one. Thanks a lot.
CDR