[Pharo-project] could we agree to remove caseOf: and caseOf:otherwise:

Benoit St-Jean bstjean at yahoo.com
Sun Feb 13 19:29:45 CET 2011


I mostly agree with you on all points Bill..  It's just that usually, "ugliness" 
in Smalltalk, is a symptom of bad design or at least that something could be 
refactored a little bit more...  In all the years and all the Smalltalk 
implementations, why did no one ever implemented Number arithmetic operations 
using case statements (or case style) and used double dispatch instead ??  I 
guess there are many other ways this could have been implemented more 
effectively (performance-wise) but simplicity & clarity seem to have won.  
Simplicity & clarity have their merits.  It's no wonder, a few years ago, there 
was a Smalltalk implementation that allowed "assembly code" inside Smalltalk 
code but this feature never got popular even though "it could have been 
extremely fast".  What a real mess.  Probably really efficient & fast but was a 
mess from a readability & maintenance standpoint...

I'm just really skeptical about always presenting speed as the main argument 
when it comes to Smalltalk & the way to code and implement things.  It's like 
having a Cessna and trying to make it fly like the space shuttle.  It wasn't 
designed for that.  Yes we could add boosters, yes we could extend the wings, 
yes we could change the engine, yes we could patch this, yes we could do that, 
etc.  If I want to go to the moon, I'll use the Space Shuttle but in the 
meantime, I must not forget I'm piloting and using a Cessna.

This #caseOf:otherwise: painfully reminds me of a coding horror I saw years 
ago...  The programmer told us he was never sure of the receiver (a few possible 
classes only) and had to rely on a "very useful and flexible" method called 
#ifTrue:ifFalse:ifNil:ifEmpty:otherwise:  .Obviously, you can only imagine the 
rest of the "logic" involved where this method was called...  Double dispatching 
would have been so simpler and more elegant.  It felt like doing BASIC a class 
browser !

I'm not against change when needed.  I'm not against suggestions.  I'm not 
against speed improvements. But I'm not for speed at all costs, especially code 
readability.  If we want speed, it's in the VM we have to implement it.  Cincom 
rarely relied on ugly Smalltalk code implementations to make VW faster.  They 
pushed the VM.  Not the Collection hierrachy, not the Number hierarchy, not the 
Stream, etc.

Besides, performance arguments is a slippery slope.  What about memory 
consumption?  Which road should we take ?  It's fast but it instantiates 10 
million objects or it's small and used 3Ks of memory but runs 5 seconds slower?  
There's always another side to what "efficiency" means to everyone.

My 2 cents!

:)



 -----------------
Benoit St-Jean
Yahoo! Messenger: bstjean
A standpoint is an intellectual horizon of radius zero.
(Albert Einstein)




________________________________
From: "Schwab,Wilhelm K" <bschwab at anest.ufl.edu>
To: "Pharo-project at lists.gforge.inria.fr" <Pharo-project at lists.gforge.inria.fr>
Sent: Sun, February 13, 2011 12:13:41 PM
Subject: Re: [Pharo-project] could we agree to remove caseOf: and 
caseOf:otherwise:

Read the Federalist Papers and Bastiat's "The Law," and then we can talk about 
democracy, one illustration of which is three wolves and a sheep voting on the 
dinner menu.  In its raw form, yes, I argue against democracy, aka mob rule.

However, we are not talking about taking someone's life, liberty or property 
here: this is software, and one can always retain #caseOf: in any image.  
However, a vote seems reasonable.  I would be just as willing to accept the 
ruling of the benign dictators.

A switch often suggests inadequate reification (aka direct polymorphism or 
double dispatch might be in order), but I sometimes resort to a dictionary as a 
quick way to map numbers or strings to actions.  Since landing in Pharo, I have 
been using the modified stream protocol I developed in response to default 
actions, which I consider to be a disaster in the making.  Others are less 
worried about it.  It is fairly easy to have some code that one loads into an 
image.  I do it for streams, others can do it for case statements.

The above said, one thing I don't like is "you can't do that because I think 
its' ugly."  Perhaps a compromise for Stef to consider is to clean the uses of 
the method so it is not used in the image (effectively removing it), but leave 
it in place for those who want to use it their own code??

Bill


________________________________________
From: pharo-project-bounces at lists.gforge.inria.fr 
[pharo-project-bounces at lists.gforge.inria.fr] On Behalf Of Benoit St-Jean 
[bstjean at yahoo.com]
Sent: Sunday, February 13, 2011 9:43 AM
To: Pharo-project at lists.gforge.inria.fr
Subject: Re: [Pharo-project] could we agree to remove caseOf: and       
caseOf:otherwise:

Let's get to the point here...  Most people will tell you it's an awful "beast" 
that doesn't belong to the OO and Smalltalk world.  If I *love* case statements 
and I absolutely need them, I can code in C.  If I *love* case statements and I 
absolutely need them, nothing prevents me from adding them to the image as my 
own-superoptimized extension.  You'll always find something, someone, somewhere 
who could argue about the need for such a thing but in reality, I guess this 
method has always bugged most Smalltalkers...  It's ugly, not OO, not good style 
and good practice, not essential and not needed by 99% of the people here (and 
if it's sooooooooooo needed, how do you explain that all other Smalltalk vendors 
haven't implement it as part of their core libraries ?).

So let's vote (you won't argue against democracy, won't you?!) for the removal 
of #caseOf:otherwise: and let's move forward onto more important business.

On a less serious note, let's all remember what Spock said:

"Were I to invoke logic, however, logic clearly dictates that the needs of the 
many outweigh the needs of the few"

Let's remove this thing!

+1

P.S.  Performance-wise, if you always need "optimized" code, you can always rely 
on primitives & plugins...  Let's not go performance-frenzy here!  We don't want 
to end up in an environment where all the code is unreadable...  Clarity & 
simplicity are good, not evil in Smalltalk!

-----------------
Benoit St-Jean
Yahoo! Messenger: bstjean
A standpoint is an intellectual horizon of radius zero.
(Albert Einstein)


________________________________
From: Levente Uzonyi <leves at elte.hu>
To: Pharo-project at lists.gforge.inria.fr
Sent: Sun, February 13, 2011 8:50:53 AM
Subject: Re: [Pharo-project] could we agree to remove caseOf: and 
caseOf:otherwise:

On Sun, 13 Feb 2011, Sven Van Caekenberghe wrote:

>
> On 12 Feb 2011, at 18:41, Levente Uzonyi wrote:
>
>> ~27x slowdown in this case.
>
> I personally never heard of #caseOf:otherwise !
>
> It feels like a hack that is not often needed.

You don't need it often, but it's sometimes useful.

>
> If after writing correct code you need to optimize integer/byte handling, there 
>are many solutions, check any book on algorithms, most of them are using table 
>dispatch.

The blocks of #caseOf: are not just boilerplate code, you can evaluate
any expression there. It's cumbersome to do that with table based
dispatch.

>
> Another problem in your benchmark is that you keep the creation of the dynamic 
>array inside the code to measure, while in the compiler primitive case it is of 
>course compiled away, that alone makes a huge difference:

It's not a problem, it's intentional. See the mail that I replied to.


Levente

>
> (timings on my machine)
>
> [ 1 to: 10 do: [ :each |
>     each
>         caseOf: {
>             [ 1 ] -> [ $a ].
>             [ 2 ] -> [ $b ].
>             [ 3 ] -> [ $c ].
>             [ 4 ] -> [ $d ].
>             [ 5 ] -> [ $e ] }
>         otherwise: [ $x ] ] ] bench.
> '8,920,000 per second.'
>
> [ 1 to: 10 do: [ :each |
>     ({
>         [ 1 ] -> [ $a ].
>         [ 2 ] -> [ $b ].
>         [ 3 ] -> [ $c ].
>         [ 4 ] -> [ $d ].
>         [ 5 ] -> [ $e ] }
>             detect: [ :ea | ea key value = each ]
>             ifNone: [ [ $x ] ]) value ] ] bench.
> '70,600 per second.'
>
> | actions |
> actions := { [ $a ]. [ $b ]. [ $c ]. [ $d ]. [ $e ]. [ $x ]. [ $x ]. [ $x ]. [ 
>$x ]. [ $x ]. }.
> [ 1 to: 10 do: [ :each |
>     (actions at: each) value ] ] bench.
> '3,230,000 per second.'
>
> | letters |
> letters := 'abcdexxxxx'.
> [ 1 to: 10 do: [ :each |
>     letters at: each ] ] bench.
> '8,930,000 per second.'
>
> If other Smalltalks can live without it, so can we.
>
> Sven
>
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.gforge.inria.fr/pipermail/pharo-project/attachments/20110213/65736686/attachment.htm>


More information about the Pharo-project mailing list