Mutliple Return Values [was: Re: Why we should remove {} from Squeak]

Dan Ingalls Dan at SqueakLand.org
Wed Oct 3 16:15:59 UTC 2001


"Richard A. O'Keefe" <ok at atlas.otago.ac.nz>  wrote...

>Here's a favourite example of mine.  In my XML kit, I have a function
>that finds a place in a tree and splits it at that point.  Conceptually,
>it's quite simple:
>
>    split_before :: (Tree -> Bool) Tree -> (Tree, Tree)
>    split_after  :: (Tree -> Bool) Tree -> (Tree, Tree)
>
>If I followed the Eiffel dogma, I'd have to write
>	tree1.split_before(condition)
>	tree2 := tree2.piece_split_off
>which requires every tree to have a place to hold a piece split off.
>In Smalltalk, I have a choice of
>
>(a) tree2 := tree1 splitBefore aBlock.
>(b) aPair := tree1 splitBefore aBlock.
>    tree1 := aPair first.
>    tree2 := aPair second.   
>(c) anArray := tree1 splitBefore aBlock.
>    tree1 := anArray first.
>    tree2 := anArray second.
>
...and, please don't overlook:

	originalTree splitBefore: splitBlock
		beforeAndAfter: [:tree1 :tree2 | ...]

When I need this kind of multiple return,
this is my choice for how to do it.

Two examples from the image:

	<methodReference> setClassAndSelectorIn:
		[:class :selector | ...]
and
 	<RunArray> at: index setRunOffsetAndValue:
		[:run :offset :value |
		^ (runs at: run) - offset]

These messages are not named ideally, but they illustrate the convenience of providing, at the call site, an immediate name and scope for the parts "returned" (note no additional declaration required for tree1 and tree2).  Think of this use of blocks as an in-line tuple, and it's hard to beat.

We have had this multiple return value discussion before, and it would be nice if someone would scan the archives and collect it in the Swiki, if it isn't already there.

	- Dan




More information about the Squeak-dev mailing list