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

setf functions

16 views
Skip to first unread message

David Bakhash

unread,
Apr 3, 2000, 3:00:00 AM4/3/00
to
Is there a way to pass in multiple values to a setf function:

e.g. an example would be:

(setf (global-pointer-position *display*) (values x y))

how? what's the right way, if there is one?

dave

Coby Beck

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

David Bakhash <ca...@mit.edu> wrote in message
news:c29u2hi...@nerd-xing.mit.edu...

(setf global-pointer-position x *display* y)

(multiple-value-setq (global-pointer-position *display*) (values x y))

Coby


dave

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

Coby Beck <cb...@mercury.bc.ca> wrote in message
news:954804...@NewsSIEVE.cs.bonn.edu...

I don't get it. this doesn't seem right. Let's look at an example:

CL-USER 1 > (defvar *x* 3)
*X*

CL-USER 2 > (defvar *y* 4)
*Y*

CL-USER 3 > (defun f () (values *x* *y*))
F

CL-USER 4 > (multiple-value-setq (f) (values 9 10))
9

CL-USER 5 > *y*
4

the problem there, i.e. with your example, is that you must realize that
you're using #'multiple-value-SETQ and _not_ #'multiple-value-SETF (which
doesn't exist).

dave

Coby Beck

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

dave <deen...@yahoo.com> wrote in message
news:38ea8083$0$21...@senator-bedfellow.mit.edu...

As i understood the original poster's question, he wanted to set two
variables at once, either from two other variable values or from a form
returning multiple values. To that end, my original examples do work.

I'm not sure what you're trying to show...even with (defun f() *x*) you can
not setf it:

> (defun foo () *x*)
foo
> (setf (foo) 3)
Error: (setf foo) does not have a function definition
[condition type: simple-error]
>

I think if you repeat your session above, you'll find that you just set the
value of a new symbol 'f' to 9 and did not refer to the function f at all.

Perhaps i'm missing something? (wouldn't be the first time ;-)

Coby

Marco Antoniotti

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

In CLIM there is a requirement to have a SETF* macro. Does anybody
have an implementation of this beast. I can see that it could be
generally useful.

Cheers

--
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa

David Bakhash

unread,
Apr 5, 2000, 3:00:00 AM4/5/00
to
"Coby Beck" <cb...@mercury.bc.ca> writes:

> > the problem there, i.e. with your example, is that you must realize that
> > you're using #'multiple-value-SETQ and _not_ #'multiple-value-SETF (which
> > doesn't exist).
>
> As i understood the original poster's question, he wanted to set two
> variables at once, either from two other variable values or from a form
> returning multiple values. To that end, my original examples do work.
>
> I'm not sure what you're trying to show...even with (defun f() *x*) you can
> not setf it:
>
> > (defun foo () *x*)
> foo
> > (setf (foo) 3)
> Error: (setf foo) does not have a function definition
> [condition type: simple-error]

You must understand the point of my post, though. If it's only a
single value, you can make a setf function:

(defun (setf f) (newval input-arg-1 input-arg-2 ... input-arg-3)
(...))

the point is that the way setf functions are defined with DEFUN,
there's only space for a _single_ `newval'. If instead there were:

(defun (setf f) ((values newval-1 newval-2) input-arg-1 ...)
"Just a silly example to try to show what I mean here."
(setf (values *x* *y*)
(values newval-1 newval-2)))


Harald Hanche-Olsen

unread,
Apr 5, 2000, 3:00:00 AM4/5/00
to
+ "Coby Beck" <cb...@mercury.bc.ca>:

| dave <deen...@yahoo.com> wrote in message
| news:38ea8083$0$21...@senator-bedfellow.mit.edu...
| >

| > I don't get it. this doesn't seem right. [...]


|
| As i understood the original poster's question, he wanted to set two
| variables at once, either from two other variable values or from a form
| returning multiple values. To that end, my original examples do work.

Assuming that the original poster understands setf in its most basic
usage, I would venture the guess that your understanding of his
question is wrong.

I believe he has a function global-pointer-position which, when fed a
suitable object *display*, returns two values x and y. He wishes to
be able to say

(setf (global-pointer-position *display*) (values x y))

to modify the contents of *display* so that future calls to
(global-pointer-position *display*) will return the two values x and
y. This is not an unreasonable expectation.

| I'm not sure what you're trying to show...even with (defun f() *x*) you can
| not setf it:
|
| > (defun foo () *x*)
| foo
| > (setf (foo) 3)
| Error: (setf foo) does not have a function definition

Sure, you can, if you do the right thing with define-setf-expander
first. But I haven't got the expertise to show you what the right
thing is -- consult the Hyperspec for that.

My point is that, as far as I can understand the Hyperspec, there is
no way to do this for a function returning multiple values, since the
form should be a place, which by definition can only refer to a single
value. I'd love to be proved wrong on this one, though. Or even if I
am right, maybe there is a more natural way to attack the problem?
--
* Harald Hanche-Olsen <URL:http://www.math.ntnu.no/~hanche/>
- "There arises from a bad and unapt formation of words
a wonderful obstruction to the mind." - Francis Bacon

Erik Naggum

unread,
Apr 5, 2000, 3:00:00 AM4/5/00
to
* Harald Hanche-Olsen <han...@math.ntnu.no>

| My point is that, as far as I can understand the Hyperspec, there is
| no way to do this for a function returning multiple values, since the
| form should be a place, which by definition can only refer to a single
| value. I'd love to be proved wrong on this one, though. Or even if I
| am right, maybe there is a more natural way to attack the problem?

apart from actually working, what's wrong with this example?

(defstruct display
x y)

(defun global-pointer-position (object)
(values (display-x object) (display-y object)))

(defsetf global-pointer-position (object) (new-x new-y)
`(setf (display-x ,object) ,new-x
(display-y ,object) ,new-y))

#:Erik

Harald Hanche-Olsen

unread,
Apr 6, 2000, 3:00:00 AM4/6/00
to
+ Erik Naggum <er...@naggum.no>:

| apart from actually working, what's wrong with this example?

Well, it indicates that I didn't understand the HyperSpec, which comes
as no surprise.

| (defstruct display
| x y)
|
| (defun global-pointer-position (object)
| (values (display-x object) (display-y object)))
|
| (defsetf global-pointer-position (object) (new-x new-y)
| `(setf (display-x ,object) ,new-x
| (display-y ,object) ,new-y))

But since you seem to suggest there actually *is* something wrong with
the example, I managed to find fault with it anyway:

The Notes section for defsetf says

forms must include provision for returning the correct value (the
value or values of store-variable).

so I would think that

(defsetf global-pointer-position (object) (new-x new-y)

`(progn


(setf (display-x ,object) ,new-x
(display-y ,object) ,new-y)

(values ,new-x ,new-y)))

is more correct.

Fernando D. Mato Mira

unread,
Apr 6, 2000, 3:00:00 AM4/6/00
to
Harald Hanche-Olsen wrote:

> so I would think that
>
> (defsetf global-pointer-position (object) (new-x new-y)
> `(progn
> (setf (display-x ,object) ,new-x
> (display-y ,object) ,new-y)
> (values ,new-x ,new-y)))
>
> is more correct.

But this is nicer:

(defsetf global-pointer-position (object) (new-x new-y)

`(setf (values (display-x ,object) (display-y ,object))
(values ,new-x ,new-y)))


DEFSETF could be a little smarter in some implementations, though:

* (macroexpand '(setf (global-pointer-position d) (values 1 2)))
(LET* ((#:G914 D))
(MULTIPLE-VALUE-BIND
(#:G915 #:G916)
(VALUES 1 2)
(SETF (VALUES (DISPLAY-X #:G914) (DISPLAY-Y #:G914))
(VALUES #:G915 #:G916))))

--
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


Marco Antoniotti

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

"Fernando D. Mato Mira" <mato...@acm.org> writes:

> Harald Hanche-Olsen wrote:
>
> > so I would think that
> >
> > (defsetf global-pointer-position (object) (new-x new-y)
> > `(progn
> > (setf (display-x ,object) ,new-x
> > (display-y ,object) ,new-y)
> > (values ,new-x ,new-y)))
> >
> > is more correct.
>
> But this is nicer:
>
> (defsetf global-pointer-position (object) (new-x new-y)
> `(setf (values (display-x ,object) (display-y ,object))
> (values ,new-x ,new-y)))
>
>

What about this?

(defun (setf global-pointer-position) (new-x new-y object)
(setf (values (display-x object) (display-y object))
(values new-x new-y)))

It does not work in CMUCL, but I believe it should (modulo my
understanding on the CLHS)

Erik Naggum

unread,
Apr 6, 2000, 3:00:00 AM4/6/00
to
* Marco Antoniotti <mar...@parades.rm.cnr.it>

| What about this?
|
| (defun (setf global-pointer-position) (new-x new-y object)
| (setf (values (display-x object) (display-y object))
| (values new-x new-y)))
|
| It does not work in CMUCL, but I believe it should (modulo my
| understanding on the CLHS)

that would mean the call would have to be

(setf (global-pointer-position new-y object) new-x)

this is not what we want.

#:Erik

Dave Bakhash

unread,
Apr 6, 2000, 3:00:00 AM4/6/00
to
Marco Antoniotti <mar...@parades.rm.cnr.it> writes:

> > But this is nicer:
> >
> > (defsetf global-pointer-position (object) (new-x new-y)
> > `(setf (values (display-x ,object) (display-y ,object))
> > (values ,new-x ,new-y)))
> >
> >
>

> What about this?
>
> (defun (setf global-pointer-position) (new-x new-y object)
> (setf (values (display-x object) (display-y object))
> (values new-x new-y)))
>
> It does not work in CMUCL, but I believe it should (modulo my
> understanding on the CLHS)

no way. I don't think this will work at all.

remember that my goal was to be able to do this:

(setf (global-pointer-position displ) (values 2 3))

dave

0 new messages