[Python-ideas] Yet Another Switch-Case Syntax Proposal

Andrew Barnert abarnert at yahoo.com
Sat Apr 19 06:54:56 CEST 2014


On Apr 18, 2014, at 16:08, "Lucas Malor" <7vsfeu4pxg at snkmail.com> wrote:
> 
> On 18 April 2014 18:51, Andrew Barnert abarnert-at-yahoo.com |python-ideas-at-python.org| <3en9kh2cbt at sneakemail.com> wrote:
>> No it isn't. First, the "for ... in" keywords are not the same as just "for" and a bunch of parens and semicolons.
> 
> My propose has elcase, that is not present in other languages.

I can't understand why you're still not getting it, but I'll try again.

Most languages' case statements are of the form "case ... in ...", sometimes substituting "of" or punctuation in place of "in". C and its derivatives instead use "switch ... case ...". By using the unique C syntax (or a minor variation on it, which won't even be visible in any statement without an elcase) without the C semantics, you're creating a misleading parallel, and for no benefit that I can see.

>> Also, notice that if you try to read the switch statement, or your Python version, as English, it's nonsense.
> 
> Yes, the fact a case will behave differently for tuples and non-tuples will be difficult to translate in English.

No, that's not at the point. Consider:

    for ch in mystring:
        process(ch)

You can read the first one aloud and it sounds like an English sentence. Maybe a slightly stilted sentence, the kind of thing you'd hear from a mathematician speaking technically or someone speaking English as a foreign language, but clearly recognizable and understandable to anyone who understands English. And this generally works for all statements in Python.

The same is not at all true with the C equivalent:

    for (pch=mystring; *pch; ++pch)
        process(*pch)

No matter how you try to pronounce the punctuation, the result is not English, it's gibberish. C is not meant to be readable as English (or as "executable pseudocode", if you prefer).

Now try this with switch:

    switch mystring case "spam":
        process(thingy)

That is not even remotely interpretable as an English sentence. That's not a problem for C, but it is for Python.

>> Bash doesn't have separate "case" and "elcase" cases. After one case is done, the rest are skipped, just as in most other languages.
> 
> But it has ;& and ;;& similarly to break and continue of C, that it's equivalent to case and  elcase of my proposal.

First, break and continue are not even remotely equivalent of your case and elcase. A break means you skip over all subsequent cases; no break means you fall through to the next case; continue is a syntax error (unless of course the switch is inside a loop, in which case it's the loop that's continued); and there is no way short of abusing goto to skip over some cases but not others.

Second, bash does not have either ";;&" or ";&". It requires every case clause to end in ";;", which always skips over the rest of the cases. A ";" just separates statements within a clause. In some versions of bash, ";&" is interpreted basically the same as "&"--that is, it both ends a statement and makes a background job out of it--while in others (including all recent versions) it's a syntax error, as is ";;&". There is no way to either fall through to the next clause or skip some clauses but not others.

>> I don't see how skipping over any elcase but falling through to the next case is in any way simpler than C.
> 
> Well, because it's coherent with if-elif. See my last example in my first message.

No it isn't. An elif clause is embedded in an if statement; there is no if clause you can embed on an if statement, just an entirely new and unrelated if statement. 

>> Well, then at least look at the limited form of pattern matching Python has in the for and assignment statements and parameter matching, and maybe look at how pattern matching is used with case statements in other languages; don't try to suggest language designs based on guesses.
> 
> Excuse me? I know list comprehensions, lambdas and argument unpacking.

Who asked you about list comprehensions or lambdas? What do you think they have to do with anything? Can you give an example that shows how they're relevant?

> And I do not think you can see what I do before I post a message.

No, all I can see is what you say. But you said that you don't know much about pattern matching, so I think it's fair to assume you don't know much about pattern matching.

And I think that also makes it fair to assume you didn't try to learn about it, because the only alternative is that you tried and were incapable, which I think would be very insulting, and I prefer not to assume that of people.

> About pattern matching in the for statement, I really don't know what they are.

OK, first let's look at something you can do with a case statement in a language like ML or Haskell, translated into more Python-like syntax:

    case spam:
        of (x, y):
            process(x, y)

This case will match only if spam is a tuple of exactly two values, and will bind x and y to those values.

Obviously that syntax conflicts with your syntax for matching two distinct cases with the same clause, but ignore that for a moment. If there were suitable syntax for both, would you want that in Python?

Compare this perfectly valid Python code:

    if value == x, y:
        process(x, y)

    x, y = value
    process(x, y)

    for x, y in pairs_of_values:
        process(x, y)

Here, each element in pairs_of_values has to be an iterable (not necessarily a tuple) of exactly two values, and x and y are bound to the two values. That's very close to what's happening in the ML-style case statement (and the difference--the fact that it takes any iterable instead of a tuple--is probably what you'd expect from Python duck typing vs. ML static typing).

Meanwhile, ML and friends let you go farther, matching by partial values:

    of (True, y):
        process(y)
    of Eggs(z):
        fry(z)

The first matches only if it's a tuple of exactly two values and the first is equal to True, binding y to the second; the second matches only if it's equal to an Eggs instance constructed with exactly one argument, and binds z to that argument.

Clearly not all of this fits into Python. (The last example isn't even conceptually possible, given the way object initialization works.) But it's worth considering what does and what doesn't fit rather than trying to design a feature without even knowing what the options are.

>> ... and? Are you suggesting that if the switch expression is a string and the case expression a compiled regex you could automatically call match instead of testing for equality? If not, how is having regexp even relevant here? And how are recursive functions relevant?
> 
> I'm suggesting to use if-elif with re module, if you want to use regular expression, and to use recursive functions if you want... recursive functions.

I have no idea why you think recursive functions are relevant to anything being discussed here. Maybe if you can give and example of what you mean?

> To be more clear, IMHO switch-case is useful if it's simple.
> 
> 
>> A generator expression is equal to anything except itself, and doesn't contain anything.
> 
> You can convert it to an iterable. Probably an overkill, but you can do it. 

A generator expression is already an iterable; no conversion is necessary.

But your proposal was to treat tuples specially and match all other iterables as single values, which means that a generator expression would be matched as a single value, meaning it would only match itself. 

And again, I don't understand what the relevance is supposed to be.

>> I don't know what you mean by "symbolic pattern" here.
> 
> For what I know (not too much), in Mathematica pattern matching can be used for symbols, and symbols can be used as identifiers:
> https://reference.wolfram.com/mathematica/guide/Patterns.html

You're mixing up different terms here. Symbolic patterns in Mathematica match symbolic structures, not identifiers. The idea is to provide ML-style structural pattern matching, in a way that looks like intuitive "fill-in-the-blanks" in the simplest cases, but is then extended in a way that's similar to regular expressions, but more verbose and readable whenever regexps become too obtuse. Mathematica uses these patterns in all kinds of places beyond what Python and ML do, and it's a pretty cool feature, but I think you want to look at some examples instead of trying to get the idea from the formal reference docs.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140418/4e3161b6/attachment-0001.html>


More information about the Python-ideas mailing list