Thursday, June 04, 2009

In Support Of Multiple Return Values

Lately I've been working on a gambling app for a client (fun stuff!) and I find myself making pretty heavy use of multiple return values. Here's an example:

 (define (deal deck count)
   ...
   (values the-dealt-cards the-updated-deck))

In this case, I've got a nice and functional interface for dealing cards - send in a deck and the number of cards I want dealt and get back the cards and the updated deck. This makes for plenty of let-values but I'm not finding them too clunky. For example:

  (define (play ...)
   (let-values ([(player1 deck) (deal deck 5)])
     (let-values ([player2 deck) (deal deck 5)])
       ;; player 1 & 2 both have 5 cards and our deck has 10 fewer cards
       ...)))

The multiple values approach seems to work well here, as it avoids me having to come up with a structure to describe the result or use a list. In either case, I don't have to worry about destructuring the results later on.

What do you think? Should I be considering an alternate approach than values?

I was going to lament the lack of multiple return values in other languages, but, PHP kinda sorta handles it somewhat gracefully. You can say:

  function deal($deck, $count) {
    ...magic...
    return array($the_cards, $the_updated_deck);
  }

  list($cards, $deck) = deal($deck, 10);

Not great, but at least list makes it easy to get a hold of the multiple values.

I'm not sure I'd want to try this in Java though...

3 comments:

  1. Hi Ben,

    I am pro-values. The reason I like is that it communicates to the reader your intent regarding that to which a function evaluates.

    You could have returned a list, but that would have told the user that you can return any number of results, including the empty list.

    You could have created a record (structure), but it really isn't structure data that you intend to reuse anywhere else (much like lambda functions).

    Enter values: you are documenting your intent. The only way to use those values is to bind them, so bam, you are done.

    You allude to PHP's list destructuring, but syntax really isn't the issue here as you could use PLT match or any of the other match libraries to do the same thing. I think what you are talking about is capturing intent, and that is what values does.

    That said, here are some wildly varying views on this:

    http://groups.google.com/group/comp.lang.scheme/browse_thread/thread/ba8873b2f955af67/54ac3c381f9fed47?q=values+performance&lnk=ol&

    ReplyDelete
  2. There are also other threads in comp.lang.scheme if you go looking.

    ReplyDelete
  3. Grant -

    That's an excellent point about values conveying specific intent. I like it.

    -Ben

    ReplyDelete