From: Geert-Jan van Opdorp
Subject: setf and multiple values
Date: 
Message-ID: <GEERT.95May3115740@sparc.aie.nl>
Hi,

I have been experimenting writing setf methods
for `places' that hold multiple values. 
I encountered the following problem: because
in `define-setf-method' I have to give a list of
storage-variables, I have to either know how many
will be stored, or just giving a large amount
of variables and just hope it will suffice.

For example:

This is no problem because `places' tell me the
maximum needed storage-variables:

(define-setf-method values (&rest places)
  (let* ((methods (mapcar #'(lambda (place)
			      (multiple-value-list (get-setf-method place)))
		          places))
	 (tmps       (apply #'append (mapcar #'first  methods)))
	 (val-forms  (apply #'append (mapcar #'second methods)))
	 (store-vars (apply #'append (mapcar #'third  methods)))
	 (store-forms  (mapcar #'fourth methods))
	 (access-forms (mapcar #'fifth  methods))
	 (store-form `(progn ,@store-forms
		             (values ,@store-vars)))
	 (access-form `(values ,@access-forms)))
    (values tmps val-forms store-vars store-form access-form)))

But this is a problem:

(define-setf-method values-list (l)
  (let* ((tmps (list (gensym)))
	 (val-forms (list l))
         ;; Here I can't think of anything than 
         ;;  just providing lots of gensyms...
	 (store-vars (list (gensym) (gensym) (gensym) 
                           (gensym) (gensym) (gensym)))
	 (store-form `(progn (mapl #'(lambda (sub-l store)
				       (setf (car sub-l) (car store))
				       ,(car tmps)
				       ,store-vars))
		       (values ,@store-vars)))
	 (access-form `(values-list ,(car tmps))))
    (values tmps val-forms store-vars store-form access-form)))

Is there a better way? Or do I want the impossible?
Any light on this I would greatly appreciate!

Thanks,

Geert-Jan.
-- 
Geert-Jan van Opdorp
AI-Engineering
Amsterdam, The Netherlands
·····@aie.nl
From: Bruno Haible
Subject: Re: setf and multiple values
Date: 
Message-ID: <3ob4rm$brl@nz12.rz.uni-karlsruhe.de>
Geert-Jan van Opdorp <·····@sparc.aie.nl> wrote:

> But this is a problem:
>
> (define-setf-method values-list (l)
>   (let* ((tmps (list (gensym)))
> 	   (val-forms (list l))
>          ;; Here I can't think of anything than 
>          ;;  just providing lots of gensyms...
> 	   (store-vars (list (gensym) (gensym) (gensym) 
>                            (gensym) (gensym) (gensym)))
> 	   (store-form `(progn (mapl #'(lambda (sub-l store)
> 				       (setf (car sub-l) (car store))
> 				       ,(car tmps)
> 				       ,store-vars))
> 		         (values ,@store-vars)))
> 	   (access-form `(values-list ,(car tmps))))
>     (values tmps val-forms store-vars store-form access-form)))
>
> Is there a better way? Or do I want the impossible?
> Any light on this I would greatly appreciate!

Sounds impossible. How could you implement  (rotatef (place1) (place2))
if (place1) and (place2) both designate an unspecified number of Lisp
objects?

If you want only support for SETF, then you have to hack the SETF macro,
adding the following rule:

   (SETF (VALUES-LIST form) value) -->
   (VALUES-LIST (SETF form (MULTIPLE-VALUE-LIST value)))



                    Bruno Haible
                    ······@ma2s2.mathematik.uni-karlsruhe.de