[ANSI-Smalltalk] Behaviour of #collect:

Richard O'Keefe ok at cs.otago.ac.nz
Thu Sep 25 02:29:31 BST 2008


On 25 Sep 2008, at 12:20 am, Ralph Johnson wrote:

>> I find it difficult to believe that anyone ever *designed*
>> Smalltalk's collection classes so that
>>       'abc' collect: [:each | each codePoint]
>> would drop you into the debugger.
>
> I bet that the original authors knew it.  They went out of their way
> to ensure that Interval>>collect: didn't return an interval, they
> could have done the same for String.  But they didn't want the species
> of String to be Array.  So, they lived with the weakness because they
> couldn't see a good way to eliminate it.  If we can get rid of it
> without too much cost, great!

I spent a lot of time examining the Squeak sources.
There was a lot of old stuff there which never made that much sense.
My favourite example of 'I don't believe this was designed' is the
behaviour of
	aCollection removeAll: aCollection.
Try it in an image you don't care about some time.

Especially with the Agile YAGNI mindset, a LOT of Smalltalk code gets
written for the case at hand, and then it's there in the image when
someone else comes along wanting to use something like that, and the
restrictions never got documented.

They went out of their way to ensure that Interval>>collect: didn't
return an interval, because it practically *never* worked, and
because collecting over an interval is actually quite a common thing
to do.  For example, if you want to process the first n elements of
an array,
	anArray from: 1 to: n collect: aBlock
doesn't exist, so you have to choose between
	(anArray copyFrom: 1 to: n) collect: aBlock
and	(1 to: n) collect: [:i | aBlock value: (anArray at: i)]
You'd rather not copy the array, so what do you do?

On the other hand,
	n := 0.
	aByteArray collect: [:each | n := n + each]
probably never got tried.

Even in commercial Smalltalks, I've found code lying around with
general names and no warning comments that obviously worked for
them but with missing or inappropriately inherited methods.

I do not for one second believe that Alan Kay and the others at PARC
couldn't have seen some way to deal with the issue, and very quickly
at that, _had it ever risen to their consciousness_.  If I can fix it
to my satisfaction, they could have.

>> The simplicity that counts most is simplicity for Smalltalk  
>> *programmers*,
>> not Smalltalk *implementors*.
>
> Maybe not.   See http://www.jwz.org/doc/worse-is-better.html
>
> Simplicity for users of an abstraction is important, but simplicity of
> implementors is also important

I didn't say it wasn't important, I said it wasn't MOST important.

> This is especially true for
> Smalltalk, where users tend to learn how something works by reading
> the source code.

This is, in fact, an even stronger argument for trying to make things
work whenever practical and DOCUMENTING VERY CLEARLY whatever
practical limitations may remain.

Let's take Visual Works Non-Commercial 7.5, simply because I happen to
have it on my machine.  Look for implementors of #collect:, the
relevant one is in SequenceableCollection.  If you read the code with
minute care, you will realise "OOPS, this only really works for
collections that accept any kind of object."  But there is no warning
comment in the code, and so far I haven't been able to find anything
in the manuals.  Nor is there any warning in String.  The class
comment, for example, says nothing about "beware of collect:".
What exactly are users supposed to learn from this?

>  The original Smalltalk developers achieved a great
> balance between simplicty of use and simplicity of implementation.

Agreed.  But they were men, not gods.  And they had to *invent* all
this stuff, not just fix it.




More information about the ANSI-Smalltalk mailing list