From: Pascal Bourguignon
Subject: Re: How can I access function multiple-values partially (w/o warnings)?
Date: 
Message-ID: <87mzr0cc4f.fsf@thalassa.informatimago.com>
Jeffrey Cunningham <····················@boeing.com> writes:

> If I need to use only some of the outputs from a multiple valued function,
> say for example:
>
> (defun somefunction()
> 	;; compute x,y,z
> 	(values x y z))
>
> (multiple-value-bind (x y z) (somefunction)
> 	(format t "I'm only using z=~A~%" z))
>
> When I compile this second line, it emits warnings that I've defined but
> never used x and y. How can I eliminate this warning? I only want to get
> at z in this case, not x and y, but can't find a way to get around the
> need for them as place holders. 
>
> Incidentally, I have no control over 'somefunction'.

By adding declarations:

 (multiple-value-bind (x y z) (somefunction)
    (declare (ignore x y))
 	(format t "I'm only using z=~A~%" z))

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

Nobody can fix the economy.  Nobody can be trusted with their finger
on the button.  Nobody's perfect.  VOTE FOR NOBODY.

From: Adam Warner
Subject: Re: How can I access function multiple-values partially (w/o warnings)?
Date: 
Message-ID: <pan.2005.05.13.02.27.15.365607@consulting.net.nz>
On Fri, 13 May 2005 00:28:48 +0200, Pascal Bourguignon wrote:
>> When I compile this second line, it emits warnings that I've defined
>> but never used x and y. How can I eliminate this warning? I only want
>> to get at z in this case, not x and y, but can't find a way to get
>> around the need for them as place holders.
>>
>> Incidentally, I have no control over 'somefunction'.
> 
> By adding declarations:
> 
>  (multiple-value-bind (x y z) (somefunction)
>     (declare (ignore x y))
>  	(format t "I'm only using z=~A~%" z))

Jeffrey, IGNORABLE is also good for those situations where there's no
reason you must ignore X and Y and you don't want to change the
declaration if you start using the variables: (declare (ignorable x y z))

An improved MULTIPLE-VALUE-BIND would accept NIL as a placeholder for
unused values. Why be forced to make up variable names that you don't want
to use? Here's a MVB macro with the functionality:

(defmacro mvb (vars values-form &body body)
  "NIL can be used in the place of a symbol naming a variable as an extension
to ignore a return value."
  (let* ((ignorables)
         (new-vars (loop for var in vars collect
                         (if (null var)
                             (let ((g (gensym)))
                               (push g ignorables)
                               g)
                             var))))
    `(multiple-value-bind (,@new-vars)
      ,values-form
      (declare (ignore ,@(nreverse ignorables)))
      ,@body)))

Example:
(defun somefunction ()
  (values 1 2 3))

(mvb (nil nil z)
    (somefunction)
  (format t "I'm only using z=~A~%" z))

The approach is clear:
(macroexpand-1 '(mvb (nil nil z)
    (somefunction)
  (format t "I'm only using z=~A~%" z)))
 =>
(MULTIPLE-VALUE-BIND (#:G3888 #:G3889 Z)
    (SOMEFUNCTION)
  (DECLARE (IGNORE #:G3888 #:G3889))
  (FORMAT T "I'm only using z=~A~%" Z))

i.e., all occurrences of NIL are simply replaced with ignored gensyms.

You may also want to add an ~/.emacs rule for MVB indentation:

;;Refer /usr/share/emacs/21.3/lisp/emacs-lisp/cl-indent.el for examples
(setq lisp-indent-function 'common-lisp-indent-function)
(put 'mvb 'common-lisp-indent-function '((&whole 6 &rest 1) 4 &body))

Regards,
Adam
From: Jock Cooper
Subject: Re: How can I access function multiple-values partially (w/o warnings)?
Date: 
Message-ID: <m364xndka3.fsf@jcooper02.sagepub.com>
Adam Warner <······@consulting.net.nz> writes:

> On Fri, 13 May 2005 00:28:48 +0200, Pascal Bourguignon wrote:
> >> When I compile this second line, it emits warnings that I've defined
> >> but never used x and y. How can I eliminate this warning? I only want
> >> to get at z in this case, not x and y, but can't find a way to get
> >> around the need for them as place holders.
> >>
> >> Incidentally, I have no control over 'somefunction'.
> > 
> > By adding declarations:
> > 
> >  (multiple-value-bind (x y z) (somefunction)
> >     (declare (ignore x y))
> >  	(format t "I'm only using z=~A~%" z))
> 
> Jeffrey, IGNORABLE is also good for those situations where there's no
> reason you must ignore X and Y and you don't want to change the
> declaration if you start using the variables: (declare (ignorable x y z))
> 
> An improved MULTIPLE-VALUE-BIND would accept NIL as a placeholder for
> unused values. Why be forced to make up variable names that you don't want
> to use? Here's a MVB macro with the functionality:
> 
> (defmacro mvb (vars values-form &body body)
>   "NIL can be used in the place of a symbol naming a variable as an extension
> to ignore a return value."
>   (let* ((ignorables)
>          (new-vars (loop for var in vars collect
>                          (if (null var)
>                              (let ((g (gensym)))
>                                (push g ignorables)
>                                g)
>                              var))))
>     `(multiple-value-bind (,@new-vars)
>       ,values-form
>       (declare (ignore ,@(nreverse ignorables)))
>       ,@body)))
> 

I did something similar recently for destructuring bind:

(defmacro my-destructuring-bind (tree expr &body body)
  (let ((ignores nil))
    (labels ((walk-tree (tree)
	       (if (null tree) nil
		   (let ((lhs (car tree)))
		     (cons (cond ((null lhs)
				  (let ((new-sym (gensym)))
				    (push new-sym ignores)
				    new-sym))
				 ((consp lhs)
				  (walk-tree lhs))
				 (t (car tree)))
			   (walk-tree (cdr tree)))))))
      (let ((new-tree (walk-tree tree)))
	`(destructuring-bind ,new-tree ,expr
	  (declare (ignore ,@ignores))
	  ,@body)))))

Because I was using a regex package that returned a structured list
with most values I wanted to ignore.  This code works but hasn't 
been tested extensively.  Also declarations are not supported.
Anyone have a better macro for this sort of thing?

Jock Cooper
From: Marco Antoniotti
Subject: Re: How can I access function multiple-values partially (w/o warnings)?
Date: 
Message-ID: <BY8he.43$mi7.64248@typhoon.nyu.edu>
Adam Warner wrote:
> On Fri, 13 May 2005 00:28:48 +0200, Pascal Bourguignon wrote:
> 
>>>When I compile this second line, it emits warnings that I've defined
>>>but never used x and y. How can I eliminate this warning? I only want
>>>to get at z in this case, not x and y, but can't find a way to get
>>>around the need for them as place holders.
>>>
>>>Incidentally, I have no control over 'somefunction'.
>>
>>By adding declarations:
>>
>> (multiple-value-bind (x y z) (somefunction)
>>    (declare (ignore x y))
>> 	(format t "I'm only using z=~A~%" z))
> 
> 
> Jeffrey, IGNORABLE is also good for those situations where there's no
> reason you must ignore X and Y and you don't want to change the
> declaration if you start using the variables: (declare (ignorable x y z))
> 
> An improved MULTIPLE-VALUE-BIND would accept NIL as a placeholder for
> unused values. Why be forced to make up variable names that you don't want
> to use? Here's a MVB macro with the functionality:
> 

Well, the OP question is actually answered by NTH-VALUE.  As for 
extending DESTRUCTURING-BIND, here is YASP (yet another shameless plug): 
check out CL-UNIFICATION in common-lisp.net  :)

Cheers
--
Marco
From: Pascal Bourguignon
Subject: Re: How can I access function multiple-values partially (w/o warnings)?
Date: 
Message-ID: <87k6lyzvpl.fsf@thalassa.informatimago.com>
Jeffrey Cunningham <····················@boeing.com> writes:

> On Fri, 13 May 2005 17:26:59 -0400, Marco Antoniotti wrote:
>
>> Well, the OP question is actually answered by NTH-VALUE.  As for 
>> extending DESTRUCTURING-BIND, here is YASP (yet another shameless plug): 
>> check out CL-UNIFICATION in common-lisp.net  :)
>> 
>> Cheers
>
> I will (check out cl-unification).
> I'm not sure how nth-value would solve the problem, though. When I try
> this:
>
> (nth-value 2 (list  1 2 3 4 5))
>
> I get nil.


You should not confond: list  nth        destructuring-bind 
                  with: values nth-value multiple-value-bind

Either: (nth-value 2 (values 1 2 3 4 5)) ; stores multiple values in 
                                         ; result registers and selects
                                         ; the third.

or:     (nth       2 (list   1 2 3 4 5)) ; conses a list of five elements
                                         ; and then seeks the third.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
The rule for today:
Touch my tail, I shred your hand.
New rule tomorrow.