Smalltalk Block Return

You can put a return statement in a Smalltalk block; if it's executed, it returns not only from the block but from the lexically enclosing method (provided it's still active -- if not, you get an exception).

The good

The syntax is clean and very brief.

Without block-return, you can't make cool stuff like this:

  result := Dialog 
    confirm: 'Are you sure you want to erase the *entire* hard drive?' 
    onCancelDo: [^self].
Since Smalltalk uses blocks for the basic control structures (ifs and loops and such), you need block-return to implement GuardClauses and other useful idioms:

  foo isBroken ifTrue: [^badResult]
The bad

The brevity of the syntax means that it doesn't generalise in the sort of way that CommonLisp's return-from does. For instance, if you define a block inside another block, the block-return feature doesn't give you a way to return from both those blocks but not from the enclosing method. (But note that many would consider it bad style to write code complicated enough to make this an issue.)

You can't use block-return for some of the amazing things that can be done with call/cc in Scheme. (This bug in Smalltalk really needs to be fixed. HaHaOnlySerious. -- StephanHouben)

The ugly (uhm.. misuse)

Generally speaking, use of the block return in Smalltalk is an error. It is VERY strange to have a thread of execution suddenly terminate with a return from the middle of a method, with even that method not getting a chance to see a return from whatever method it thinks is running. IMO intentional use of this feature militates against communication and rates as a CodeStench. In practice, probably over 90% of the block returns that occur in code are just mistakes. --RonJeffries

90% of block returns that occur in code are correct. 10% are mistakes. Most block returns are in ifTrue/ifFalse blocks, where they are clearly justified, or in ifAbsent/ifNone blocks, where again they are justified. I don't understand how you see 90% of the block returns being wrong. Can you please elaborate? --AnthonyLander

I think it would require a lot more code to implement the SmallTalk iterators without block-return. Consider the creation of #detect from #do. I'm I misunderstanding block-return?

Perhaps there's a distinction to be made here between implementors and users. Block-return in Smalltalk, like call/cc in Scheme, is a useful tool for building other abstractions, but maybe it's usually a bad idea to use it directly in "ordinary" code. Of course, in a language that gives users as much access to the internals as Smalltalk does, this distinction is much fuzzier than it is in languages like C.

Closely related facilities in other languages


EditText of this page (last edited July 12, 2004) or FindPage with title or text search