Yet Another Switch-Case Syntax Proposal

Ian Kelly ian.g.kelly at gmail.com
Fri Apr 4 13:55:11 EDT 2014


On Fri, Apr 4, 2014 at 10:44 AM, Marko Rauhamaa <marko at pacujo.net> wrote:
> Consider:
>
>     switch local_sabbath():        # bad
>     case (1, 2, 3) as sabbath:
>         ...

I'm not overly fond of that either.  That's why I liked the OP's
choice to put the first case in the switch statement.

> Now Python "framing" requires that you place something between the first
> ":" and "case":
>
>     switch local_sabbath():        # bad
>         pass
>     case (1, 2, 3) as sabbath:
>         ...

That's absurd.  Granted that omitting the pass doesn't match any
existing syntax, but that doesn't mean it *must* be done that way.

> Placing the expression after the colon terminates the first colon
> cleanly. Also, the "lambda" precedent allows an expression to follow a
> colon; both "lambda" and my "switch" mandate that the expression stay on
> the same line with the colon.

But in the case of the lambda *expression*, the following expression
is effectively the entire "suite" of the lambda "clause", mirroring
the form of a def statement.  If "local_sabbath()" is treated as the
suite of the switch *statement*, then "Python framing" tells us the
same construct could be written like this:

switch:
    local_sabbath()
case 1:
    ...

And if that's allowed, then why not this?

switch:
    if username == "ozzy":
        black_sabbath()
    else:
        local_sabbath()
case 1:
    ...

Or:

switch:
    for sabbath in list_of_sabbaths:
        sabbath
case 1:
    ...

Or even:

switch:
    pass
case 1:
    ...

The intent of the first two are fairly clear, but they're way out of
scope for a switch statement.  I don't even intuitively know what to
do with the last two.  The point here is that the switch expression
really ought to be a single expression contained in the switch header,
not a suite.


>> Second, "as" clauses are used in other contexts for local assignment.
>> What is the purpose of doing that here? How does this solve the
>> problem of explicitly denoting case multiplicity?
>
> The "as" clause follows the precedent of the "try/except" statement. It
> removes the occasional annoyance in C:
>
>    switch (next_char()) {
>    case '\n':
>    case '\r':
>        putchar(???);
>         :   :   :
>
> which forces you to introduce a temporary variable:

How is the target identifier of the "as" not a temporary variable?
Try/except statements and with statements use "as" keywords to capture
values that may not otherwise be available in scope for assignment.
Except assigns the exception instance that was just caught, and with
assigns whatever arbitrary object was returned by the context
manager's __enter__ method.  With switch there is no need for that;
just do this:

char = next_char()
switch next_char:
case in '\n\r':
    print(char)

Similarly there is no need for the "if" or "while" statements to
support an "as" keyword, as in:

while next_char() as char:
    print(char)

There are good reasons why the language generally does not allow
assignments in non-assignment statements, which is what your "as" is
trying to do.  The Pythonic way to write that loop is:

while True:
    char = next_char()
    if not char: break
    print(char)

Which is at least as ungraceful as assigning the switch variable
before the switch statement.



More information about the Python-list mailing list