Newsgroups: comp.lang.lisp
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!swrinde!pipex!dircon!rheged!simon
From: simon@rheged.dircon.co.uk (Simon Brooke)
Subject: Re: Urgent! Help! Return more than one argument.
Message-ID: <D0JGt5.G0@rheged.dircon.co.uk>
Organization: none. Disorganization: total.
References: <3c3es0$19s@masala.cc.uh.edu>
Date: Fri, 9 Dec 1994 10:22:16 GMT
Lines: 61

In article <3c3es0$19s@masala.cc.uh.edu>,
>Here is my question. How can I return more than one
>argument to the call function. Let's say two and three.
>Normal function only returns one argument.

If you are using Common LISP (as I expect you are) then the best/most
efficient thing to do is to use the multiple values mechanism, as
detailed in an earlier followup.

However, the more elegant thing to do (and if you're not using Common
LISP the only thing to do) is to remember LisP is about *lists* and
that your function can happily return a list. So the skeleton would
look like this:

(defun myfun (<args>)
    (let (<local bindings if any>)
        (<code shared by all partial results>)
        (list
            (<code to produce partial result one>)
            (<code to produce partial result two>)
            ....
        )))

Your caller must then use car, cadr, caddr... to unpack the partial results.

NOTES:

(1) If you have no local bindings, you don't need let;
(2) If you have only two partial results, use cons rather than list
    and use car and cdr to unpack.

The alternative solution -- using sybols not in the scope of myfun to
pass information back -- is abhominable, and if your tutor is any
good, will properly earn you a fail.

DISCUSSION

If this mechanism is so easy to use, and so general, why should Common
LISP users prefer multiple-value-bind?

You can ignore Guy Steele's claim that multiple-value-bind is cleaner.
He is entitled to his own aesthetics. The answer is simple: Common
LISP is designed to be optimised on present generation machines, which
typically use a combination of stack and registers rather than stack
alone to handle transient data. There is assumed to be a substantial
overhead in transfering data between the stack and the registers.

Using multiple-value-bind is a way of signalling to the compiler that
what you are doing is passing back multiple transient values (i.e. you
don't actually intend to hold on to the list for any longer term
purpose), and consequently (i) it can save consing, and (ii) hold the
values in registers, provided there are sufficient registers to spare.

In otherwords it's a machine oriented hack, and nothing to do with
clenliness of language, but it works and does (on present generation
machines) save machine resources, so it's worth doing.
-- 
--------simon@rheged.dircon.co.uk

	There are no messages. The above is just a random stream of
	bytes. Any opinion or meaning you find in it is your own creation.
