Hi all,
If I write the following code to experiment with squeak's block closures I get the expected answer: factorial := [:n | (n=1) ifTrue: [1] ifFalse: [n * (factorial value: (n - 1))]]. factorial 3. -> 6
In this case it appears that the block is implicitly returning the last object, ie: return 1 in the ifTrue: case. If I change the code to explicitly return the 1 ie: factorial := [:n | (n=1) ifTrue: [^1] ifFalse: [n * (factorial value: (n - 1))]]. factorial 3. -> An error indicating that the block cannot return.
My question is this: Why is the implicit return of values allowed and not the explicit? Is there a best practice for dealing with block closures in smalltalk, such that we should only be using implicit returns?
Thanks for your help, Jeff G.
An explicit "answer" from a block exits the method in which the block is defined. This is often used for "easy answers" in a method:
someMethodFor: aValue
aValue < 3 ifTrue: [^7]. aValue > 10 ifTrue: [^aValue * 10]. ^aValue complexExpressionHere.
As you discovered, if you don't answer from a block, the block's value is the last expression evaluated.
You actually *can* return a value from the "middle" of a block, but at that point, the code within the block is better factored out as a separate method. In fact, nested blocks and complex blocks and desire to have complex control inside a block are all signs that you aren't yet thinking in terms of small, single-purpose methods.
beginners@lists.squeakfoundation.org