From: David Bakhash
Subject: setf functions
Date: 
Message-ID: <c29u2hiu6sx.fsf@nerd-xing.mit.edu>
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

From: Coby Beck
Subject: Re: setf functions
Date: 
Message-ID: <954804834669@NewsSIEVE.cs.bonn.edu>
David Bakhash <·····@mit.edu> wrote in message
····················@nerd-xing.mit.edu...
| 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

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

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

Coby
From: dave
Subject: Re: setf functions
Date: 
Message-ID: <38ea8083$0$21259@senator-bedfellow.mit.edu>
Coby Beck <·····@mercury.bc.ca> wrote in message
·················@NewsSIEVE.cs.bonn.edu...
>
> David Bakhash <·····@mit.edu> wrote in message
> ····················@nerd-xing.mit.edu...
> | 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
>
> (setf global-pointer-position x *display* y)
>
> (multiple-value-setq (global-pointer-position *display*)  (values x y))

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
From: Coby Beck
Subject: Re: setf functions
Date: 
Message-ID: <BuyG4.9918$eh.914814@news.bc.tac.net>
dave <········@yahoo.com> wrote in message
·····················@senator-bedfellow.mit.edu...
>
> Coby Beck <·····@mercury.bc.ca> wrote in message
> ·················@NewsSIEVE.cs.bonn.edu...
> >
> > David Bakhash <·····@mit.edu> wrote in message
> > ····················@nerd-xing.mit.edu...
> > | 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
> >
> > (setf global-pointer-position x *display* y)
> >
> > (multiple-value-setq (global-pointer-position *display*)  (values x y))
>
> 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).

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
From: David Bakhash
Subject: Re: setf functions
Date: 
Message-ID: <m3ln2sof20.fsf@alum.mit.edu>
"Coby Beck" <·····@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)))
From: Harald Hanche-Olsen
Subject: Re: setf functions
Date: 
Message-ID: <pcosnx07auz.fsf@math.ntnu.no>
+ "Coby Beck" <·····@mercury.bc.ca>:

| dave <········@yahoo.com> wrote in message
| ·····················@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
From: Erik Naggum
Subject: Re: setf functions
Date: 
Message-ID: <3163950557082770@naggum.no>
* Harald Hanche-Olsen <······@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
From: Harald Hanche-Olsen
Subject: Re: setf functions
Date: 
Message-ID: <pcosnwzalso.fsf@math.ntnu.no>
+ Erik Naggum <····@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.

-- 
* 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
From: Fernando D. Mato Mira
Subject: Re: setf functions
Date: 
Message-ID: <38EC533D.68A9DD59@acm.org>
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
From: Marco Antoniotti
Subject: Re: setf functions
Date: 
Message-ID: <lwem8jtvgl.fsf@parades.rm.cnr.it>
"Fernando D. Mato Mira" <········@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)

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
From: Erik Naggum
Subject: Re: setf functions
Date: 
Message-ID: <3164020402912136@naggum.no>
* Marco Antoniotti <·······@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
From: Dave Bakhash
Subject: Re: setf functions
Date: 
Message-ID: <m3aej79ta3.fsf@lost-in-space.ne.mediaone.net>
Marco Antoniotti <·······@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
From: Marco Antoniotti
Subject: Re: setf functions
Date: 
Message-ID: <lw66twyjo3.fsf@parades.rm.cnr.it>
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