The Cost of Dynamism (was Re: Pyhon 2.x or 3.x, which is faster?)

Steven D'Aprano steve at pearwood.info
Mon Mar 14 21:55:30 EDT 2016


On Tue, 15 Mar 2016 04:53 am, BartC wrote:

> On 14/03/2016 17:17, Mark Lawrence wrote:
>> On 13/03/2016 20:12, Marko Rauhamaa wrote:
>>> BartC <bc at freeuk.com>:
>>>
>>>> Exactly why having ready-made solutions is preferable to everyone
>>>> hacking their own solutions to switch.
>>>
>>> A developer friend of mine once said insightfully that the point of OO
>>> is getting rid of switch statements. IOW, most use cases for switch
>>> statements are handled with virtual functions.
>>>
>>> The most significant exception in my experience is message decoding,
>>> where switches/ifs cannot be avoided.
> 
>> http://c2.com/cgi/wiki?SwitchStatementsSmell
> 
> I get it. The author doesn't like switch statements!


I don't think you do -- there's no "the author". It's a wiki. There's
potentially *thousands* of "authors". The page you (might have) read is a
discussion between many different people, debating the pros and cons of
switches.

Also, the person quoted in the first paragraph is not just any author, but
Martin Fowler, one of the acknowledged authorities on object oriented
programming, refactoring, agile methodology and others:

https://en.wikipedia.org/wiki/Martin_Fowler

So he is worth listening to, even if you end up disagreeing.


> But they can be a succinct and convenient way of expressing some code
> patterns. Nobody is obliged to use them, but it would nice for a
> language to give the /choice/. And since they mainly involve syntax, the
> cost of providing them is small.

One of the problems with switch statements is that they are *anything but*
succinct. Compare this:

> switch X
> when A,B   then S1
> when C     then S2
> when D,E,F then S3
> else            S4
> end switch

to the object-oriented solution, using polymorphism:

X.foo()


where foo returns S1, S2, ... S4 as appropriate, according to the type of X.

Six lines versus one expression. Which did you say was succinct again?
*wink*


In any case (pun intended), there have been two proposals to introduce a
switch/case statement to Python, including one by Guido himself.


https://www.python.org/dev/peps/pep-3103/

https://www.python.org/dev/peps/pep-0275/



> The typical characteristics - when A to F are known at compile-time - are:
> 
> * X is only evaluated once

That's easy to emulate with a temporary variable.


> * None of A to F need to be evaluated
> * Only a single test is needed, no matter how many case expressions

How does the compiler know which case matches from a single test?

I think that you might be assuming that the switch statement uses a jump
table. In your case, since you wrote the language, you might be right, but
that's certainly not the case in general. In general, switch statements are
implemented as either a chain of if...else or as a jump table, or possibly
as a hybrid of the two.

http://embeddedgurus.com/stack-overflow/2010/04/efficient-c-tip-12-be-wary-of-switch-statements/


Consider:

switch n:
    case 0, 1, 2: 
        print "Small"
    case 705210841296510943:
        print "You found the magic number!"
    case 18446744073709551610...18446744073709551615:
        print "Big"
    default:
        print "Middling".

I'd like to see the jump table you use for that :-)


But of course, in Python any switch statement would have to support values
of any and every type, not just integers. So any implementation you are
thinking of would have to support cases like this:


switch obj:
    case "Hello", None: ...
    case [1, 2, 3]: ...
    case 23.01, 15+2j, Fraction(10, 11): ...
    case 100**100, {}: ...


and more. This is not negotiable: having a switch statement limited to small
ints is simply not an option.



> * Only one of S1 to S4 is executed (at most one when there is no else)
> 
> (When A to F are not known at compile time, then it might be implemented
> differently. X is still evaluated once, but A to F are evaluated and
> tested in sequence until a match or not is found. However, nothing need
> change in the source.)



This syntax I find interesting, although it is rather limited in that you
can only switch on integers:

> Here's another pattern, which can also be implemented with an underlying
> switch:
> 
>   X = (N |A, B, C, ... |Z)
> 
> This selects the N'th value from A, B, C (in Python, probably 0-based).
> Z is the default if N is out of range. A, B, C can be any expressions.
> 
> The main characteristic is that only *one* of A, B, C  or Z evaluated,
> which is the difference between just using a list.

Are there any well-known languages which support this or similar syntax?

Of course, the syntax won't work in Python, because ( ... ) is already used
for tuples, and N|A would be ambiguous with bitwise-or. The closest we have
in Python would be:

x = {A, B, C][n]

or with a default:

x = {0: A, 1: B, 2: C}.get(n, Z)



-- 
Steven




More information about the Python-list mailing list