Multiple return values

214 views
Skip to first unread message

Fredrik Appelberg

unread,
Oct 20, 2008, 6:51:33 AM10/20/08
to clo...@googlegroups.com
Hi all,

The CL feature for handling multiple return values from a function come in really handy sometimes and make for cleaner APIs. For example, the ROUND function returns the integer part of a float as the regular value (as this is what you want most of the time), but optionally also returns the floating point part in case you want it.

I haven't found anything like MULTIPLE-VALUE-BIND in Clojure. Are there any plans of incorporating any kind of mechanism for multiple return values?

Cheers,
-- Fredrik
==============================================
What am I up to? http://twitter.com/appelberg

Parth Malwankar

unread,
Oct 20, 2008, 7:03:22 AM10/20/08
to Clojure


On Oct 20, 3:51 pm, "Fredrik Appelberg" <fredrik.appelb...@gmail.com>
wrote:
> Hi all,
>
> The CL feature for handling multiple return values from a function come in
> really handy sometimes and make for cleaner APIs. For example, the ROUND
> function returns the integer part of a float as the regular value (as this
> is what you want most of the time), but optionally also returns the floating
> point part in case you want it.
>
> I haven't found anything like MULTIPLE-VALUE-BIND in Clojure. Are there any
> plans of incorporating any kind of mechanism for multiple return values?

Hi Fredrik,

Similar results can be accomplished using vectors and
destructuring in Clojure.

user=> (defn foo [] [:one :two :three])
#=(var user/foo)
user=> (let [[a b c] (foo)] (println b))
:two
nil
user=>

The destructuring capabilities of "let" are quite nice.
A bunch of examples are available in the let reference:
http://clojure.org/special_forms

Parth

Michel Salim

unread,
Oct 20, 2008, 3:47:43 PM10/20/08
to Clojure


On Oct 20, 7:03 am, Parth Malwankar <parth.malwan...@gmail.com> wrote:
> On Oct 20, 3:51 pm, "Fredrik Appelberg" <fredrik.appelb...@gmail.com>
> wrote:
>
> > Hi all,
>
> > The CL feature for handling multiple return values from a function come in
> > really handy sometimes and make for cleaner APIs. For example, the ROUND
> > function returns the integer part of a float as the regular value (as this
> > is what you want most of the time), but optionally also returns the floating
> > point part in case you want it.
>
> > I haven't found anything like MULTIPLE-VALUE-BIND in Clojure. Are there any
> > plans of incorporating any kind of mechanism for multiple return values?
>
> Hi Fredrik,
>
> Similar results can be accomplished using vectors and
> destructuring in Clojure.
>
> user=> (defn foo [] [:one :two :three])
> #=(var user/foo)
> user=> (let [[a b c] (foo)] (println b))
> :two
> nil
> user=>
>
> The destructuring capabilities of "let" are quite nice.
> A bunch of examples are available in the let reference:http://clojure.org/special_forms
>
We could further combine this by making a scalar equivalent to a
vector of length 1; that way, users who expect a function to return
one value would not be confused when a vector is returned instead.

There's a problem, of course -- how to distinguish between vector-as-
holder-of-return-values and vector-as-the-returned-value ?

Cheers,

--
Michel Salim

Fredrik Appelberg

unread,
Oct 20, 2008, 4:00:35 PM10/20/08
to clo...@googlegroups.com


On Mon, Oct 20, 2008 at 1:03 PM, Parth Malwankar <parth.m...@gmail.com> wrote:

On Oct 20, 3:51 pm, "Fredrik Appelberg" <fredrik.appelb...@gmail.com>
wrote:
> Hi all,
>
> The CL feature for handling multiple return values from a function come in
> really handy sometimes and make for cleaner APIs. For example, the ROUND
> function returns the integer part of a float as the regular value (as this
> is what you want most of the time), but optionally also returns the floating
> point part in case you want it.
>
> I haven't found anything like MULTIPLE-VALUE-BIND in Clojure. Are there any
> plans of incorporating any kind of mechanism for multiple return values?

Hi Fredrik,

Similar results can be accomplished using vectors and
destructuring in Clojure.

user=> (defn foo [] [:one :two :three])
#=(var user/foo)
user=> (let [[a b c] (foo)] (println b))
:two
nil
user=>

The destructuring capabilities of "let" are quite nice.
A bunch of examples are available in the let reference:
http://clojure.org/special_forms

I agree that Clojure's let form goes a long way towards making multiple return values easy to handle. What's missing, though, is the ability to return a single value or multiple values depending on the context in which the function was called. I.e, if the call happens enclosed in MULTIPLE-VALUE-BIND, I get all the returned values, otherwise I get a single one.

Anyway, this is a really nifty feature in CL, but it might not be necessary in Clojure as its 'let' form is more potent.

Jeffrey Chu

unread,
Oct 21, 2008, 1:48:21 AM10/21/08
to Clojure
Hi,

If you really need multiple value calls, you can always try to emulate
parts of it with some fancy macros. I've hacked up a quick proof of
concept - I haven't gotten a chance to test it too much, but it seems
to work.

http://paste.lisp.org/display/68919

- Jeff


On Oct 20, 1:00 pm, "Fredrik Appelberg" <fredrik.appelb...@gmail.com>
wrote:
> On Mon, Oct 20, 2008 at 1:03 PM, Parth Malwankar
> <parth.malwan...@gmail.com>wrote:

Fredrik Appelberg

unread,
Oct 21, 2008, 4:21:38 AM10/21/08
to clo...@googlegroups.com
On Tue, Oct 21, 2008 at 7:48 AM, Jeffrey Chu <joc...@gmail.com> wrote:

Hi,

If you really need multiple value calls, you can always try to emulate
parts of it with some fancy macros. I've hacked up a quick proof of
concept - I haven't gotten a chance to test it too much, but it seems
to work.

http://paste.lisp.org/display/68919

Nice. I tried to hack a simple macro for this on my way to work this morning. It worked reasonably, but choked on nested statements (and probably a lot of other things as well). Yours looks a lot better. :)
Reply all
Reply to author
Forward
0 new messages