PEP 308: an additional "select/case" survey option
Steven Cummings
cummingscs at netscape.net
Tue Mar 4 21:41:01 EST 2003
Will this syntax be pursued separately if it does not become the lead nomination for PEP308? I wouldn't mind seeing both this switch-case syntax in addition to what I've already selected in the PEP308 vote.
/S
"Clark C. Evans" <cce at clarkevans.com> wrote:
>After some encouragement by Raymond, I'd like to add one more
>item to the survey, if you like what follows perhaps you can
>even *change* your vote (Raymond?) to include:
>
> Q accept switch-case
> Z deny everything else!
>
>Dedication:
>
> To those who hate the terinary operator beacuse it isn't pythonic...
>
>Background:
>
> After looking over much of my Python source code, I found that
> where I thought I needed a terinary operator, I ended
> up taking one of two paths:
>
> if 0 == quantity: exit = 'no exit'
> elif 1 == quantity: exit = 'a door'
> else: exit = '%s doors' % quantity
>
> Or, the more concise mapping-idiom:
>
> exit = { 0: 'no exit',
> 1: 'a door' }.get(quantity,
> '%s doors' % quantity)
>
> The latter construct has two advantages over the if/else
> statement level solution:
>
> 1. It's clear that I'm making an assignment to exit;
> in effect the "exit =" isn't duplicated and this
> aids in authoring/maintenance/reading.
>
> 2. The ugly '== quantity' isn't duplicated for each line,
> once again improving maintenance.
>
>
> However, the mapping-idiom has three problems:
>
> 1. The conditional switch isn't exactly "obvious" here
> unless you're a Python vetran, this hurts in the
> maintenance arena; besides the 'else' case is ugly.
>
> 2. It doesn't short-circut cleanly, to do a short-circut
> you need to use lambda's... ick; further, it results in
> the construction of a mapping which may not really help
> out optimizations.
>
> 3. It really doesn't facilitate the use whitespace/indentation
> to re-inforce a visual representation of the program's
> structure.
>
>Philosophy:
>
> The whole rationale for this construct is to reduce data
> duplication (both the assignments and conditional tests)
> to increase maintenance.
>
> The goal is not to save on vertical screen realistate by
> enabling multi-line constructs to be "jumbled" into a
> single line. It seems that many people are asking for the
> terinary option for the latter.
>
> Instead, this proposal seeks to engage Python's unique approach
> to syntax by using whitespace to enhance the visual representation
> of the program's structure. Many Python converts are here exactly
> beacuse Python is very readable and thus maintainable. This proposal
> is here soley to re-enforce this "pythonic" approach to coding.
>
>Proposal:
>
> The proposal introduces a 'select' or 'switch' keyword which creates
> an indented expression block. Instead of the following,
>
> exit = { 0: 'no exit',
> 1: 'a door' }.get(quantity,
> '%s doors' % quantity)
>
> You could write,
>
> exit = select quantity
> case 0: 'no exit'
> case 1: 'a door'
> else: '%s doors' % quantity
>
> This proposal gives you the power of the mapping-idiom without
> the uglyness. It expresses the intent of the construct in a
> very human readable manner using whitespace smartly.
>
> While the above is "good", it assumes an equality operator. So
> that the structure is more generic, his proposal allows an optional
> operator (a function taking 2 or more value and returning a boolean)
> immediately following the 'case' label,
>
> z = 1.0 + select abs(z)
> case < .0001: 0
> case > .5: .5
> else: -sigma / (t + 1.0)
>
> Note that the examples given in the proposal are thus
> very easily expressed using this notion:
>
> data = select hasattr(s,'open')
> case true: s.readlines()
> else: s.split()
>
> z = 1.0 + select abs(z)
> case < .0001: 0
> else: z
>
> t = v[index] = select t
> case <= 0: t - 1.0
> else: -sigma / (t + 1.0)
>
> return select len(s)
> case < 10: linsort(s)
> else: qsort(s)
>
> The 'operator' need not be binary, one could, for example,
> provide a terinary operator, such as:
>
> def between(cmp,rhs,lhs): return cmp >= rhs and cmp <= lhs
>
> score = select die
> case 1: -2
> case 2: -1
> case between 3,4: 0
> case 5: +1
> case 6: +2
> else: raise "invalid die roll %d " % roll
>
>Summary:
>
> The proposal thus creates a flexible mechanism for avoiding
> the excessive duplication of assignment and equality fragments
> within a conditional assignment nest; it does so through a
> new expression structure which, like the rest of Python, uses
> indentation for structure.
>
> This proposal thus provides the pratical benefit of a terinary
> operator, while at the same time opening the door to a rich
> (and quite readable) conditional assignment mechanism.
>
> In particular, this proposal rejects the rationale for 'terinary'
> operator as a way to trade horizontal screen realestate for
> vertical space; as this rationale is in direct opposition to
> the fundamental principle of readability. And as such, the
> proposal explicitly does not include a way to include multiple
> case labels on the same line.
>
>Credits:
>
> Alex Martelli for validating the elimination of needless-duplication
> of code as the primary goal for the construct; and
>
> Carel Fellinger for presenting the idea of a plugable predicate/operator
>
> Raymond Hettinger for asking me to write this up more or less formally
>
>
>
>--
>http://mail.python.org/mailman/listinfo/python-list
>
--
Steven Cummings
Columbia, MO
Email: cummingscs at netscape.net
AIM: cummingscs
ICQ: 3330114
__________________________________________________________________
The NEW Netscape 7.0 browser is now available. Upgrade now! http://channels.netscape.com/ns/browsers/download.jsp
Get your own FREE, personal Netscape Mail account today at http://webmail.netscape.com/
More information about the Python-list
mailing list