From: Patrick Maupin on
On Apr 30, 11:04 am, Jabapyth <jabap...(a)gmail.com> wrote:
> At least a few times a day I wish python had the following shortcut
> syntax:
>
> vbl.=func(args)
>
> this would be equivalent to
>
> vbl = vbl.func(args)
>
> example:
>
> foo = "Hello world"
> foo.=split(" ")
> print foo
> # ['Hello', 'world']
>
> and I guess you could generalize this to
>
> vbl.=[some text]
> #
> vbl = vbl.[some text]
>
> e.g.
>
> temp.=children[0]
> # temp = temp.children[0]
>
> thoughts?

First thought: good luck getting something like this through.
Probably not going to happen, although I do find the idea very
intriguing.

Second thought: I don't like the proposed syntax at all.

+=, -=, /=, *=, etc. conceptually (and, if lhs object supports in-
place operator methods, actually) *modify* the lhs object.

Your proposed .= syntax conceptually *replaces* the lhs object
(actually, rebinds the lhs symbol to the new object).

If this were to be deemed worthy of the language, I would think a
better syntax would be something like:

mystring = .upper()
mystring = .replace('a', 'b')

etc.

The '=' shows clearly that mystring is being rebound to a new object.

As Steven has shown, '.' functions as an operator, so if this change
were accepted, in reality you would probably be able to write:

mystring = . upper()
mystring=.upper()

or whatever. But the canonical form would probably be with a space
before the period but not after.

Regards,
Pat
From: Tim Chase on
On 05/01/2010 12:08 AM, Patrick Maupin wrote:
> +=, -=, /=, *=, etc. conceptually (and, if lhs object supports in-
> place operator methods, actually) *modify* the lhs object.
>
> Your proposed .= syntax conceptually *replaces* the lhs object
> (actually, rebinds the lhs symbol to the new object).

The += family of operators really do rebind the symbol, not
modify the object.

>>> from decimal import Decimal
>>> d = Decimal(42)
>>> e = Decimal(18)
>>> orig = d
>>> d += e
>>> d
Decimal("60")
>>> e
Decimal("18")
>>> orig
Decimal("42")
>>> d is orig
False

If your suggestion that += *modifies* the object, then orig would
now unintuitively contain 60 and "d is orig" would return True.

This doesn't preclude you from implementing a self-mutating +=
style __add__ method and returning "self", but it's usually a bad
idea unless it's dire for performance (and even then, think it
over a couple times).

-tkc



From: Stefan Behnel on
Tim Chase, 01.05.2010 14:13:
> On 05/01/2010 12:08 AM, Patrick Maupin wrote:
>> +=, -=, /=, *=, etc. conceptually (and, if lhs object supports in-
>> place operator methods, actually) *modify* the lhs object.
>>
>> Your proposed .= syntax conceptually *replaces* the lhs object
>> (actually, rebinds the lhs symbol to the new object).
>
> The += family of operators really do rebind the symbol, not modify the
> object.
>
> >>> from decimal import Decimal
> >>> d = Decimal(42)
> >>> e = Decimal(18)
> >>> orig = d
> >>> d += e
> >>> d
> Decimal("60")
> >>> e
> Decimal("18")
> >>> orig
> Decimal("42")
> >>> d is orig
> False
>
> If your suggestion that += *modifies* the object, then orig would now
> unintuitively contain 60 and "d is orig" would return True.
>
> This doesn't preclude you from implementing a self-mutating += style
> __add__ method and returning "self", but it's usually a bad idea unless
> it's dire for performance (and even then, think it over a couple times).

It's not like this was unprecedented in Python, though:

Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> l = [1,2,3]
>>> a = l
>>> l += [4,5,6]
>>> l
[1, 2, 3, 4, 5, 6]
>>> a
[1, 2, 3, 4, 5, 6]

And I'm pretty sure this wasn't just done for performance reasons. Mutable
data types behave that way.

Stefan

From: Alf P. Steinbach on
On 01.05.2010 14:13, * Tim Chase:
> On 05/01/2010 12:08 AM, Patrick Maupin wrote:
>> +=, -=, /=, *=, etc. conceptually (and, if lhs object supports in-
>> place operator methods, actually) *modify* the lhs object.
>>
>> Your proposed .= syntax conceptually *replaces* the lhs object
>> (actually, rebinds the lhs symbol to the new object).
>
> The += family of operators really do rebind the symbol, not modify the
> object.
>
> >>> from decimal import Decimal
> >>> d = Decimal(42)
> >>> e = Decimal(18)
> >>> orig = d
> >>> d += e
> >>> d
> Decimal("60")
> >>> e
> Decimal("18")
> >>> orig
> Decimal("42")
> >>> d is orig
> False
>
> If your suggestion that += *modifies* the object, then orig would now
> unintuitively contain 60 and "d is orig" would return True.

In some cases += modifies the object. For CPython this is an optimization for
the 'str' type, reducing to O(n) time the common newbie O(n^2) loops. The
criterion for doing it is that there is exactly 1 reference (as is the case
after a first append, subsequent appends can just modify).


> This doesn't preclude you from implementing a self-mutating += style
> __add__ method and returning "self", but it's usually a bad idea unless
> it's dire for performance (and even then, think it over a couple times).

Agreed, at the Python level one doesn't in general have the necessary
information to do it safely. Nothwithstanding the current CPython and Jython
documentation error of sys.getrefcount (or whatever the name was) that indicates
that it's available in any implementation.


Cheers,

- Alf
From: Lie Ryan on
On 05/01/10 11:16, Steven D'Aprano wrote:
> On Fri, 30 Apr 2010 12:34:34 -0400, D'Arcy J.M. Cain wrote:
>
> In practice though, I think that's a difference that makes no difference.
> It walks like an operator, it swims like an operator, and it quacks like
> an operator.
>

Nope it's not. A full-time operator in python have a reflected version
(e.g. __radd__), which dot does not have. And Python's object system
makes it that the argument to __getattr__ is always a string even though
there might be a valid variable that corresponds to it:

a = MyClass()
b = MyClass()
print a . b

I've often wanted to figure out a way to (ab)use python's dot operator
for function composition (i.e. f.g(x) ==> f(g(x)) ). There's no way to
do it, not without being way too hackish. OTOH, doing so is quite
trivial with regular operators. In short, unless there's __rgetattr__
and unless you can refer to the right-hand operand as an object[1], dot
doesn't quack like an operator.

[1] well, technically string is an object, but you get what I mean