Open gvanrossum opened 4 years ago
At first I was going to write a post saying that I didn't care one way or another (which seems like a waste of space, except to point out that there are valid arguments either way, and they are all aesthetic or pedagogical in nature), however I'm starting to lean towards favoring 'as'.
My reasoning is this: in the one-off form (which I support), match A as B:
reads more naturally than match A case B:
. And the full match statement should be consistent with the one-off form.
Also: reserved word frugality :)
That makes sense, as far as it goes.
I do observe that for people proposing random new bits of syntax, as
is just about the most commonly proposed keyword. It's been proposed for argument types (instead of :
), return types (instead of ->
), the walrus (f() as a
instead of a := f()
).
Also, the the three existing uses (import ... as x
, with ... as x
, except ... as x
) all assign something to x
, whereas here... Oh, wait! At least the simplest form, as x:
actually does that too. But as Point(x, y)
is still a bit of a stretch.
Well, in Python the keyword as
traditionally functions as a way to make a statement act like an expression; I suspect that the various random pieces of syntax being suggested are trying to leverage that concept.
However, the keyword as
means something different in C#: it's a type cast. a as Type
is equivalent to the C++ cast operator (with runtime type checking). The use of as
in the proposed match statement seems somewhat closer to this meaning.
In English, the word 'as' has multiple definitions, but I suspect the one most relevant is the prepositional one, meaning "used to refer to the function or character that someone or something has".
If I were not constrained by Python syntax and tradition, I wouldn't use a keyword at all, I'd use an operator: pattern => body
or some such. However, to be consistent with other Python statements a colon has to introduce the suite. (Putting an operator in prefix position, in place of the as
, for example => pattern: body
, doesn't look great to me but YMMV.)
Technically you don't need a keyword at all: pattern: body
is unambiguous enough in the context of match statement body. However, I don't recommend this approach either - while your PEG parser may not have a problem with it, the average reader needs a bit more syntactical clues to be able to flash-recognize a statement pattern.
I imagine that whatever syntax gets chosen, VSCode will have a very lovely syntax coloring for it.
In any case, I don't have a strong opinion about this, I'll let others weigh in.
Well, in Python the keyword ‘as’ traditionally functions as a way to make a statement act like an expression;
Huh?
Sorry if I wasn't clear. As you point out, 'as' is typically used to assign to some variable. (Although import binds to a variable in either case, 'as' just changes the name of it). And when I say 'like an expression' I mean that the statement produces an output value, as opposed to merely changing control flow or having side effects, which would be the case for 'with' without the 'as' clause for example.
I guess what I am trying to say is that I agree with your characterization of the usage of the word 'as' in existing syntax, and I suspect that people who want to use 'as' in new syntax are using it in a similar way.
as
and case
convey two different ways of looking at pattern matching, quite like @viridia's comment on the one-off form already indicates.
In ML languages, it is completely natural to write things like
let Point(x, y) = p in ...
to assign p
's fields to the variables x
and y
, respectively. Pattern matching is then an extension with the possibility to choose the most appropriate assignment out of many. In this context, as
makes perfect sense.
More on the ALGOL side (i.e. C, Pascal, etc.), there is no such assignment and the primary focus is on choosing an alternative. Naturally, case
is the favoured keyword there.
I still maintain that most users of Python's pattern matching will come from the ALGOL side, and despite all our nice observations how we could replace isinstance
-checks with pattern matching, the great public will probably welcome it as a "switch on steroids" and primarily replace if
-elif
-chains by the new pattern matching.
The one argument that really speaks in favour of as
is not having to introduce a new keyword. But since case
as keyword really appears in very well defined, selected places, this might less of an issue than we think.
Hence, I would favour case
, but I am open to as
as well. And I actually do not see a problem in combing using case
for general patterns and as
in the one-off case. It might even be an advantage to use different keywords there.
Python (like me) comes definitely from the Algol side (-60 and -68).
Once we have the machinery for a context keyword, 'match', adding 'case' is trivial.
It is interesting that I see choice aspect more important than assignment aspect (as I mentioned in other issue), yet as
still sounds better to me. Maybe this is personal, since I read it like "if I can match ... as ...". But if you are sure that using case
will highlight the importance of choice aspect, I am fine with case
.
I feel the same way. If it were me, I would choose 'as', but I don't think the choice matters all that much.
I am strongly in favor of tradition -- case
has a venerable history, from C switch
to Scala match
. Using as
sounds a bit like a syntax hack (of which Python has plenty). But ultimate it's just bikeshedding.
For the sake of completeness (i.e. being pedantic), I'll lay out all the other options besides 'as' and 'case' even though I am not seriously proposing them:
1) Pick a different English preposition, here's a list: https://dictionary.cambridge.org/us/grammar/british-grammar/prepositions
So for example 'match to', 'match on', 'match when', etc.
2) Use an operator rather than a keyword:
match target:
=> Point(x, y):
...
=> Rectangle(x0, y0, x1, y1):
...
3) Use nothing:
match target:
Point(x, y):
...
Rectangle(x0, y0, x1, y1):
...
We decided to go with case
. The PEP needs updating.
The PEP has been updated, let's relabel this.
We've been using
case
, like this:@ilevkivskyi proposes
as
, like this:Let's decide.