-1 on the whole proposal.
Currently when I see an f-string such as
f"My name is {name} and my age is {age}."
I can easily translate it mentally (if I have to - usually I don't)
into
"My name is " + str(name) + " and my age is " + str(age) + "."
Whether such a translation is technically accurate or not is
irrelevant - the point is that, modulo technical niceties, f-strings
are translated by simple, easily understood and unambiguous
rules into an expression with easily understood semantics.
Whereas this proposal
- Is a really obscure and non-obvious way of
assigning to variables. I doubt that anybody could readily guess
the meaning when seeing it for the first time. (Frankly, I don't
care if something similar has been implemented in Scala - I still
think it's horrible for Python.)
- Would add to the interpreter the bloat of a whole parsing
engine whose working would be a totally obscure
"black box" (and I suspect would be hard to implement correctly the
first time).
- Would require a lot of work to implement and maintain
(including maintaining the docs) a feature which might not be used
much. (IMO no convincing use cases have been presented so far. No
doubt there are some. Just IMO not enough to justify the
proposal.) Even providing reasonably helpful error messages could
be quite a lot of work (a blanket ValueError, e.g., would move it
towards the "unusable" end of the spectrum).
- Is subject to greedy/non-greedy parsing ambiguities.
Whatever the choice(s) made, the results will be surprising to some
of the people some of the time. And trying to resolve them would
surely slow down the parsing process.
- The behaviour of said "black box" parsing engine could
not be changed in any way by users if it wasn't exactly
what they wanted, which I suspect would happen quite often, and not
just because of the greedy/non-greedy issue. This is my gut feeling
- I can't articulate it concretely except to mention an issue that
Chris Angelico raised: is partial assignment (i.e. assignment to
some but not all of the target variables) supported, or not?
Whereas users are free to tweak parse.py or write their own custom
parser. I visualise a lot of Stack Overflow questions on the lines
of "Why doesn't this [f-string assignment] do what I want?" In fact
for this reason (impossibility of finding a spec which will suit
everyone) I am opposed to building parsing into the Python language,
e.g. with a "parse" keyword. A built-in parse() function would not
be so bad, though I'd be dubious about it. But having parsing snuck
in by, and only accessible by, assignment to f-strings, with
no way of users changing it, strikes me as the worst of all
possible worst worlds.
- As others have mentioned: could inject variables into locals()
making debugging harder.
- There is no precedent in Python for an expression on the LHS
of an assignment. (Tuple unpacking, dotted names, slices,
dictionary keys etc. might or might not be considered
counter-examples but at least their intent is clear.) Certainly not
for something which looks like a literal on the LHS of an
assignment.
(As another reference point: Contrast PEP 622, Pattern Matching
(whatever flavour of it we end up with). It's on record that I'm
not its biggest fan, but I posit that (a) a "match" construct is easy
to understand when seen for the first time, at least in
general intent (b) a "match" construct is translatable to ordinary
code containing equality tests, isinstance tests, etc. in a simple,
easily understood and unambiguous - if tedious -
way.)
In short, "assigning" to f-strings is not and cannot be a simple
reversal of having them in expressions. Rather, it is opening a
big can of worms.
Best wishes
Rob Cliffe