I experimented with Python in college and I've been for close to 20 years now. (Coming and going as needed) I love the language. But there is one annoyance that I continually run into. There are basically two assignment operators, based on context, = and : a = 1 { a: 1 } They cannot be used interchangeably: a: 1 # error {a=1} # error I don't think I should be this way. There are times when I have a bunch of variables that I want to collect into an object or destructure. This involves adding commas, and swapping the :/=. I don't have a good fix for the adding of commas (maybe a newline?) but I think : should at least be accepted as = everywhere except in ifs: a: 1 # same as a = 1 One area where it might help (although the python parser already catches it) is in ifs: if a:1 # always error ? if a=1 # currently error, but might be accepted shorthand for == ? Ideally, I could take a: 1 b: 2 then in 3 edits: 1. first line prepend 'x: {' 2. last line append '}' 3. indent between { } I guess his would imply that { open up an assignment scope, where newlines are commas if the last line did not end with an operator or the next line did not start with an operator: x: { a: x - # - operator f(x) b: # : operator 5487234728394720348988734574357 c: 7 # c is 13, no trailing operator but next line has a preceding operator + 6 } The only issue then is how do we address a? x.a # looks fine to me x['a'] # as a dict, but the conversion of a to string 'a' could be confusing. Additionally, I was also thinking about : as an implied await: a = await f() # await generator a: f() # await generator, or direct assignment if return type is not a generator/async func Thoughts? Please be gentle :-)
On 21/07/17 18:07, Jason H wrote:
There are basically two assignment operators, based on context, = and : a = 1 { a: 1 }
No there aren't. The colon isn't assigning at all, it's separating a key from a corresponding value. The object referenced by 'a' is unchanged by being part of a dictionary literal. From that point on your whole argument falls apart. -- Rhodri James *-* Kynesim Ltd
On Fri, 21 Jul 2017 at 10:08 Jason H
I experimented with Python in college and I've been for close to 20 years now. (Coming and going as needed) I love the language. But there is one annoyance that I continually run into.
There are basically two assignment operators, based on context, = and : a = 1 { a: 1 }
So the latter is not an assignment. `=` is an assignment as it creates a new entry in a namespace, while the later just associates a key with a value in a dictionary.
They cannot be used interchangeably: a: 1 # error {a=1} # error
I don't think I should be this way.
But it's on purpose as they do different things. Thanks for sharing the idea but I don't see this changing. -Brett
There are times when I have a bunch of variables that I want to collect into an object or destructure. This involves adding commas, and swapping the :/=. I don't have a good fix for the adding of commas (maybe a newline?) but I think : should at least be accepted as = everywhere except in ifs: a: 1 # same as a = 1
One area where it might help (although the python parser already catches it) is in ifs: if a:1 # always error ? if a=1 # currently error, but might be accepted shorthand for == ?
Ideally, I could take a: 1 b: 2 then in 3 edits: 1. first line prepend 'x: {' 2. last line append '}' 3. indent between { }
I guess his would imply that { open up an assignment scope, where newlines are commas if the last line did not end with an operator or the next line did not start with an operator: x: { a: x - # - operator f(x) b: # : operator 5487234728394720348988734574357 c: 7 # c is 13, no trailing operator but next line has a preceding operator + 6 }
The only issue then is how do we address a? x.a # looks fine to me x['a'] # as a dict, but the conversion of a to string 'a' could be confusing.
Additionally, I was also thinking about : as an implied await: a = await f() # await generator a: f() # await generator, or direct assignment if return type is not a generator/async func
Thoughts? Please be gentle :-) _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
On Fri, Jul 21, 2017 at 10:19 AM, Brett Cannon
On Fri, 21 Jul 2017 at 10:08 Jason H
wrote: I experimented with Python in college and I've been for close to 20 years now. (Coming and going as needed) I love the language. But there is one annoyance that I continually run into.
There are basically two assignment operators, based on context, = and : a = 1 { a: 1 }
The `=` isn't an assignment operator, it's a *binding*. The name 'a' gets bound to the integer object "1" in your example. Don't confuse this with a language like C where it really is an assignment. If I later write: a = 2 I haven't changed the "cell" that contains the integer object, I've rebound the NAME `a` to a different object. But you've left out quite a few binding operations. I might forget some, but here are several: import a # bind the name `a` to a module object with open(fname) as a: pass # bind the name `a` to a file handle for a in [1]: pass # bind the name `a` to each of the objects in an iterable # ... In this case, the net result is identical to `a=1` def a(): pass # bind the name `a` to a function object defined in the body class a: pass # bind the name `a` to a class object defined in the body With a bit of circuitous code, you *can* use a dictionary to bind a variable too: >>> globals().update({'a':1}) >>> a 1 -- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.
On Fri, Jul 21, 2017 at 12:59 PM, David Mertz
But you've left out quite a few binding operations. I might forget some, but here are several:
Ned Batchelder had a good presentation at PyCon 2015 about names/values/assignments/binding: https://youtu.be/_AEJHKGk9ns?t=12m52s His summary of all assignment operators: X = ... for X in ... class X: pass def X: pass def fn(X): # when called, X is bound import X from ... import X except ... as X: with ... as X: ...I think only includes one other assignment type from what you listed (function parameters) that ironically is where one could maybe blur =/:, as doing f(x=3) and f(**{x: 3}) are usually similar (I think some C functions react poorly?).
On Wed, Jul 26, 2017 at 3:02 AM, Nick Timkovich
...I think only includes one other assignment type from what you listed (function parameters) that ironically is where one could maybe blur =/:, as doing f(x=3) and f(**{x: 3}) are usually similar (I think some C functions react poorly?).
The only difference with C functions is that you can have named positional-only parameters, which you can't do in a pure-Python function. The nearest equivalent is to use *args and then peel the arguments off that manually, but then they don't have names at all. ChrisA
On 2017-07-25 18:02, Nick Timkovich wrote:
On Fri, Jul 21, 2017 at 12:59 PM, David Mertz
mailto:mertz@gnosis.cx> wrote: But you've left out quite a few binding operations. I might forget some, but here are several:
Ned Batchelder had a good presentation at PyCon 2015 about names/values/assignments/binding: https://youtu.be/_AEJHKGk9ns?t=12m52s His summary of all assignment operators:
X = ... for X in ... class X: pass def X: pass def fn(X): # when called, X is bound import X from ... import X except ... as X: with ... as X:
There's also: import ... as X from ... import ... as X
...I think only includes one other assignment type from what you listed (function parameters) that ironically is where one could maybe blur =/:, as doing f(x=3) and f(**{x: 3}) are usually similar (I think some C functions react poorly?).
On 7/25/17, MRAB
On 2017-07-25 18:02, Nick Timkovich wrote:
On Fri, Jul 21, 2017 at 12:59 PM, David Mertz
mailto:mertz@gnosis.cx> wrote: But you've left out quite a few binding operations. I might forget some, but here are several:
Ned Batchelder had a good presentation at PyCon 2015 about names/values/assignments/binding: https://youtu.be/_AEJHKGk9ns?t=12m52s His summary of all assignment operators:
X = ... for X in ... class X: pass def X: pass def fn(X): # when called, X is bound import X from ... import X except ... as X: with ... as X:
There's also:
import ... as X from ... import ... as X
globals()['X'] = ...
2017-07-21 10:07 GMT-07:00 Jason H
I experimented with Python in college and I've been for close to 20 years now. (Coming and going as needed) I love the language. But there is one annoyance that I continually run into.
There are basically two assignment operators, based on context, = and : a = 1 { a: 1 }
They cannot be used interchangeably: a: 1 # error {a=1} # error
I don't think I should be this way.
There are times when I have a bunch of variables that I want to collect into an object or destructure. This involves adding commas, and swapping the :/=. I don't have a good fix for the adding of commas (maybe a newline?) but I think : should at least be accepted as = everywhere except in ifs: a: 1 # same as a = 1
One area where it might help (although the python parser already catches it) is in ifs: if a:1 # always error ? if a=1 # currently error, but might be accepted shorthand for == ?
Ideally, I could take a: 1 b: 2
This conflicts with PEP 526 variable annotations: "a: int" already means "a is of type int", but with your syntax there would be no way to distinguish between "a = int" and "a: int".
then in 3 edits: 1. first line prepend 'x: {' 2. last line append '}' 3. indent between { }
I guess his would imply that { open up an assignment scope, where newlines are commas if the last line did not end with an operator or the next line did not start with an operator: x: { a: x - # - operator f(x) b: # : operator 5487234728394720348988734574357 c: 7 # c is 13, no trailing operator but next line has a preceding operator + 6 }
The only issue then is how do we address a? x.a # looks fine to me x['a'] # as a dict, but the conversion of a to string 'a' could be confusing.
Additionally, I was also thinking about : as an implied await: a = await f() # await generator a: f() # await generator, or direct assignment if return type is not a generator/async func
Thoughts? Please be gentle :-) _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
participants (9)
-
Brett Cannon
-
Chris Angelico
-
David Mertz
-
Jason H
-
Jelle Zijlstra
-
MRAB
-
Nick Timkovich
-
Pavol Lisy
-
Rhodri James