Fear and loathing of the "perification" of Smalltalk

Paolo Bonzini paolo.bonzini at lu.unisi.ch
Thu Sep 13 08:57:19 UTC 2007


> Eh? What? You're calling me a troll? If that's the case that's just 
> silly and very inappropriate since you are deeply mistaken. You know me 
> Paolo, we've had interactions over the years, and I'm quite surprised 
> that you'd stoop to person an hominem attacks by calling me a troll. 

Exactly because I knew you, I was as surprised by your messages; 
sometimes one can be a troll without realizing it.  I should probably 
have said "you're acting as a troll".

(Besides, that message was posted off-list for a reason.  Now that it's 
made public, I'll try to sum up my arguments in a single message.)

> 1) You'd have to agree that the normal Smalltalk evaluator simply 
> returns the object from the last statement in a sequence of statements? 
> Right? For example, the value of the following block is the value of 
> "c", whatever that is: "[ a. b. c ] value". Let's assume that the 
> variables are defined in the method or are instance variables.

So far so good.

> 2) You'd have to agree that it would be possible for a NEW evaluator to 
> return a collection containing the values of ALL the statements in a 
> sequence of statements?

Yes, but I agree with Damien that I would *not* call it a block.  The 
definition of statement is blurred away after compilation.  In principle 
it would be possible to compile a block to an array of statements, each 
of them being a lambda:

      (Array new: 3)
           at: 1 put: [<lambda> 1];
           at: 2 put: [<lambda> 2];
           at: 3 put: [<lambda> 3];

(more on the syntax extension later).  Then, you could indeed implement 
#value/#values like this:

   BlockClosure>>#value
       ^self blocksForEachStatement inject: nil into:
           [ <lambda> :old :each | each value ]

   BlockClosure>>#values
       ^self blocksForEachStatement collect: [ <lambda> :each | each value ]

   LambdaBlockClosure>>#value
       <primitive: ...>

   LambdaBlockClosure>>#values
       ^Array with: self value

I will even make a bold statement about performance; you could implement 
#value via a BlockClosure>>#asLambda method and cache its result; then 
the result would probably not even be much slower than the current state 
of things!

However, this beg the question: is it worth it?  In my opinion, no.  It 
would be probably like one or two weeks of work to add the necessary 
support (the VM does not need to be changed, if I thought it right). 
The syntax still needs to be changed, or you risk infinite recursion 
(those <lambda> markers in the source code were there for a reason). 
So, overall, the amount of thought in designing your extension exceeds 
the amount of thought in designing curly braces (and I don't see a way 
to design the extension cleanly without a syntax extension too).

(In addition, in older versions of Squeak curly braces were allowed on 
the LHS of the assignment too; I don't remember if this is still there 
or was removed.  This kind of tuple assignment is quite elegant and 
useful even though it may apply only in relatively few cases).

> So, assuming that you understood the two above paragraphs then you'd 
> have to agree that (2) is a valid option or alternative to (1). As such 
> you'd have to agree that I do know what I'm talking about, since it's 
> clearly explained in the above two paragraphs. Simply put Blocks can do 
> the job that curly braces do leaving curly braces out of Smalltalk 
> syntax and available for a far better purpose.

I'd say that you really knew what you were talking about, if you came up 
with something like the sketch I did above.  I have high expectations on 
any message that talks about the implementation of the language 
(probably because I have better skills there than in OO design), and 
they were missed too often in the course of this thread.

Boasting the power of your proposed extension in this example:

>>    [
>>        1 to: 1000 do: [:count | count random ]
>>    ] streamObjectsInto: aStreamOfRandomIntegers

(which only includes one statement, i.e. the send of #to:do:) was for me 
the sign that you hadn't put the necessary thought into your message, 
especially compared to the boldness of the message itself.

In the remainder of the thread, your stating that {...} needs support in 
the VM, and your presenting SOAR as an alternative to bytecodes (when it 
should be clear that a hypotetical alternative to bytecodes should allow 
*more* reflection, not less as is the case for native code!), was too 
close to being gratuitous trolling.

> Now, I know that you and others will raise the specter that you can't 
> implement this notion with blocks since given your ideas of how to 
> implement it it wouldn't be efficient and would mangle the virtual 
> machine. Well, I've heard this and maybe it's time to mangle the virtual 
> machine for Smalltalk up a bit! Time for some innovation! Nothing like 
> stirring the pot to get it either.

I will concede you this.  However, give time to think on it since, as 
you said, squeak-dev has some clever people in it.  A defensive attitude 
  and an enormous thread is not needed to stir the pot.

> "common sign that your love for a language
> has been corrupted into religion".

"Your" was meant to be impersonal (don't you love ambiguous grammars? 
:-)  I think that sometimes one needs to look "out of the box", and it 
happens too often that this is limited to features while other things 
(including syntax) are taken too much for granted.  But a language is a 
tool, not a religion: if one feels a need and the language cannot 
express it well, it might be good to look at the same time "in the box" 
and "out of the box".  I can give you examples.

One is foreign function interface; you can define external functions 
either with a "magical" method that you send to the class and does 
everything (like "Integer class define: #getPid as: 'int getpid (void)'" 
for example), or you can see the similarity with a primitive and extend 
<primitive: ...> into the pragma syntax that's seen in most modern 
Smalltalks.  The second example is Unicode; you can force everybody to 
write "16r1000 asCharacter" (which is also less efficient than $A) or 
try to find a simple extension to the syntax, for example $<16r1000> 
could be an idea.

(On the other hand, there are surely cases where the existing 
abstractions are more than enough, and there's no need to introduce new 
ones: continuations and generators are an example).

My opinion is that part of what is blocking evolution of Smalltalk is 
the lack of "looking out of the box".  Evolution does not mean 
perlification; on the contrary, if Randal Schwartz is in this mailing 
list we might have something to learn from him and Perl.

Paolo




More information about the Squeak-dev mailing list