From: Andrew Philpot
Subject: (SETF VALUES)
Date: 
Message-ID: <1993Jan6.213139.27999@kronos.arc.nasa.gov>
Is it possible to implement (SETF VALUES) in a Lisp which doesn't
already do this?

This is (will be) part of lisp, e.g., as per section 5.1.2.3 of the
dpans, but my vendor hasn't implemented it yet.

I thought it should be possible, and worked on this awhile, but
couldn't seem to get it to work.  VALUES is "just" a function, after
all, not a special form/special operator.  I don't have a lot of
experience with DEFINE-SETF-METHOD (now DEFINE-SETF-EXPANDER); I don't
think the simpler routes will work (will they?).  I imagine that a
home-brewed version would be less efficient than a built-in one, but
perhaps compile-time transformations could result in pretty good code.

If anyone has done this in a (stock hardware) Lisp, or knows good
reasons why it can or cannot be done, please let me know or post.

Andrew Philpot - "not a rocket scientist"
·······@ptolemy.arc.nasa.gov

From: Frank Yellin
Subject: Re: (SETF VALUES)
Date: 
Message-ID: <FY.93Jan6155542@hardwick.lucid.com>
In article <·····················@kronos.arc.nasa.gov>
·······@kepler.arc.nasa.gov (Andrew Philpot) writes: 

>   Is it possible to implement (SETF VALUES) in a Lisp which doesn't
>   already do this?

Always happy to help.

-- Frank Yellin
   ··@lucid.com

(define-setf-method values (&rest arguments &environment environment)
  (let (all-dummies all-values all-newvals all-setters all-getters)
    (dolist (place arguments)
      ;; look at each of the place arguments
      (multiple-value-bind (dummies values newvals setter getter)
          ;; get the setf method for each place argument
	  (get-setf-method-multiple-value place environment)
        ;; collect all the dummies, and the values to bind them to
	(push dummies all-dummies)   ; list of dummies for each place
	(push values all-values)     ; list of values for each place
	(push getter all-getters)    ; list of getters for each place
        ;; Collect the setters and the newvals variables.  This is
        ;; slightly complicated if (length newvals) isn't 1.  For example,
        ;; (setf (values a (values b c) d) ...) should always set c to 
        ;; 'nil, and (setf (values (values) b) ...) should just ignore the
        ;; first value passed.
	(cond ((null newvals)
	       ;; Will this ever happen?  A setf method expecting no newvals?
               ;; Create a gensym to gets its value, and ignore it
	       (let ((temp (gensym)))
		 (push temp all-newvals)
		 (push `(locally (declare (ignore ,temp)) ,setter) all-setters)))
	      ((null (cdr newvals))	; The most common case.
               ;; Just collect the setter and the single newval slot
	       (push (car newvals) all-newvals)
	       (push setter all-setters))
	      (t
               ;; The place argument expects multiple values.  Bind all but
               ;; the first one to nil in the setter.
	       (push (car newvals) all-newvals)		 
	       (push `(let ,(cdr newvals) ,setter) all-setters)))))
    ;; Return the five values
    (values (apply 'nconc (nreverse all-dummies))
	    (apply 'append (nreverse all-values))
	    (nreverse all-newvals)
	    `(values ,@(nreverse all-setters))
	    `(values ,@(nreverse all-getters)))))
From: Stephen M Jameson
Subject: Re: (SETF VALUES)
Date: 
Message-ID: <SJAMESON.93Jan8084615@fergie.atl.ge.com>
In article <···············@hardwick.lucid.com> ··@lucid.com (Frank Yellin) writes:
> 
> >   Is it possible to implement (SETF VALUES) in a Lisp which doesn't
> >   already do this?
> 

Pardon my ignorance here, but could you explain in what situations one would
wish to do this?
--
Steve Jameson                 General Electric Aerospace / Martin Marietta
········@atl.ge.com           Advanced Technology Laboratories
                              Moorestown, New Jersey              
****************************************************************************
**  . . . but I do not love the sword for its sharpness, nor the arrow    **
**  for its swiftness, nor the warrior for his glory.  I love only that   **
**  which they defend . . .                                               **
**    -- Faramir, "The Two Towers"                                        **
****************************************************************************
From: Barry Margolin
Subject: Re: (SETF VALUES)
Date: 
Message-ID: <1imgf4INNmf@early-bird.think.com>
In article <·····················@fergie.atl.ge.com> ········@atl.ge.com writes:
>In article <···············@hardwick.lucid.com> ··@lucid.com (Frank Yellin) writes:
>> >   Is it possible to implement (SETF VALUES) in a Lisp which doesn't
>> >   already do this?
>Pardon my ignorance here, but could you explain in what situations one would
>wish to do this?

The normal multiple-value assignment operators only allow you to assign to
variables, but you might want to assign to a set of generalized references.
Here's a simple, contrived example:

(defstruct (q-and-r (:conc-name qr-))
  quotient
  remainder)

(defvar *qr* (make-q-and-r))
...
(setf (values (qr-quotient *qr*) (qr-remainder *qr*))
      (floor numerator denominator))
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar
From: Stephen M Jameson
Subject: Re: (SETF VALUES)
Date: 
Message-ID: <SJAMESON.93Jan11145337@fergie.atl.ge.com>
In article <···········@early-bird.think.com> ······@think.com (Barry Margolin) writes:
> In article <·····················@fergie.atl.ge.com> ········@atl.ge.com writes:
> >In article <···············@hardwick.lucid.com> ··@lucid.com (Frank Yellin) writes:
> >> >   Is it possible to implement (SETF VALUES) in a Lisp which doesn't
> >> >   already do this?
> >Pardon my ignorance here, but could you explain in what situations one would
> >wish to do this?
> 
> The normal multiple-value assignment operators only allow you to assign to
> variables, but you might want to assign to a set of generalized references.
> Here's a simple, contrived example:
> 
> (defstruct (q-and-r (:conc-name qr-))
>   quotient
>   remainder)
> 
> (defvar *qr* (make-q-and-r))
> ...
> (setf (values (qr-quotient *qr*) (qr-remainder *qr*))
>       (floor numerator denominator))

Thank you, I understand now.  I don't have a Cltl2 or draft standard handy, but
isn't there such a thing as multiple-value-setf which would serve exactly this
purpose? 


> -- 
> Barry Margolin
> System Manager, Thinking Machines Corp.
> 
> ······@think.com          {uunet,harvard}!think!barmar
--
Steve Jameson                 General Electric Aerospace / Martin Marietta
········@atl.ge.com           Advanced Technology Laboratories
                              Moorestown, New Jersey              
****************************************************************************
**  . . . but I do not love the sword for its sharpness, nor the arrow    **
**  for its swiftness, nor the warrior for his glory.  I love only that   **
**  which they defend . . .                                               **
**    -- Faramir, "The Two Towers"                                        **
****************************************************************************
From: Bruno Haible
Subject: Re: (SETF VALUES)
Date: 
Message-ID: <1iupd2INN42h@nz12.rz.uni-karlsruhe.de>
········@atl.ge.com writes:
> Thank you, I understand now. I don't have a Cltl2 or draft standard handy, but
> isn't there such a thing as multiple-value-setf which would serve exactly this
> purpose? 

There is MULTIPLE-VALUE-SETQ, but this one only handles symbols as places.
The good thing about the (VALUES ...) place is that it makes
MULTIPLE-VALUE-SETQ obsolete. You can also write macros LETF and LETF* that
make MULTIPLE-VALUE-BIND obsolete. You can then write

(letf* (((values x y) (values (car l) (cdr l)))
        ((values q r) (floor x y)))
  (foo q r)
)

which expands into

(let ((x (car l)) (y (cdr l)))
  (multiple-value-bind (q r) (floor x y)
    (foo q r)
) )


Bruno Haible
······@ma2s2.mathematik.uni-karlsruhe.de
From: Barry Margolin
Subject: Re: (SETF VALUES)
Date: 
Message-ID: <1iupurINNih2@early-bird.think.com>
In article <······················@fergie.atl.ge.com> ········@atl.ge.com writes:
>Thank you, I understand now.  I don't have a Cltl2 or draft standard handy, but
>isn't there such a thing as multiple-value-setf which would serve exactly this
>purpose? 

No, there's only a MULTIPLE-VALUE-SETQ.

In hindsight, having separate SETQ and SETF was a bad design, IMHO.
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar