Lisp HUG Maillist Archive

setf values

setf values Hello,

The CAPI functions (setf pinboard-pane-position) and (setf pinboard-pane-size) have a particularity I’d never seen elsewhere :

(setf (pinboard-pane-position pane) (values x y))
Witch return (pinboard-pane-position pane) => x, y

My question is simple (and maybe very naïve) :
How to write a setf function that accept a (values x y) as his entry ? I didn’t find the solution nor in the doc or by testing.

Thanks

Denis


----------------------------------------------------
Denis Pousseur
6 clos du Drossart
1180 Bruxelles, Belgique

Mail :  denis.pousseur@compositeurs.be
Website : http://compositeurs.be
----------------------------------------------------

Re: setf values

On Thu, 23 Mar 2006 11:21:16 +0100, Denis Pousseur <denis.pousseur@compositeurs.be> wrote:

> How to write a setf function that accept a (values x y) as his entry
> ? I didn¹t find the solution nor in the doc or by testing.

You need a macro, not a function.

  <http://www.lispworks.com/documentation/HyperSpec/Body/m_defi_3.htm>

Here's a toy example that worked for me:

  CL-USER 38 > (defun frob (list)
                 "Returns the first two elements of LIST as two values."
                 (values (first list) (second list)))
  FROB

  CL-USER 39 > (define-setf-expander frob (place &environment env)
                 (multiple-value-bind (dummies vals newval setter getter)
                     (get-setf-expansion place env)
                   (let ((store-1 (gensym))
                         (store-2 (gensym)))
                     (values dummies
                             vals
                             `(,store-1 ,store-2)
                             `(setf (values (first ,getter) (second ,getter))
                                    (values ,store-1 ,store-2))
                             getter))))
  FROB

  CL-USER 40 > (defparameter *a* (list 1 2 3))
  *A*

  CL-USER 41 > (defparameter *b* (list *a* 'foo))
  *B*

  CL-USER 42 > (frob (first *b*))
  1
  2

  CL-USER 43 > (setf (frob (first *b*)) (values 42 43))
  42
  43

  CL-USER 44 > (frob (first *b*))
  42
  43

  CL-USER 45 > *a*
  (42 43 3)

  CL-USER 46 > *b*
  ((42 43 3) FOO)

  CL-USER 47 > (setf (frob *a*) (values (list 1 2) (list 3 4)))
  (1 2)
  (3 4)

  CL-USER 48 > (setf (second (nth-value 1 (frob (first *b*)))) 69)
  69

  CL-USER 49 > *a*
  ((1 2) (3 69) 3)

HTH,
Edi.


Re: setf values

On Thu, 23 Mar 2006 12:00:28 +0100, Edi Weitz <edi@agharta.de> wrote:

>   CL-USER 39 > (define-setf-expander frob (place &environment env)
>                  (multiple-value-bind (dummies vals newval setter getter)
>                      (get-setf-expansion place env)
>                    (let ((store-1 (gensym))
>                          (store-2 (gensym)))
>                      (values dummies
>                              vals
>                              `(,store-1 ,store-2)
>                              `(setf (values (first ,getter) (second ,getter))
>                                     (values ,store-1 ,store-2))
>                              getter))))

Should have been

  (define-setf-expander frob (place &environment env)
    (multiple-value-bind (dummies vals newval setter getter)
        (get-setf-expansion place env)
      (let ((store-1 (gensym))
            (store-2 (gensym)))
        (values dummies
                vals
                `(,store-1 ,store-2)
                `(setf (values (first ,getter) (second ,getter))
                       (values ,store-1 ,store-2))
                `(frob ,getter)))))


Re: setf values

It works perfectly, thanks a lot !


Le 23/03/06 12:09, « Edi Weitz » <edi@agharta.de> a écrit :

> 
> On Thu, 23 Mar 2006 12:00:28 +0100, Edi Weitz <edi@agharta.de> wrote:
> 
>>   CL-USER 39 > (define-setf-expander frob (place &environment env)
>>                  (multiple-value-bind (dummies vals newval setter getter)
>>                      (get-setf-expansion place env)
>>                    (let ((store-1 (gensym))
>>                          (store-2 (gensym)))
>>                      (values dummies
>>                              vals
>>                              `(,store-1 ,store-2)
>>                              `(setf (values (first ,getter) (second ,getter))
>>                                     (values ,store-1 ,store-2))
>>                              getter))))
> 
> Should have been
> 
> (define-setf-expander frob (place &environment env)
>   (multiple-value-bind (dummies vals newval setter getter)
>       (get-setf-expansion place env)
>     (let ((store-1 (gensym))
>           (store-2 (gensym)))
>       (values dummies
>               vals
>               `(,store-1 ,store-2)
>               `(setf (values (first ,getter) (second ,getter))
>                      (values ,store-1 ,store-2))
>               `(frob ,getter)))))
> 
> 



----------------------------------------------------
Denis Pousseur
6 clos du Drossart
1180 Bruxelles, Belgique

Mail :  denis.pousseur@compositeurs.be
Website : http://compositeurs.be
----------------------------------------------------




Updated at: 2020-12-10 08:48 UTC