# Another stab at a "switch/case" construct (for Python 3000):

damien morton morton at dennisinter.com
Thu Mar 28 20:37:14 CET 2002

```You could go a lot further with this case statement

First thing is to allow for variable length list unpack:

(a, b, *c) = (1,2,3,4,5,6,7)
a <- 1
b <- 2
c <- (3,4,5,6,7)

Second thing is to allow non-binding literals in a list unpack:

(1, a, b) = (1, 2, 3)  matches/unpacks with a=2, b=3
(1, a, b) = (2, 3, 4)  fails
('fred', a, b) = ('fred', 'was', 'here') matches/unpacks with a='was',b='here'
('fred', a, b) = ('joe', 'was', 'here') fails

Then, introduce a simple case statement:

case var:
20:
print 'var is 20'
30:
print 'var is 30'
else:
print 'we have fallen though'

A slightly more complex case statement:

case:
if var < 20:
print 'var is < 20'
if var = 25:
print 'var is 25'
if var > 30:
print 'var is > 30'
else:
print 'we have fallen though'

An even more complex case statement:

case someobject:
(X, Y):
print 'macthes any list/tuple of length 2'
print X, Y
(X, Y, *Z) if X<32 and Y=="abc" and len(Z)>4:
print 'would match (1,"abc",3,4,5,6,7)
print 'X <- 1'
print 'Y <- "abc"'
print 'Z <- (3,4,5,6,7)'
print X, Y, Z
(X, Y, *Z):
print 'matches any list/tuple of length 3 or more'
print X, Y, Z
X if isinstance(X, file):
print 'matches any file object'
print X
else:
print 'final condition matches anything'

translated into current python:

(assuming that variable list unpack is included in the python core)

try:
(X, Y) = someobject
except ValueError:
try:
(X, Y, *Z) = someobject
except ValueError:
X = someobject
if isinstance(X, file):
print 'matches any file object'
print X
else:
print 'final condition matches anything'
else:
if X<32 and Y=="abc" and len(Z)>4:
print 'would match (1,"abc",3,4,5,6,7)
print 'X <- 1'
print 'Y <- "abc"'
print 'Z <- (3,4,5,6,7)'
print X, Y, Z
else:
print 'matches any list/tuple of length 3 or more'
print X, Y, Z
else:
print 'macthes any list/tuple of length 2'
print X, Y

"Ken Peek" <Ken.Peek at SpiritSongDesigns.comNOSPAM> wrote in message news:<3ca33c88 at news.mhogaming.com>...
> Well-- OK, my new ISP doesn't have a news server, but I found one
> that I could use to post this with.  If you reply to my email, do
> the 'nospam' thing first to my email address...
>
> looked at all the other c.l.py posts on this construct, but I
> don't think anyone proposed this format.
>
> BTW-- the 'until' thing in the original letter was already posted,
> so please disregard that part of this post- (I left it in for
> accuracy.)
>
>   -----Original Message-----
>   From: Guido van Rossum
>   Sent: Thursday, March 28, 2002 04:45
>   To: Ken.Peek at SpiritSongDesigns.NOSPAM.com
>   Cc: Marc-Andre Lemburg
>   Subject: Re: PEP 0275
>
>   If you really want to discuss this, it's better to post to c.l.py.
>
>
>   -----Original Message-----
>   From: Ken Peek [mailto:Ken.Peek at SpiritSongDesigns.NOSPAM.com]
>   Sent: Thursday, March 28, 2002 01:05
>   To: Marc-Andre Lemburg
>   Cc: Guido van Rossum
>   Subject: PEP 0275
>
>
>   match some_object:
>
>       ("I dream of Jeanie",):
>           print "with the light brown hair"
>
>       (1,3,5,7):
>
>           print "some odd numbers"
>
>           # 'break' leaves the entire match structure
>           if (time_to_leave): break
>
>           # 'continue' jumps to the first
>           # statement in the next clause
>           continue
>
>       (123,456,789):
>
>           print "some bigger numbers too"
>
>       (19,56,22):
>
>           print "some random numbers"
>
>       (1001,2002,3000):
>           # YES! It IS possible we want to do NOTHING!
>           pass
>
>       any:
>           print "we got here because there were no matches"
>
>   This is kind of a neat construct because you can put multiple
>   tests on one line, and it doesn't look too messy (like C's
>   'switch' would look.)  Also-- we are not limited to matching up
>   only integers.  This is very clean code compared to a long string
>   of "if/elif/elif/elif/else" clauses...  I like READABLE code--
>   which is why I like Python!
>
>   Note that the aggregate of the tuples must have unique values and
>   types-- (this allows for efficient implementation, and for future
>   optimization.)  A match is found only when BOTH the type and
>   value are the same.  'some_object' can be any object, but it
>   would be wise to not use floating point numbers or other things
>   that do not guarantee a valid '==' compare.  I suppose these
>   ambiguous types could be flagged with an error from the compiler,
>   but I would hate to see a run time check (which would slow things
>   down, just to accommodate a bad programmer.)
>
>   The match clauses do not 'fall through' automatically like a "C -
>   switch" statement-- (this is the source of many errors in 'C'.)
>   A clause can be forced to 'fall through' with the use of a
>   'continue' statement, which jumps to the first statement in the
>   next match clause (because 'falling through' IS useful
>   sometimes.)  I suppose the interpreter/compiler could flag an
>   error "UnreachableCode" (or 'BadIndentation') if 'continue' was
>   used by itself, and there were statements after it at the same
>   indentation level...
>
>   The 'any' keyword could be changed to 'else' I suppose, but I
>   think the word 'any' "just plain sounds better when you say it",
>   and I like the 'match' keyword better than anything I have seen
>   or can think of...
>
>   =================================
>
>   I have also been mulling over a new 'until' keyword-- it works
>   the same as 'while', but the body of the loop is executed first
>   before the conditional test is made the first time, and the sense
>   of the test is opposite (ie- the test must be FALSE for the body
>   of the loop to be executed again.)  'continue' jumps directly to
>   the conditional test, and 'break' jumps out of the loop (as expected):
>
>   until something_becomes_true:
>
>       print 'here we are in the body of the loop'
>       print 'which was executed at least once'
>       print "before the 'something_becomes_true'"
>
>       # we can skip to the test now with a 'continue':
>       if bad_programming_practice == TRUE: continue
>       print 'nope-- no continue'
>
>       # we can get out of the loop with a 'break':
>
>       # we probably need to stop the loop someday:
>       something_becomes_true = do_some_check()
>
>   =================================
>
>   I doubt if any of this will ever make it into Python (well--
>   maybe Python 3000)-- but it's fun to think about.
>
>   Well, what do you think?
>
>   --Ken Peek
>   Ken.Peek at SpiritSongDesigns.NOSPAM.com
>   (This letter is released to the public domain-- KP.)

```