Add .= as a method return value assignment operator

Hi, When using Python, I find myself often using assignment operators, like 'a += 1' instead of 'a = a + 1', which saves me a lot of time and hassle Unfortunately, this doesn't apply to methods, thus we have to write code like this: text = "foo" text = text.replace("foo","bar") # "bar" I propose that we should add '.=' as a method return value assignment operator so we could write the code like this instead: text = "foo" text .= replace("foo","bar") # "bar" This looks cleaner, saves time and makes debugging easier Here are a few more examples: text = " foo " text .= strip() # "foo" text = "foo bar" text .= split(" ") # ['foo', 'bar'] text = b'foo' text .= decode("UTF-8") # "foo" foo = {1,2,3} bar = {2,3,4} foo .= difference(bar) # {1} Rebane

On Wed, Sep 26, 2018 at 9:14 PM Jasper Rebane <rebane2001@gmail.com> wrote:
All the other augmented operators are of the form: target #= value with some sort of valid assignment target, and any value at all on the right hand side. You can take the value and put it in a variable, you can replace it with a function returning that value, etc, etc, etc, as it is simply a value. There's no difference between "x += 123" and "y = 123; x += y". (Putting it another way: "x *= y + z" is not equivalent to "x = x * y + z", but to "x = x * (y + z)".) With your proposed ".=" operator, it's quite different: the RHS is textually concatenated with the LHS. This creates odd edge cases. For example: items = ["foo", "bar", "quux"] items[randrange(3)] .= upper() Is this equivalent to: items[randrange(3)] = items[randrange(3)].upper() ? That would call randrange twice, potentially grabbing one element and dropping it into another slot. If it isn't equivalent to that, how is it defined? I'm sure something can be figured out that will satisfy the interpreter, but will it work for humans? ChrisA

As I see it, you are mixing very different things. Augmented operators in Python work on objects, generally trying to mutate them in-place. So usually after these operations you have the same object (with the same type, with the same name and etc.) as before these operations. Of course there are exceptions, for example all immutable types or some promotions between numbers. In your examples some cases imply that you are working on names, others that you are working on objects. And as for me this ambiguity is not solvable. With kind regards, -gdg ср, 26 сент. 2018 г. в 14:14, Jasper Rebane <rebane2001@gmail.com>:

This seems like a fairly terrible idea. -100 from me. Python simply does not tends to chain methods for mutation of objects. A few libraries—e.g. Pandas—do this, but in those cases actual chaining is more idiomatic. This is very different from '+=' or '*=' or even '|=' where you pretty much expect to wind up with the same type of thing on the binding or mutation. Of course, you can define operators as you like, so it's not hard and fast, but it's usual. I.e. '+=' is unlikely to leave the current number domain, other than according to the regular numeric hierarchy. text = "foo"
text .= replace("foo","bar")
This one example is okay. But most are awful: text .= count('foo') text .= split(';') text .= find('bar') In all of those you jump around among various data types bound to 'text'

On Wed, Sep 26, 2018 at 9:14 PM Jasper Rebane <rebane2001@gmail.com> wrote:
All the other augmented operators are of the form: target #= value with some sort of valid assignment target, and any value at all on the right hand side. You can take the value and put it in a variable, you can replace it with a function returning that value, etc, etc, etc, as it is simply a value. There's no difference between "x += 123" and "y = 123; x += y". (Putting it another way: "x *= y + z" is not equivalent to "x = x * y + z", but to "x = x * (y + z)".) With your proposed ".=" operator, it's quite different: the RHS is textually concatenated with the LHS. This creates odd edge cases. For example: items = ["foo", "bar", "quux"] items[randrange(3)] .= upper() Is this equivalent to: items[randrange(3)] = items[randrange(3)].upper() ? That would call randrange twice, potentially grabbing one element and dropping it into another slot. If it isn't equivalent to that, how is it defined? I'm sure something can be figured out that will satisfy the interpreter, but will it work for humans? ChrisA

As I see it, you are mixing very different things. Augmented operators in Python work on objects, generally trying to mutate them in-place. So usually after these operations you have the same object (with the same type, with the same name and etc.) as before these operations. Of course there are exceptions, for example all immutable types or some promotions between numbers. In your examples some cases imply that you are working on names, others that you are working on objects. And as for me this ambiguity is not solvable. With kind regards, -gdg ср, 26 сент. 2018 г. в 14:14, Jasper Rebane <rebane2001@gmail.com>:

This seems like a fairly terrible idea. -100 from me. Python simply does not tends to chain methods for mutation of objects. A few libraries—e.g. Pandas—do this, but in those cases actual chaining is more idiomatic. This is very different from '+=' or '*=' or even '|=' where you pretty much expect to wind up with the same type of thing on the binding or mutation. Of course, you can define operators as you like, so it's not hard and fast, but it's usual. I.e. '+=' is unlikely to leave the current number domain, other than according to the regular numeric hierarchy. text = "foo"
text .= replace("foo","bar")
This one example is okay. But most are awful: text .= count('foo') text .= split(';') text .= find('bar') In all of those you jump around among various data types bound to 'text'
participants (5)
-
Chris Angelico
-
David Mertz
-
James Lu
-
Jasper Rebane
-
Kirill Balunov