On 2020-09-17 12:16, Alex Hall wrote:
On Thu, Sep 17, 2020 at 8:57 PM Brendan Barnwell <brenb...@brenbarn.net
<mailto:brenb...@brenbarn.net>> wrote:

    On 2020-09-16 21:52, Dennis Sweeney wrote:
     > TL;DR: I propose the following behavior:
     >
     >      >>> s = "She turned me into a newt."
     >      >>> f"She turned me into a {animal}." = s
     >      >>> animal
     >      'newt'
     >
     >      >>> f"A {animal}?" = s
     >      Traceback (most recent call last):
     >      File "<pyshell#2>", line 1, in <module>
     >              f"A {animal}?" = s
     >      ValueError: f-string assignment target does not match 'She
    turned me into a newt.'
     >
     >      >>> f"{hh:d}:{mm:d}:{ss:d}" = "11:59:59"
     >      >>> hh, mm, ss
     >      (11, 59, 59)

             I don't like this at all.  It looks like assigning to a
    literal, which
    is weird.


People keep saying this, but iterable unpacking looks like assigning to
a literal (a tuple or list literal) just as much.

Only if you keep using extremely simple template strings that don't contain anything except the variables you're assigning to. But this proposal allows the string to contain ANYTHING. The assignment targets may represent only a small part of it. For tuples and lists of assignment targets, the target list/tuple can't contain any extraneous material apart from the variables you're assigning to. There is no assign-to-a-tuple analogue of

f"My name is {name} and I am {age} years old" = "My name is Bob and I am 100 years old"

Also PEP 622 proposes something that looks like assignment to a function
call, albeit within a match/case statement.

That doesn't look like an assignment, because there's no equals sign. In any case, I'm not sure I support PEP 622 as it stands either, for similar reasons to why I don't support this current proposal.

It's natural to have symmetry between assignments and expression. For
another example, look at subscripting, i.e. `__getitem__` vs `__setitem__`.

    Also, it hides the assignment target within a string of
    potentially unbounded length and complexity, which makes it
    difficult to
    reason about code because it's hard to see when variables are being
    assigned to.


It's really not. A decent IDE should already be able to automatically
show you assignments and usages of a variable - PyCharm does with one
Ctrl+click. A syntax highlighter that can handle f-strings will make the
assignments obvious at a glance.

No, it won't, unless the target string is simple. Also, the assigned values won't be easily discernible in the right-hand string, because there are no delimiters there to mark them.

In any case, even if it were borderline possible with an IDE, it's still not useful or important enough to me to gum up an operation as basic as assignment. I'm fine with putting it into a function call or something like that, but not overloading the assignment statement in this way.

       It also introduces a whole host of questions about the
    details of the parsing (i.e., how does the greediness work if the
    pattern is something like "{one} {two} {three} {four}" and the
    string to
    be parsed is five or ten words).


This I agree with, another reason to go for putting regexes in the
f-strings like I suggested.

             I think a better approach for something like this would be
    a .parse()
    method of some sort on strings, sort of like the inverse of .format().
    It would parse a given string according to the format string and return
    a dict with the mappings (just as format can take a dict in and return
    the string with the substitutions made).  So it would be like:

      >>> pattern = "That {animal} is really {attribute}."
      >>> d = pattern.parse("That snake is really powerful.")
      >>> d['animal']
    'snake'
      >>> d['attribute']
    'powerful'


I think someone else just made the same proposal. But how does this
solve the greediness issue?

It doesn't, but that's the least important of my objections. What it does solve is it avoids adding new behavior to the assignment statement, and it avoids creating a way to inject local variables whose names and/or values are unclear in the statement where they're created.

             This wouldn't let you assign the results into local
    variables, but I
    think that's a good thing.  Creating local variables "programmatically"
    is not a good idea; it's better to use a dict.


How is

     f"{a} {b}" = "1 2"

creating local variables any more "programmatically" than

     a, b = "1 2".split()

? The variables are static and visible to the compiler.

As I mentioned above, your examples are unrealistically simple. If you know your string is like "1 2" and you want to assign to a, b, you do what you just showed: use split. But in the "Bob is 100 years old" example I gave, it is more programmatic, because there is matching going on which is extracting parts of the RHS string, and you have to carefully read both the LHS and the RHS to see which parts are extracted into which variable. And that is still a pretty simple example, with relatively short and unambiguous strings on both sides of the equals sign. As the string grows longer and more complicated, it only becomes more programmatic.

I think we may be arguing from different premises here, though, because I think the real issue is that for me the equals sign and local variable names are quite sacred objects. I'm not sure I would even support nested tuple and list assignments if they didn't exist and were proposed today. All of these forms of assignment that are being discussed are too complicated to put into the simple assignment statement to be used to create local variables. It's fine to have the parsing side of it going on, but there just isn't any reason, in my view, to have it be part of an assignment statement that creates local variables. Just have it be a function call that creates a dict.

--
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is no path, and leave a trail."
   --author unknown
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/OMFJXQLENIEFHHN45UYJH7OGTJG55R4F/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to