On Tue, Oct 20, 2020 at 01:41:02PM +0200, Thomas Wouters wrote:
a, *?, b = expression print(?) # wait this doesn't work;
I'm not sure how this is different than, say,
a, _, _ = range(3) print(_)
For starters, that will actually print something, not fail with a SyntaxError or runtime exception.
You are correct that if I use the same `_` variable in multiple places:
a, _, _, b, _ = something
and then need to see the "ignore" values for debugging, I can't. I will only see the value in the final `_` unless I rename them.
But with your proposal, I can't even see a *single* `?` (non-)target. So that's even more inconvenient than `_` because it affects more cases.
- `_` is inconvenient for debugging if you have two or more in one assignment statement;
- `?` is inconvenient for debugging if you have two or more in one assignment statement; - PLUS if you have only a single one in the statement.
So strictly more inconvenient.
Each time I use a `?` target, I expect that eventually I will need to debug that piece of code. When I need to debug it, I will need to change the `?` into a real variable. I don't plan to change it back: why churn the code unnecessarily? So there's this ratchett effect, where over time every `?` I use will eventually be converted into a real variable. So why not just use real variables in the first place?
Unless there is a seriously large performance gain from `?` I wouldn't bother using it in the first place.
I don't hate the idea, but I don't think it's very useful either.
That is to say, some things are impossible; if you want to print the value, don't assign to '?'.
Indeed, but the problem is that when I name the variable *today*, I might not know that *tomorrow* I will need to see its value.
In my opinion, having a convention to treat certain variables as "unused" is great (I'm partial to `__` myself, to avoid clobbering the special variable `_` in the REPL). But having that be a pseudo-variable which is *actually* unused and unuseable strikes me as being an attractive nuisance.
And yet that's exactly what is being proposed in pattern matching. https://www.python.org/dev/peps/pep-0634/#id3
"A wildcard pattern always succeeds. It binds no name."
That says nothing about variables. It defines a *pattern* which always matches anything. Patterns are a different kind of thing to variables, just as keywords are not variables.
A better argument for your position woud be this quote from a different PEP, 635:
"The wildcard pattern is a special case of a 'capture' pattern: it accepts any value, but does not bind it to a variable."
But I think that description makes a conceptual error. I think it is a mistake to think of the wildcard pattern as a non-binding capture pattern, since that's a contradiction: if it never captures any value, how can it be a capture pattern?
I think that it is important to recognise that the wildcard pattern is *distinct* from capture patterns, literal patterns etc. Like literal patterns, it captures nothing. Unlike literal and other patterns, it matches everything. There's a certainly similarity to capture patterns
No, that's not "exactly what is being proposed". The *pattern* "_" is not an assignment target. Capture patterns are similar to assigment targets, but patterns in general are not:
does not attempt to use  as an assignment target. Likewise for value patterns such as `case HttpStatus.OK`. Value patterns like HttpStatus.OK are perfectly legal assignment targets, but that's not what they mean inside a case statement.
Symbols having multiple meanings are not so unusual:
- inside a float, a . is part of the float; - outside of a float, a . is an attribute delimiter;
- the chars 'None' have special meaning on their own; - but otherwise inside an identifier, or a string, they're just letters;
- round brackets (parentheses) can mean grouping or calling; - square brackets create lists, or subscripting;
etc. Why are we so hung up over the fact that inside a case statement, the underscore means something different from outside of a match statement? It seems like a very minor issue to worry about.
If we can accept that `None` and other keywords are syntactically legal identifiers, but not actually usable as identifiers as they are reserved for other purposes, then we ought to be able to accept that `_` is syntactically a legal assignment target, but not usable as a capture pattern as it is reserved for another purpose (wildcard pattern).