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.
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
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.