Python dot-equals (syntax proposal)

J

Jabapyth

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?
 
D

D'Arcy J.M. Cain

foo = "Hello world"
foo.=split(" ")

Isn't;

foo = "Hello world"
bar = foo.split() # side note - split() splits on whitespace by default

so much clearer? Do you really want to see Python turn into Perl?

However, if you really want to propose this you should be clear about
which of the following you mean.

foo .= split()
or
foo. = split()

I assume you mean the former to be analagous to "+=" and friends but I
am not sure since "." isn't an operator.
 
S

Stefan Behnel

J. Cliff Dyer, 30.04.2010 18:20:
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?

That's kind of a nifty idea. However, python is currently under a
syntax moratorium. No syntax changes will be accepted for at least 24
months starting from the release date of Python 3.1. See more details
here: http://www.python.org/dev/peps/pep-3003/

In any case, the right place to discuss this is the python-ideas list.

Stefan
 
P

Peter Otten

Jabapyth said:
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']

Extending a language comes at a cost, too. A language with 1000 superb
features will be much harder to use than one with 10 or 20.

In that spirit I suggest a thought experiment: which two features would you
kick out of Python to get your new one in?

Peter
 
J

Jean-Michel Pichavant

Jabapyth said:
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?
Useless if you use meaningful names for your variables & attributes.

It may happen that one object attribute refer to an object of the same
type, but it is quite rare that both can share the same name anyway.

Possible use cases:

1/
car = Car()
car = car.wheel # ???

2/
wheel = Car() # ???
wheel = wheel.wheel # ???

3/
currentCar = Car()
currentCar = currentCar.nextCar

The syntax you prose will be applicable on very little assignements (use
case 3). I'm not sure it's worth it.

JM
 
J

John Bokma

D'Arcy J.M. Cain said:
Isn't;

foo = "Hello world"
bar = foo.split() # side note - split() splits on whitespace by default

so much clearer? Do you really want to see Python turn into Perl?

Oh, boy, there we go again. Can you and your buddies please refrain from
using Perl as a kind of uber-argument? Just write why you think it's
wrong. Bonus points if you can use Python in your arguments.

Why I am asking this is that most "Oh, like Perl" statements I've seen
the past months were made by people who either haven't used Perl
themselves or have very little skill in the language. This is a Python
group.

On top of that, it's not possible in Perl (heh, no surprise there). The
only thing that comes close is:

for ( $a_very_long_variable_name ) {

s/foo/bar/g;
s/baz/woot/g;
s/o+/i/g;
}

Which makes $_ an alias for $a_very.... and since s/// defaults to $_
this works.
 
C

Chris Rebert

Oh, boy, there we go again. Can you and your buddies please refrain from
using Perl as a kind of uber-argument? Just write why you think it's
wrong. Bonus points if you can use Python in your arguments.

Why I am asking this is that most "Oh, like Perl" statements I've seen
the past months were made by people who either haven't used Perl
themselves or have very little skill in the language. This is a Python
group.

On top of that, it's not possible in Perl (heh, no surprise there). The
only thing that comes close is:

Actually/ironically, it does appear to be in Perl 6:
"""
Mutating method call
$obj.=meth
The .= operator does inplace modification of the object on the left.
""" -- Synopsis 3: Perl 6 Operators (http://feather.perl6.nl/syn/S03.html)

Cheers,
Chris
 
L

Lie Ryan

currentCar = Car()
currentCar = currentCar.nextCar

The syntax you prose will be applicable on very little assignements (use
case 3). I'm not sure it's worth it.


And for the last use case, isn't iterator better?
 
D

D'Arcy J.M. Cain

Oh, boy, there we go again. Can you and your buddies please refrain from
using Perl as a kind of uber-argument? Just write why you think it's
wrong. Bonus points if you can use Python in your arguments.

I think I was clear that the problem was obfuscation which Perl is very
good at. Haven't you ever had a Perl programmer show you a snippet of
code and say "I bet you can't guess what this does"?
On top of that, it's not possible in Perl (heh, no surprise there). The
only thing that comes close is:

for ( $a_very_long_variable_name ) {

s/foo/bar/g;
s/baz/woot/g;
s/o+/i/g;
}

Which makes $_ an alias for $a_very.... and since s/// defaults to $_

I hope that this example wasn't supposed to be a proof of Perl's
readability.

Anyway, you are right. I just happen to be dealing with some Perl and,
even worse, PHP issues on a new server and I am feeling a little
battered. I'll be better in a day or two.

By the way, to get back to the original topic, I don't really mind if
this makes it into the language because I won't be forced to use it.
 
A

Aahz

Why I am asking this is that most "Oh, like Perl" statements I've seen
the past months were made by people who either haven't used Perl
themselves or have very little skill in the language.

What evidence do you have for your assertion?
 
B

Brendan Abel

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?

I tend to use this design pattern occasionally in my code as well:

val = val.func() PROPOSED: val .= func()

OR

val = func(val) PROPOSED: val .= func(?) (not really sure how this
should look)


However, these are the only two use cases I can think of for this
language syntax modification proposal. The first use case could lead
to namespace issues (if func() exists as a function as well as a
method), and even if the interpreter can choose correctly, reading it
may lead to confusion. There will be at least some ambiguity in the
second use case (what if func() takes more than one argument, what if
it requires keyword arguments?). The current implementation is much
more readable (THE guiding principle with python), and doesn't require
any lengthier code than the proposed changes, especially when you
factor in any other syntax changes that would be necessary to handle
the aforementioned ambiguities.

Just my 2 cents. :)
 
S

Steven D'Aprano

Jabapyth said:
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)
[...]
Useless if you use meaningful names for your variables & attributes.

It may happen that one object attribute refer to an object of the same
type, but it is quite rare that both can share the same name anyway.

How about these common operations?

my_string = my_string.replace('quite rare', 'very common')
my_string = my_string.upper()
my_string = my_string.strip()

my_dict = my_dict.copy()

Or from decimal, a whole lot of methods that return new decimals,
including:

to_integral, next_plus, canonical, ln, sqrt, and many others.


But regardless of whether the pattern x = x.method is common or rare, I
don't like the suggestion, I don't think it's necessary, and because of
the moratorium it isn't going to happen any time soon even if Guido
himself suggests it.

-1 for the suggested .= syntactic sugar.
 
S

Steven D'Aprano

I assume you mean the former to be analagous to "+=" and friends but I
am not sure since "." isn't an operator.

It's a de facto operator. If you google on "python dot operator" you will
find many people who refer to it as such, and attribute lookup can be
over-ridden at runtime (using __getattribute__, __getattr__, etc.) just
like operators +, -, * etc.

Also you can do this:
'SOMETHING ELSE'

And even apply the dot "operator" to floats and ints, although because of
the ambiguity with floats you need to be clever:
4


However, dot is not a "real" operator, whatever that means: internally,
CPython treats it as a delimiter:

http://docs.python.org/reference/lexical_analysis.html#operators


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.
 
P

Patrick Maupin

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
 
T

Tim Chase

+=, -=, /=, *=, 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.
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
 
S

Stefan Behnel

Tim Chase, 01.05.2010 14:13:
The += family of operators really do rebind the symbol, not modify the
object.

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
 
A

Alf P. Steinbach

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

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
 
L

Lie Ryan

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top