Aha! How to get rid of Blocks in Smalltalk.

Richard A. O'Keefe ok at atlas.otago.ac.nz
Fri Apr 28 01:13:00 UTC 2000


I wrote
	>David Farber <dfarber at numenor.com>
	>describes a restriction on blocks (one message send per block)
	>and the reason for it (making a callback-based GUI work).

David Farber replied	
	The *reason* i proposed the change to blocks really has nothing to do with
	the callback-based GUI example i described. the reason i proposed allowing
	only one message send per block is because you can always group message
	sends together by putting them into a method. blocks, as they currently
	stand, break the principle of monotony.
	
I am not familiar with the "principle of monotony".
If it's the old "each language should have ONE way to do each thing",
then I was impressed when I read it 20+ years ago, but then realised
it's not possible in any non-trivial language.  Given that we can
write x+y in some language (where "x" alphabetically precedes "y"),
does it make sense to ban y+x?  In Smalltalk, since we have
#ifTrue:ifFalse, should we eliminate #ifFalse:ifTrue:?

Let's take another stab at language trimming.
Smalltalk-sans-blocks doesn't need temporary variables either.
Let's take my DomNode>>select: example, which starts out like

   select: aBlock
      |result|
      result := self clone privateZap.
      ...

We can eliminate the temporary by writing

   select: aBlock
      ^self select: aBlock into: self clone privateZap.

   select: aBlock into: result
      ...

See?  We had two mechanisms for introducing local names, and we can
get rid of one of them.

That does introduce some awkwardness.  Because we can store into
temporaries, but not arguments.  But hey, that's ok, we don't need
assignment to temporaries either!  (Assignment to instance variables,
global variables, and so on, yes.  To temporaries, no.)  Prolog
manages fine without that.  Basically, you can handle any flow
chart by associating with each node the set of temporaries
and arguments live at that point, give the node a name, and make
those variables its arguments.  For this to be reasonably efficient,
we'd have to make method calls tail recursive, which would be nice anyway.

In fact, if we eliminate all but one-message-send blocks, we pretty
much have to learn how to do without assignment to method temporaries
anyway, because if we move stuff into other methods, it doesn't have
access to the method temporaries.

	i have heard this several times in regard to my proposal and i am convinced
	that exactly the opposite is the case. methods make code *clearer* and
	*easier* to understand.

But I provided an example where they *DIDN'T*.

	All i am saying is, let's use more methods.

That's not what I understood from earlier messages.

	Blocks (when they group message sends) are exactly the opposite;
	they are totally anonymous.

Of course.  Some things *shouldn't* be named.  Breaking code out of a
block and turning it into a method makes it something that is accessible
from outside, and something that subclass designers have to worry about.
Having to figure out how to re-implement a method (because it _might_ be
called from outside) which makes no real sense in a subclass (because it
uses a different algorithm) is not my idea of fun or clarity.

Of course, when you _want_ subclasses to override parts of an algorithm
without having to copy the rest, then it actually buys you something to
split those parts out as named methods.

	You have to actually *read* the code to figure out what is going
	on.  A well named method quickly lets you know what its group of
	messages is all about.
	
This seems backwards.  If you want to understand what a method is for, you
read its interface line and its comment.  Only if you want to understand
how it works do you want to read any of the code, and then you *need*
the code to be visible.  I have already made that point.  If there is
anything about a block that isn't obvious, well, that's what we've got
comments for.

Smalltalk provides some fairly heavy hints about style.
In particular, the size of the bottom pane in a browser quitely suggests
"it would be a really good idea for the entire method body to fit here".
As long as method bodies are small, I don't think it matters how many
blocks or message sends in blocks there are.  If anything_ about a method
is complicated, whether it is in a block or not, then is time to do some
refactoring.





More information about the Squeak-dev mailing list