Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

setf & setq, newbie needs short definitions/examples

44 views
Skip to first unread message

;;; helmer . . .

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
Can anyone provide me w/ some clarification on the difference between
setf and setq, I'm learning on my own and don't seem to get it.
--
;;; helmer . . .


Sent via Deja.com http://www.deja.com/
Before you buy.

Will Fitzgerald

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to

In simple terms, SETQ sets the value of a VARIABLE. (You can also do
multiple variables at once).
For example, (setq a 10) gives the variable A the value 10.

SETF is a generalization of SETQ. It sets the value of some place in a data
structure. For example,

(SETQ L1 '(A B C)) => '(A B C)
(SETF (Car L1) 1) -> 1
L => (1 B C)

In this example, The place indicated by 'CAR' has been changed.

Since this is a generalization, you can use SETF for variable setting too.
So,

(SETQ A 10) and
(SETF A 10)

are equivalent.

Some people prefer SETQ for variables for stylistic reasons, but the
semantics are the same.


Tom Breton

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to
;;; helmer . . . <assem...@t-three.com> writes:

> Can anyone provide me w/ some clarification on the difference between
> setf and setq, I'm learning on my own and don't seem to get it.

setq is effectively a special case of setf. When you feed setf a
symbol, they're exactly the same:

(setf a 12)
(setq a 12) ;same

The difference is that setf can take more general place arguments as
well.

(setf (car a) 12)

--
Tom Breton, http://world.std.com/~tob
Not using "gh" since 1997. http://world.std.com/~tob/ugh-free.html
Rethink some Lisp features, http://world.std.com/~tob/rethink-lisp/index.html

Fernando D. Mato Mira

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to
Beware of things like this though:

* (let ((x '(a)))
(symbol-macrolet ((foo (car x)))
(setq foo 'b)
x))
(B)

--
Fernando D. Mato Mira
Real-Time SW Eng & Networking
Advanced Systems Engineering Division
CSEM
Jaquet-Droz 1 email: matomira AT acm DOT org
CH-2007 Neuchatel tel: +41 (32) 720-5157
Switzerland FAX: +41 (32) 720-5720

www.csem.ch www.vrai.com ligwww.epfl.ch/matomira.html


Barry Margolin

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to
In article <38D9ECB5...@iname.com>,

Fernando D. Mato Mira <mato...@iname.com> wrote:
>Beware of things like this though:
>
>* (let ((x '(a)))
> (symbol-macrolet ((foo (car x)))
> (setq foo 'b)
> x))
>(B)

Yeah, I'm sure someone who doesn't even know the difference between setq
and setf is going to make lots of use of symbol-macrolet....

--
Barry Margolin, bar...@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

;;; helmer . . .

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to
Ok, I'm starting to get it.

I definitely got lost on response no. 4, and in 2 what does it mean to
'set multiple variables at once'?

Tim Bradshaw

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to
* helmer wrote:
> I definitely got lost on response no. 4, and in 2 what does it mean to
> 'set multiple variables at once'?

You can say (setq a b
c d)
or (setf (aref a 1) b
(aref a 2) c)
which are equivalent to (setq a b)
(setq c d)
and similarly for the setf form, but sometimes more convenient for
people to read, if you have a lot of assignments, and also more
convenient to manipulate as a unit with an editor.

For further confusion, there are variants of these things called psetq
and psetf which do the assigments in parallel rather than one after
the other. This can matter for things like

(let ((x 0) (y 0))
(setq x (+ x 1)
y (+ x 1))
;; now x is 1, y is 2
...)

(let ((x 0) (y 0))
(psetq x (+ x 1)
y (+ x 1))
;; now x and y are both 1
...)

This is useful for things like swapping variables, and other things:

(psetq x y
y x)

exchanges x and y (although there are more idiomatic ways of doing
this, perhaps).

--tim


Coby Beck

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to

;;; helmer . . . <assem...@t-three.com> wrote in message
news:8bdt2s$hc7$1...@nnrp1.deja.com...

| Ok, I'm starting to get it.
|
| I definitely got lost on response no. 4, and in 2 what does it mean to
| 'set multiple variables at once'?
|
| --
| ;;; helmer . . .
|
|
| Sent via Deja.com http://www.deja.com/
| Before you buy

> (setq a 1 b 2 c 3)
3
> a
1
> b
2
> c
3
>

setf can do the same. FWIW, i've never used setq and i have the impression that it is
indicative of a more "antiquated" style. But there are many things i don't know...

Coby

Thom Goodsell

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to
"set multiple variables at one":

The form
(setf a 1
b 2
c 3
d 550403)

will bind the values 1, 2, 3, and 550403 to the variables a, b, c, and
d, respectively.

Thom


";;; helmer . . ." wrote:
>
> Ok, I'm starting to get it.
>
> I definitely got lost on response no. 4, and in 2 what does it mean to
> 'set multiple variables at once'?
>
> --
> ;;; helmer . . .
>
> Sent via Deja.com http://www.deja.com/

> Before you buy.

Erik Naggum

unread,
Mar 24, 2000, 3:00:00 AM3/24/00
to
* Tim Bradshaw <t...@cley.com>

| This is useful for things like swapping variables, and other things:
|
| (psetq x y
| y x)
|
| exchanges x and y (although there are more idiomatic ways of doing this,
| perhaps).

like (rotatef x y).

#:Erik

Tim Bradshaw

unread,
Mar 24, 2000, 3:00:00 AM3/24/00
to
* Erik Naggum wrote:

> like (rotatef x y).

Yup. I was trying to think of a good example of the pset* forms and
failing. Can anyone else think of one (there must be millions, but my
brain is full at the moment...)

--tim

;; h e l m e r . . .

unread,
Apr 16, 2000, 3:00:00 AM4/16/00
to
hi all,

i'm revisitng my initial question because i found something on a scheme
site that clarifies (i hope) and gives me very basic definitions,
probelm is, i have to make sure it's lisp too . . .

the difference between setf and setq is this (corrections please):

setf is used for definitions to either bound or unbound variables
setq is used for assignments to a previously bound variable

the result of setf is a variable being bound

it is an error to perform setq on an unbound variable, and setq's
result is undefined

[note i have taken these statements where sheme's 'define' = 'setf' in
lisp and similarly 'set!' = 'setq']

;; h e l m e r . . .

Courageous

unread,
Apr 16, 2000, 3:00:00 AM4/16/00
to

> setf is used for definitions to either bound or unbound variables
> setq is used for assignments to a previously bound variable

Upon reflection about this, I'd think that a certain disdain for
using setf's would have crept into the engineering practices de
jour of lisp over the years. It would seem to me that it would
be too easy through a misspelling to accidentally create a new
variable where you intended to modify on old one.

Being a beginner and all, it'd be interesting to hear a comment
or two on this.

C/

Johan Kullstam

unread,
Apr 16, 2000, 3:00:00 AM4/16/00
to
;; h e l m e r . . . <assem...@my-deja.com> writes:

> hi all,
>
> i'm revisitng my initial question because i found something on a scheme
> site that clarifies (i hope) and gives me very basic definitions,
> probelm is, i have to make sure it's lisp too . . .
>
> the difference between setf and setq is this (corrections please):
>

> setf is used for definitions to either bound or unbound variables
> setq is used for assignments to a previously bound variable

setf is a *generalization* of setq. you give it variables and it
works like setq. you give it a generalized variable (called a
_place_) and it makes that place evaluate to what you are setting it
to.

example

assuming foo is an array

(setf (aref foo 3) 14)

(aref foo 3) is now 14

notice that (aref foo 3) isn't a variable, it's an array dereference.
you cannot do (setq (aref foo 3) 14). setf isn't limited to arrays,
most aggregate types (hash-tables, lists, &c) have places which are
also setf-able.

this isn't quite automatic, there is some amount of behind-the-scenes
macrology to make this happen. however, most of the time you can
forget the implementaion details.

this makes syntax only need to deal with getting and you can ignore
the setting.

---

setq operates on variables (or symbols).

in old dynamic lisps where everything was a symbol,

(setq foo bar)

is a macro for

(set 'foo bar)

this isn't true in common-lisp since lexical variables don't have
symbols. setq itself is a special-form. however, setq works kind of
like the older style.

--
J o h a n K u l l s t a m
[kull...@ne.mediaone.net]
Don't Fear the Penguin!

Tim Bradshaw

unread,
Apr 16, 2000, 3:00:00 AM4/16/00
to
* h e l m e r wrote:

> the difference between setf and setq is this (corrections please):

> setf is used for definitions to either bound or unbound variables
> setq is used for assignments to a previously bound variable

> the result of setf is a variable being bound

> it is an error to perform setq on an unbound variable, and setq's
> result is undefined

> [note i have taken these statements where sheme's 'define' = 'setf' in
> lisp and similarly 'set!' = 'setq']

No.

Neither SETF nor SETQ should generally be used to create new bindings.
SETQ is equivalent to set! in scheme, while SETF has no equivalent in
standard scheme, and is used to update general (and user-extensible)
`places' such as slots in objects or array elements. Both return the
object being stored (actually, it would be possible for SETF for some
user-defined place to not do that I think but that would be very bad
style indeed).

Scheme's define maps approximately onto several CL constructs, in this
case one of DEFVAR, DEFCONSTANT or DEFPARAMETER (however this mapping
is not exact).

It's really a mistake to think of CL in scheme terms (or scheme in CL
terms).

--tim

Michael Hudson

unread,
Apr 16, 2000, 3:00:00 AM4/16/00
to
;; h e l m e r . . . <assem...@my-deja.com> writes:

> hi all,
>
> i'm revisitng my initial question because i found something on a scheme
> site that clarifies (i hope) and gives me very basic definitions,
> probelm is, i have to make sure it's lisp too . . .
>

> the difference between setf and setq is this (corrections please):
>
> setf is used for definitions to either bound or unbound variables
> setq is used for assignments to a previously bound variable
>
> the result of setf is a variable being bound
>
> it is an error to perform setq on an unbound variable, and setq's
> result is undefined
>
> [note i have taken these statements where sheme's 'define' = 'setf' in
> lisp and similarly 'set!' = 'setq']

You are, I'm afraid, completely wrong. Here, look at this:

[1]> (macroexpand '(setf a 1))
(SETQ A 1) ;

Well, maybe that's a bit harsh, but your conception of the difference
is. Time to reset the brain and start again, I'm afraid.

The difference between setf and setq is that setq sets the value of
variables whereas setf sets the value of `places', a somewhat more
nebulous concept - but a fairly intuitive one.

A place can be most places you could store a value, such as the car of
a cons, the slot corresponding to the symbol 'bob in a hash table, the
third item of an array.

setf is a macro that expands to the appropriate setter function, eg:

[3]> (macroexpand '(setf (aref an-array 1) 1))
(LET* ((#:G1084 AN-ARRAY) (#:G1085 1) (#:G1086 1))
(SYSTEM::STORE #:G1084 #:G1085 #:G1086)
) ;

by a process that can safely be described as "magic". If you ever
want to write a setf method, then you'll need to understand this
process - and it's a bit more of a fiddle than you think it might be -
but that's a topic to be ignored for the moment.

I'm not really sure what the semantics of assigning to an unbound
variable is; I think it's a bit of a grey area.

HTH,
Michael

--
languages shape the way we think, or don't.
-- Erik Naggum, comp.lang.lisp

Tim Bradshaw

unread,
Apr 16, 2000, 3:00:00 AM4/16/00
to
* Courageous wrote:

> Upon reflection about this, I'd think that a certain disdain for
> using setf's would have crept into the engineering practices de
> jour of lisp over the years. It would seem to me that it would
> be too easy through a misspelling to accidentally create a new
> variable where you intended to modify on old one.

No, because the original poster is confused about what setf and setq
do -- neither will create new bindings (or not without profuse
compiler warnings typically). I use setf pretty much exclusively.

--tim

Tom Breton

unread,
Apr 16, 2000, 3:00:00 AM4/16/00
to
;; h e l m e r . . . <assem...@my-deja.com> writes:

> hi all,
>
> i'm revisitng my initial question because i found something on a scheme
> site that clarifies (i hope) and gives me very basic definitions,
> probelm is, i have to make sure it's lisp too . . .
>
> the difference between setf and setq is this (corrections please):
>
> setf is used for definitions to either bound or unbound variables
> setq is used for assignments to a previously bound variable

I'm sorry, but that is nowhere near it. setf is a generalization of
setq. setf *is* setq when called with a bare symbol and a value. It
doesn't have anything to do with whether the symbol is bound or
unbound.

Suggestion: Use your killfile liberally in cll

Courageous

unread,
Apr 17, 2000, 3:00:00 AM4/17/00
to

Yeah, okay. I've never actually used setq, and thought maybe
I was missing something. Apparently not.

Come to think of it, in working with some other knowedgeable
lisp programmer's code, I don't think I see setq very
frequently either.

Thank you for the clarification,

C/

;; h e l m e r . . .

unread,
Apr 17, 2000, 3:00:00 AM4/17/00
to

> It's really a mistake to think of CL in scheme terms (or scheme in CL
> terms).
>
> --tim
>

yeah, but i still got some great information, point taken and thanks
everybody!

--


;; h e l m e r . . .

Scott L. Burson

unread,
Apr 17, 2000, 3:00:00 AM4/17/00
to
Courageous wrote:
>
> Yeah, okay. I've never actually used setq, and thought maybe
> I was missing something. Apparently not.
>
> Come to think of it, in working with some other knowedgeable
> lisp programmer's code, I don't think I see setq very
> frequently either.

My own habit, as a matter of style, is to use SETQ on local and global variables
and SETF on everything else -- *including* CLOS slot names bound by WITH-SLOTS.
This way, by glancing at the form, I can get an idea what kind of thing it's
setting.

-- Scott

Christophe Rhodes

unread,
Apr 17, 2000, 3:00:00 AM4/17/00
to
Johan Kullstam <kull...@ne.mediaone.net> writes:

> ;; h e l m e r . . . <assem...@my-deja.com> writes:
> > the difference between setf and setq is this (corrections please):
> >
> > setf is used for definitions to either bound or unbound variables
> > setq is used for assignments to a previously bound variable
>

> setf is a *generalization* of setq. you give it variables and it
> works like setq. you give it a generalized variable (called a
> _place_) and it makes that place evaluate to what you are setting it
> to.

> [...]

> this isn't quite automatic, there is some amount of behind-the-scenes
> macrology to make this happen. however, most of the time you can
> forget the implementaion details.

It's possibly worth mentioning also that the notion of a "place" is
programme- and application-dependent; for instance, defining new
structures defines new places that setf can operate on, as does
defining classes with slots with :accessor. Also, should you wish, you
can define your own "place" directly via defsetf. None of this applies
to setq, which is not generalizeable.

Christophe
--
(macrolet ((f (a b) `(unless (equal ,a "") (princ (aref ,a 0)) (setf ,a
(subseq ,a 1)) (,b))) (z (&rest a) `(format nil "~@{~35r~^ ~}" ,@a))) (
let ((w (z 693 29204 28104384)) (x (z 1984050605838 12977))) (labels ((
y () (f w z))(z () (f x y))) (y) (terpri))))#|Jesus College,Cambridge|#

Erik Naggum

unread,
Apr 17, 2000, 3:00:00 AM4/17/00
to
* ;; h e l m e r . . . <assem...@my-deja.com>

| i'm revisitng my initial question because i found something on a scheme
| site that clarifies (i hope) and gives me very basic definitions,
| probelm is, i have to make sure it's lisp too . . .

it isn't. on top of it, it's completely bogus, because ...

| [note i have taken these statements where sheme's 'define' = 'setf' in
| lisp and similarly 'set!' = 'setq']

... this is completely unfounded.

please forget comparing Scheme and Lisp for now, but feel free to try
again when you know both exceedingly well on their own merits.

#:Erik

Johan Kullstam

unread,
Apr 17, 2000, 3:00:00 AM4/17/00
to
Christophe Rhodes <cs...@cam.ac.uk> writes:

> Johan Kullstam <kull...@ne.mediaone.net> writes:
>
> > ;; h e l m e r . . . <assem...@my-deja.com> writes:
> > > the difference between setf and setq is this (corrections please):
> > >
> > > setf is used for definitions to either bound or unbound variables
> > > setq is used for assignments to a previously bound variable
> >
> > setf is a *generalization* of setq. you give it variables and it
> > works like setq. you give it a generalized variable (called a
> > _place_) and it makes that place evaluate to what you are setting it
> > to.
>
> > [...]
>
> > this isn't quite automatic, there is some amount of behind-the-scenes
> > macrology to make this happen. however, most of the time you can
> > forget the implementaion details.
>
> It's possibly worth mentioning also that the notion of a "place" is
> programme- and application-dependent; for instance, defining new
> structures defines new places that setf can operate on, as does
> defining classes with slots with :accessor. Also, should you wish, you
> can define your own "place" directly via defsetf. None of this applies
> to setq, which is not generalizeable.

and don't forget the ever popular GET-SETF-EXPANSION.

here is my anaphoric SETF, ASETF. it uses IT for _place_ in the
second half of the assignment. ASETF is a generalization of INCF
where you can supply any form not just (1+ _)

cl-user> foo
2
cl-user> (asetf foo (* 3 it))
6
cl-user> foo
6

perhaps not so interesting in the above case, but constructions like

cl-user> (asetf (aref bar index) (* factor it))

might be more useful.

here's the code. use it as you like.

;; grouping function
(eval-when (compile)
(defun group (source n)
(if (zerop n) (error "zero length"))
(labels ((rec (source acc)
(let ((rest (nthcdr n source)))
(if (consp rest)
(rec rest (cons (subseq source 0 n) acc))
(nreverse (cons source acc))))))
(if source (rec source nil) nil))))

;; setf helper
(defmacro _f (op place &rest args)
(multiple-value-bind (vars forms var set access)
(get-setf-expansion place)
`(let* (,@(mapcar #'list vars forms)
(,(car var) (,op ,access ,@args)))
,set)))

(defmacro asetf (&rest implicit-pairs)
;; unroll for multiple pairs
`(progn
,@(mapcar (lambda (pair)
`(_f (lambda (it)
(declare (ignorable it))
,(cadr pair))
,(car pair)))
(group implicit-pairs 2))))

--
johan kullstam l72t00052

0 new messages