From: Mike
Subject: setq vs setf?
Date: 
Message-ID: <QIMCf.2185$r74.1865@fe06.lga>
What's the difference? My first exposure to lisp
many years ago I did everything with setq.

Mike

From: Jeff M.
Subject: Re: setq vs setf?
Date: 
Message-ID: <1138466380.614192.41200@g47g2000cwa.googlegroups.com>
This is something that actually took me quite a long time to learn, and
most of the explanations I got were both correct, and either mysterious
or didn't really hit home. Here's my attempt to help you with it. :-)

SETQ is the simple method of binding a symbol to a value. Keep in mind,
that's all it does. It binds a symbol to a value:

(setq x 10)
(setq list '(a b c))

SETF is an extendable macro. It is a macro that expands to the proper
form required to bind "something" to a value. That "something" is the
key. For example, when setting the value in a hash table or place in an
array, you use SETF:

(setf (gethash :my-key table) 10)
(setf (aref array 2 4) '(a b c))

You can extend the definition of SETF using DEFSETF
(http://www.lispworks.com/documentation/HyperSpec/Body/m_defset.htm#defsetf).
99% of the time, you should just use SETF. If you SETF a symbol, it
will expand to a SETQ.

Hope this helps,

Jeff M.
From: Mike
Subject: Re: setq vs setf?
Date: 
Message-ID: <KsNCf.2694$r74.2511@fe06.lga>
On 2006-01-28, Jeff M. <·······@gmail.com> wrote:
> This is something that actually took me quite a long time to learn, and
> most of the explanations I got were both correct, and either mysterious
> or didn't really hit home. Here's my attempt to help you with it. :-)
>
> SETQ is the simple method of binding a symbol to a value. Keep in mind,
> that's all it does. It binds a symbol to a value:
>
> (setq x 10)
> (setq list '(a b c))
>
> SETF is an extendable macro. It is a macro that expands to the proper
> form required to bind "something" to a value. That "something" is the
> key. For example, when setting the value in a hash table or place in an
> array, you use SETF:
>
> (setf (gethash :my-key table) 10)
> (setf (aref array 2 4) '(a b c))
>
> You can extend the definition of SETF using DEFSETF
> (http://www.lispworks.com/documentation/HyperSpec/Body/m_defset.htm#defsetf).
> 99% of the time, you should just use SETF. If you SETF a symbol, it
> will expand to a SETQ.
>
> Hope this helps,
>
> Jeff M.
>

Thank you all for the explanations.

Mike
From: André Thieme
Subject: Re: setq vs setf?
Date: 
Message-ID: <1138469970.456327.259330@z14g2000cwz.googlegroups.com>
One thing that confused me was:
(setf (aref x 10) 123)

(aref x 10) returns the 11th (arrays are zero indexed) element of the
array x. Let's say it evaluates to 14. But why in the world should I
want (setf 14 123)??
I don't want 14 beeing 123.
The trick is: when used in setf then aref does not work as it would in
other places. After a while I realized that I shouldn't be confused
because  I already knew this behaviour from other languages. For
example you say:
print x[10];   // outputs "14"

So x[10] gets replaced by what this piece of memory saves, in our
example a 14. When I now say:
x[10] = 123;  then what would that mean? If x[10] is replaced with a 14
then we would have:
14 = 123;  // which wouldn't make sense.
So also in C, Java, Python, etc. the "[]" operator (aref in Lisp) is
working different when used with = (setf in Lisp).


André
--
From: Barry Margolin
Subject: Re: setq vs setf?
Date: 
Message-ID: <barmar-2B90F6.17163928012006@comcast.dca.giganews.com>
In article <························@z14g2000cwz.googlegroups.com>,
 "Andr� Thieme" <······························@justmail.de> wrote:

> One thing that confused me was:
> (setf (aref x 10) 123)
> 
> (aref x 10) returns the 11th (arrays are zero indexed) element of the
> array x. Let's say it evaluates to 14. But why in the world should I
> want (setf 14 123)??
> I don't want 14 beeing 123.

SETF is a macro, and it controls which subexpressions get evaluated.  It 
doesn't evaluate the place expression, it examines it to determine what 
you want to modify, and then expands into a call to a function that does 
that.  So the above expression will expand into something like:

(internal:array-set x 123 10)

> The trick is: when used in setf then aref does not work as it would in
> other places. After a while I realized that I shouldn't be confused
> because  I already knew this behaviour from other languages. For
> example you say:
> print x[10];   // outputs "14"
> 
> So x[10] gets replaced by what this piece of memory saves, in our
> example a 14. When I now say:
> x[10] = 123;  then what would that mean? If x[10] is replaced with a 14
> then we would have:
> 14 = 123;  // which wouldn't make sense.
> So also in C, Java, Python, etc. the "[]" operator (aref in Lisp) is
> working different when used with = (setf in Lisp).

No, it's the = operator that works specially.  Traditional languages 
make a distinction between "rvalues" and "lvalues".  An rvalue is what 
you get when you print the expression or use it as a parameter in a 
function call.  The lvalue refers to the location in memory holding the 
value, and this is what is used when the expression is the target of an 
assignment (the names lvalue and rvalue refer to the expression being 
used on the left or right side of an assignment).

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Rob Warnock
Subject: Re: setq vs setf?
Date: 
Message-ID: <M6OdnR6pp-UHtUHenZ2dnUVZ_vmdnZ2d@speakeasy.net>
Jeff M. <·······@gmail.com> wrote a good explanation except for one point:
+---------------
| SETQ is the simple method of binding a symbol to a value.
| Keep in mind, that's all it does. It binds a symbol to a value:
| 
| (setq x 10)
| (setq list '(a b c))
+---------------

Actually, if I may be a bit pedantic for a moment, SETQ does *NOT*
"bind a symbol to a value". Instead, for a symbol that is already
bound to a lexical or dynamic variable (a place that can hold a value),
it changes the value of that variable, also known as "assigning",
"storing", or "writing" a new value into a variable. (See CLHS "SETQ".)

This is a subtle point, confusing because we ordinarily don't ever
see the "variable" (the place) itself [except in Lisps with locatives].
The CLHS doesn't say it all that well in 3.1.2.1.1 "Symbols as Forms",
and is IMHO downright misleading sometimes (e.g., in 5.1.2.1 "Variable
Names as Places", or the Glossary entry for "binding"). This is one of
the areas that the Scheme standard explicates more clearly (again, IMHO),
in a way which applies to CL as well. Eliding off-topic bits, from R5RS
3.1 "Variables, syntactic keywords, and regions":

    An identifier may name a ... location where a value can be stored.
    ... An identifier that names a location is called a variable and is
    said to be bound to that location. The set of all visible bindings
    in effect at some point in a program is known as the environment
    in effect at that point. The value stored in the location to which
    a variable is bound is called the variable's value. By abuse of
    terminology, the variable is sometimes said to name the value or
    to be bound to the value. This is not quite accurate, but confusion
    rarely results from this practice.

Except when it does...  ;-}

The term "bind" means to create a *new* association between a name
(symbol) and a place (that can hold a value) -- this new association
is called a "variable". Usually the operation of binding *also* sets
(or assigns or writes) an initial "value" into the place denoted by
the variable. The value can later be *overwritten* by a subsequent
assignment [except for "constant variables"] with SETQ, but such
overwriting does *NOT* change either the place itself or the binding
between the symbol and the place.

[To add to the confusion, in CL "rebinding" a special variable with
LET or LAMBDA, etc., does *NOT* create a new association between
name & place (a new binding). Rather, it saves the old value and
*sets* a new value into the original variable but arranges for the
old value to be restored at the end of the scope of the rebinding.]

To say it one more way, SETQ does not change the variable [or the
binding]; it changes the value that the variable when return when
subsequently read.

So I would rephrase your first two sentence like so:

     SETQ is the simple method of storing a new value into the variable
     represented by a symbol. Keep in mind, that's all it does. It stores
     a new value into a lexical or dynamic variable.

+---------------
| SETF is an extendable macro. It is a macro that expands to the proper
| form required to bind "something" to a value.
+---------------

Likewise, this should be changed to remove the word "bind":

    SETF is an extendable macro. It is a macro that expands to the
    proper form required to store a new value into "something",
    conventionally called a "place".

The rest of what you wrote [including examples] is fine.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Barry Margolin
Subject: Re: setq vs setf?
Date: 
Message-ID: <barmar-CD7CAD.11244728012006@comcast.dca.giganews.com>
In article <···················@fe06.lga>, Mike <·····@mikee.ath.cx> 
wrote:

> What's the difference? My first exposure to lisp
> many years ago I did everything with setq.

SETQ can only assign to variables, SETF can assign to many different 
types of containers.  For instance, you can do:

(setf (car some-cons-cell) 3)

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Kaz Kylheku
Subject: Re: setq vs setf?
Date: 
Message-ID: <1138666212.341921.135790@g43g2000cwa.googlegroups.com>
Barry Margolin wrote:
> In article <···················@fe06.lga>, Mike <·····@mikee.ath.cx>
> wrote:
>
> > What's the difference? My first exposure to lisp
> > many years ago I did everything with setq.
>
> SETQ can only assign to variables, SETF can assign to many different
> types of containers.  For instance, you can do:
>
> (setf (car some-cons-cell) 3)

  (symbol-macrolet ((cscc (car some-cons-cell)))
    (setq cscc 3))
From: Ulrich Hobelmann
Subject: Re: setq vs setf?
Date: 
Message-ID: <441k4pF1prsltU3@individual.net>
Mike wrote:
> What's the difference? My first exposure to lisp
> many years ago I did everything with setq.

SETQ works for normal variables.  With SETF you can set whole fields (in 
fact that's how I memorize the name), like (setf (cdr *foo*) 5), but for 
all kinds of things...

I guess most people don't even bother to use SETQ, because SETF 
auto-expands to SETQ if appropriate, i.e. for variables.

-- 
Suffering from Gates-induced brain leakage...
From: Kaz Kylheku
Subject: Re: setq vs setf?
Date: 
Message-ID: <1138666039.793375.125510@g43g2000cwa.googlegroups.com>
Ulrich Hobelmann wrote:
> Mike wrote:
> > What's the difference? My first exposure to lisp
> > many years ago I did everything with setq.
>
> SETQ works for normal variables.

SETQ also works with symbol macros, which can expand to fully
generalized SETF assignment places.

This means that SETQ, just like PUSH, INCF, DECF and so forth, has to
understand SETF expanders.

> I guess most people don't even bother to use SETQ, because SETF
> auto-expands to SETQ if appropriate, i.e. for variables.

Because of the above point, SETQ is not on a subordinate level relative
to SETF; it's not something that SETF can expand to for handling the
case when a symbol is assigned to.

Rather, SETQ is a restricted subset of the SETF interface: it's a
flavor of SETF that syntactically restricts the assignment target to be
a symbol.

So in fact it would be more straightforward to implement SETQ as a
macro that verifies the constraint, and expands to the more general
SETF.

There is no reason to use SETQ because the constraint that it verifies
is visually obvious. It doesn't buy you anything to write (SETQ X VAL)
compared to (SETF X VAL) since it's obvious that X is a symbol, and so
there is no error.

So basically SETQ is utterly obsolete.
From: Brian Downing
Subject: Re: setq vs setf?
Date: 
Message-ID: <A9EDf.765236$xm3.621530@attbi_s21>
In article <························@g43g2000cwa.googlegroups.com>,
Kaz Kylheku <········@gmail.com> wrote:
> SETQ also works with symbol macros, which can expand to fully
> generalized SETF assignment places.
> 
> This means that SETQ, just like PUSH, INCF, DECF and so forth, has to
> understand SETF expanders.

It has to recognize them, but it doesn't have to "understand" them per
se.  All that's required when your evaluator or compiler hits (setq
symbol-macro foo) is to replace it with (setf expansion foo) and
continue.

> Because of the above point, SETQ is not on a subordinate level relative
> to SETF; it's not something that SETF can expand to for handling the
> case when a symbol is assigned to.

I beg to differ here.  (setf var value) must expand to something - it's
defined as a macro in the spec so a conforming implementation must
provide a macroexpansion, even if it implements it differently.  The
only thing it can expand to is a special operator, as it has to set the
lexical somehow.  It's better for everyone involved if (setf var value)
expands to (setq var value) instead of (internal::set-lexical var
value), because then you aren't going to confuse the vast majority of
code-walkers.

:; sbcl
This is SBCL 0.8.21.50.evaluator-again.4, an implementation of ANSI Common Lisp.
[...]
* (symbol-macrolet ((foo bar)
                    (bar baz))
    (let ((sb-eval::*eval-verbose* t)
          (baz nil))
      (setq foo 4)
      baz))

  (SB-EVAL::%EVAL (SETQ FOO 4))
   (SB-EVAL::%EVAL (SETF BAR 4))
    (SB-EVAL::%EVAL (SETQ BAR 4))
     (SB-EVAL::%EVAL (SETF BAZ 4))
      (SB-EVAL::%EVAL (SETQ BAZ 4))
       (SB-EVAL::%EVAL 4)
  (SB-EVAL::%EVAL BAZ)
4

Now, (setf (aref foo) bar) expands into internals, but it can be
represented with a function call (like (%aset foo bar)), which code
walkers can understand.

> Rather, SETQ is a restricted subset of the SETF interface: it's a
> flavor of SETF that syntactically restricts the assignment target to be
> a symbol.

I'd rather say it's the fundamental special operator used to set lexical
variables, with an "escape hatch" for use with symbol macro abstractions
to maintain the illusion that they are normal lexical variables.
Nevertheless it's primitive and something like it is required.

> So basically SETQ is utterly obsolete.

For use in user code, I agree.  As a language construct I disagree.

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: Joerg Hoehle
Subject: Re: setq vs setf?
Date: 
Message-ID: <umzhaovxo.fsf@users.sourceforge.net>
Brian Downing <·············@lavos.net> writes:
> I'd rather say it's the fundamental special operator used to set lexical
> variables, with an "escape hatch" for use with symbol macro abstractions
> to maintain the illusion that they are normal lexical variables.
> Nevertheless it's primitive and something like it is required.
Exactly.  Better than I could have expressed.

> Kaz Kylheku wrote:
> > So basically SETQ is utterly obsolete.
> For use in user code, I agree.  As a language construct I disagree.

By the same argumentation, COND (or IF) is utterly obsolete, WHEN or
UNLESS should never have been invented.  All obsolete.  BS!

So I disagree, but then I've used CL since CLtL1 times, and other
dialects in the Lisp family.  I'll continue to use SETQ.  And I'll
wait for scientific evidence that telling users about SETF only is
going to help them master the language any faster.

Regards,
	Jorg Hohle
Telekom/T-Systems Technology Center
From: Kaz Kylheku
Subject: Re: setq vs setf?
Date: 
Message-ID: <1138923475.220637.324390@g47g2000cwa.googlegroups.com>
Joerg Hoehle wrote:
> Brian Downing <·············@lavos.net> writes:
> > I'd rather say it's the fundamental special operator used to set lexical
> > variables, with an "escape hatch" for use with symbol macro abstractions
> > to maintain the illusion that they are normal lexical variables.
> > Nevertheless it's primitive and something like it is required.
> Exactly.  Better than I could have expressed.

No, something like it is not required. What is required is a true
primitive which assigns only to variables. SETQ cannot be that
primitive, because SETQ itself has to expand to that primitive---in
some cases!

If X expands to (AREF Y Z), then (SETQ X 42) should expand to the same
thing as (SETF X 42): some internal array assignment function.

If X doesn't expand to anything then (SETQ X 42) should expand to some
internal symbol-assignment operator: one that no longer expands to
anything else, and does not check whether its target place is a symbol
macro. Sure, that operator resembles some ancient version of SETQ from
the 1960's. So what? :)

> > Kaz Kylheku wrote:
> > > So basically SETQ is utterly obsolete.
> > For use in user code, I agree.  As a language construct I disagree.
>
> By the same argumentation, COND (or IF) is utterly obsolete, WHEN or
> UNLESS should never have been invented.  All obsolete.  BS!

This can't be said by the same argumentation, because each of these
operators does something useful which the others do not.

But SETF does in fact do everything that SETQ does exactly with the
same argument syntax.
From: Joerg Hoehle
Subject: Re: setq vs setf?
Date: 
Message-ID: <upslrnw3p.fsf@users.sourceforge.net>
"Kaz Kylheku" <········@gmail.com> writes:
> Joerg Hoehle wrote:
> No [...] What is required is a true
> primitive which assigns only to variables. SETQ cannot be that
> primitive, because SETQ itself has to expand to that primitive---in
> some cases!

SETQ was this primitive until symbol macros were invented and retrofitted.
Actually, IMHO, the true primitive would take a single name and value.
No (SETQ), nor (SETQ { name1 value1 } {name2 value2}+)
I often miss that one when writing code transformers: these must
take into consideration every pattern and becmoe clumsy.

To me, SETF and SETQ are not the same. One is a macro and can be
expanded by code walkers.  The other is a special form: MACROEXPAND
does not apply, you're on your own.  Agreed, this does not matter to
newbies.

> > By the same argumentation, COND (or IF) is utterly obsolete, WHEN or
> > UNLESS should never have been invented.  All obsolete.  BS!
> But SETF does in fact do everything that SETQ does exactly with the
> same argument syntax.

(WHEN foo bar) == (IF foo bar), so WHEN or IF is still obsolete?
Exact same syntax in base cases.  But ok, I won't continue this
discussion.  You don't need to tell me that
(WHEN foo bar grr) <> (IF foo bar grr)
;-)

Regards,
	Jorg Hohle
Telekom/T-Systems Technology Center
From: Brian Downing
Subject: Re: setq vs setf?
Date: 
Message-ID: <pHqEf.770945$xm3.371976@attbi_s21>
In article <·············@users.sourceforge.net>,
Joerg Hoehle  <······@users.sourceforge.net> wrote:
> Brian Downing <·············@lavos.net> writes:
> > Kaz Kylheku wrote:
> > > So basically SETQ is utterly obsolete.
> > For use in user code, I agree.  As a language construct I disagree.
> 
> By the same argumentation, COND (or IF) is utterly obsolete, WHEN or
> UNLESS should never have been invented.  All obsolete.  BS!

The difference, in my humble opinion, is that IF, COND, WHEN, and UNLESS
all have different syntactic advantages for different situations.  (setf
var val) and (setq var val) share the same syntax modulo one charactger,
so there's really no advantage to picking one or the other -- one might
as well pick the more general one.

> So I disagree, but then I've used CL since CLtL1 times, and other
> dialects in the Lisp family.  I'll continue to use SETQ.

Which is fine - choice is good.  More power to you.  :)

> And I'll wait for scientific evidence that telling users about SETF
> only is going to help them master the language any faster.

Dunno, but I notice we're generally not advising people use RPLACA or
RPLACD.  If SETF is good as a programmer-level interface for setting
conses, why not for variables as well?

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: Kaz Kylheku
Subject: Re: setq vs setf?
Date: 
Message-ID: <1138923533.121410.62670@g43g2000cwa.googlegroups.com>
Brian Downing wrote:
> In article <·············@users.sourceforge.net>,
> Joerg Hoehle  <······@users.sourceforge.net> wrote:
> > So I disagree, but then I've used CL since CLtL1 times, and other
> > dialects in the Lisp family.  I'll continue to use SETQ.
>
> Which is fine - choice is good.  More power to you.  :)

You mean, more syntax to you. :)
From: Coby Beck
Subject: Re: setq vs setf?
Date: 
Message-ID: <3VvEf.161326$AP5.142353@edtnps84>
"Joerg Hoehle" <······@users.sourceforge.net> wrote in message 
··················@users.sourceforge.net...

>> Kaz Kylheku wrote:
>> > So basically SETQ is utterly obsolete.
>> For use in user code, I agree.  As a language construct I disagree.
>
> By the same argumentation, COND (or IF) is utterly obsolete, WHEN or
> UNLESS should never have been invented.  All obsolete.  BS!

Well, its hard to tell, given you did not preserve any of his argumentation! 
But I don't think you are correct, the analogy is broken.  The choice 
between COND IF WHEN and UNLESS is between different semantic expressions 
regardless of the fact that can all be implemented in terms of COND.  SETQ 
vs SETF is a choice between semantically equivalent constructs, only one is 
general the other special case.

> So I disagree, but then I've used CL since CLtL1 times, and other
> dialects in the Lisp family.  I'll continue to use SETQ.  And I'll
> wait for scientific evidence that telling users about SETF only is
> going to help them master the language any faster.

It is a matter of personal preference which to use.  Obsolete in user code? 
Well, ultimately that is a matter of consensus.  I think it is getting 
there...

-- 
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")