"Assignment expression" with function call-alike syntax
Just one more variation on "assignment exression" syntax to make the list more complete :) Sorry, if something similar has already been suggested. The idea is to use function's call-like syntax in the from: `this( name = expr )`. I'm not sure that such idea will find its supporters and whether it is possible to implement it in a general way, but nevertheless. Below is a half- and slow-working prototype and some silly examples just for the sake of feeling the idea: import sys import ctypes def this(**assign): assert len(assign) == 1 [(name, value)] = assign.items() frame = sys._getframe(1) frame.f_locals[name] = value ctypes.pythonapi.PyFrame_LocalsToFast(ctypes.py_object(frame), ctypes.c_int(0)) return value Loop-and-a-half example with `dummy` function[1]: # in global scope everything works ok since locals is globals
while len( this( val = dummy() ) ) >= 0: ... print(val) [0, 1] [0, 1, 2] [0, 1, 2, 3] ...
# needs to set the same local name to work inside function def func(): val = ... while len( this( val = dummy() ) ) >= 0: print(val)
# relies on the implicit underlying function's local `x` [[this(x = (x+10)), x//10, x*10] for x in [100, 200, 300]] [[110, 11, 1100], [210, 21, 2100], [310, 31, 3100]]
In this way it is somewhat possible to make an assignment in `while` and `if ` headers right now, which covers 90% cases, but it is damn slow. Maybe be it is worth to make `this` magic call-alike object work fast...on the other hand does anyone like `this`? With kind regards, -gdg [1]: def dummy(ls = [0]): ls.append(ls[-1]+1) return ls
On 5/22/2018 5:32 PM, Kirill Balunov wrote:
Just one more variation on "assignment exression" syntax to make the list more complete :) Sorry, if something similar has already been suggested. The idea is to use function's call-like syntax in the from: `this( name = expr )`.
Functions names should be verbs. For this one, 'bind' or even better, 'let' as in 'let(name=expr)' I'm not sure that such idea will find its
supporters and whether it is possible to implement it in a general way, but nevertheless. Below is a half- and slow-working prototype and some silly examples just for the sake of feeling the idea:
import sys import ctypes
def this(**assign): assert len(assign) == 1 [(name, value)] = assign.items() frame = sys._getframe(1) frame.f_locals[name] = value ctypes.pythonapi.PyFrame_LocalsToFast(ctypes.py_object(frame), ctypes.c_int(0)) return value
Loop-and-a-half example with `dummy` function[1]:
# in global scope everything works ok since locals is globals >>> while len( this( val = dummy() ) ) >= 0: ... print(val) [0, 1] [0, 1, 2] [0, 1, 2, 3] ...
# needs to set the same local name to work inside function def func(): val = ... while len( this( val = dummy() ) ) >= 0: print(val)
>>> # relies on the implicit underlying function's local `x` >>> [[this(x = (x+10)), x//10, x*10] for x in [100, 200, 300]] [[110, 11, 1100], [210, 21, 2100], [310, 31, 3100]]
In this way it is somewhat possible to make an assignment in `while` and `if`headers right now, which covers 90% cases, but it is damn slow. Maybe be it is worth to make `this` magic call-alike object work fast...on the other hand does anyone like `this`?
With kind regards, -gdg
[1]:
def dummy(ls = [0]): ls.append(ls[-1]+1) return ls
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
-- Terry Jan Reedy
2018-05-23 6:32 GMT+09:00 Kirill Balunov
Just one more variation on "assignment exression" syntax to make the list more complete :) Sorry, if something similar has already been suggested. The idea is to use function's call-like syntax in the from: `this( name = expr )`. I'm not sure that such idea will find its supporters and whether it is possible to implement it in a general way, but nevertheless. Below is a half- and slow-working prototype and some silly examples just for the sake of feeling the idea:
import sys import ctypes
def this(**assign): assert len(assign) == 1 [(name, value)] = assign.items() frame = sys._getframe(1) frame.f_locals[name] = value ctypes.pythonapi.PyFrame_LocalsToFast(ctypes.py_object(frame), ctypes.c_int(0)) return value
FYI, I found a package [*] which binds a value by function keyword (I'm not the author). Note that the package writes a value in the global (or raise an error if the name already exists in local) unlike your idea.
[*] https://pypi.org/project/let3/ -- Masayuki
On 2018-05-22 14:32, Kirill Balunov wrote:
# in global scope everything works ok since locals is globals >>> while len( this( val = dummy() ) ) >= 0: ... print(val) [0, 1] [0, 1, 2] [0, 1, 2, 3]
Interesting! Although the example with a len() and mutable default arguments obscured the utility, I thought. Also, why limit it to one assignment? Liked Terry's suggestions for name. The name that jumped into my brain as I read was a reuse of the locals() or globals() callable with key words, that would change their behavior to what you suggest. -Mike
2018-05-23 9:05 GMT+03:00 Terry Reedy
On 5/22/2018 5:32 PM, Kirill Balunov wrote:
Just one more variation on "assignment exression" syntax to make the list more complete :) Sorry, if something similar has already been suggested. The idea is to use function's call-like syntax in the from: `this( name = expr )`.
Functions names should be verbs. For this one, 'bind' or even better, 'let' as in 'let(name=expr)'
It only looks like a function call, but in fact it should be an _magic object_ that can on the call bind a name to an expression in the current local scope. I chose `this` because in my opinion it is easily perceived: `while this( name = expr ) > 0` can be readed as "While this name assigned to an expression is greater than zero do..." the same interpretation for `if` statement. With kind regards, -gdg
2018-05-23 14:19 GMT+03:00 Masayuki YAMAMOTO
FYI, I found a package [*] which binds a value by function keyword (I'm not the author). Note that the package writes a value in the global (or raise an error if the name already exists in local) unlike your idea.
[*] https://pypi.org/project/let3/
-- Masayuki
Thank you! Writing to a globals is an even more stripped-down version from the inteded behaviour, for example it would not work in comprehensions at all and would not work if function has the same local name. In fact comprehension/generator cases are the least interesting for me. I just wanted to minimize side-effects. With kind regards, -gdg
2018-05-23 17:54 GMT+03:00 Mike Miller
On 2018-05-22 14:32, Kirill Balunov wrote:
# in global scope everything works ok since locals is globals >>> while len( this( val = dummy() ) ) >= 0: ... print(val) [0, 1] [0, 1, 2] [0, 1, 2, 3]
Interesting! Although the example with a len() and mutable default arguments obscured the utility, I thought. Also, why limit it to one assignment?
I just want some dummy example which can not be trivially handled with `for name in iter(func, value)`. But the latter is also only partly true. You can make something like: class P: __slots__ = ('func') def __init__(self, func): self.func = func def __eq__(self, other): return not self.func(other) for val in iter(dummy, P(lambda x: len(x) < 5)): print(val) [0, 1] [0, 1, 2] [0, 1, 2, 3] The only restriction is that you can not pass arguments to a `func`, but this, to some extent, can also be handled with lambda. I limit it to _one assignment_ firstly to make it simple, and secondly to get rid of some edge cases.
Liked Terry's suggestions for name. The name that jumped into my brain as I read was a reuse of the locals() or globals() callable with key words, that would change their behavior to what you suggest.
I like `this` because it is easy to follow in my opinion: " While this name assigned to an expression is greater than zero do... " But of course I'm open to any other spelling. I'm just wondering, if someone like this form as an alternative for assignment expression (`:=`). With kind regards, -gdg
The name `this` is problematic as it has a well established, different
meaning
in lots of other languages. It's basically `self` for languages that assign
to it
automatically. Full stack Python users will have `this` meaning two
different
things at each end, and they cannot alias it in either of them.
I'm not sure on the feature, but thought `let` was a perfect name for it.
-- Carl Smith
carl.input@gmail.com
On 23 May 2018 at 19:48, Kirill Balunov
2018-05-23 17:54 GMT+03:00 Mike Miller
: On 2018-05-22 14:32, Kirill Balunov wrote:
# in global scope everything works ok since locals is globals >>> while len( this( val = dummy() ) ) >= 0: ... print(val) [0, 1] [0, 1, 2] [0, 1, 2, 3]
Interesting! Although the example with a len() and mutable default arguments obscured the utility, I thought. Also, why limit it to one assignment?
I just want some dummy example which can not be trivially handled with `for name in iter(func, value)`. But the latter is also only partly true. You can make something like:
class P: __slots__ = ('func') def __init__(self, func): self.func = func def __eq__(self, other): return not self.func(other)
for val in iter(dummy, P(lambda x: len(x) < 5)): print(val)
[0, 1] [0, 1, 2] [0, 1, 2, 3]
The only restriction is that you can not pass arguments to a `func`, but this, to some extent, can also be handled with lambda. I limit it to _one assignment_ firstly to make it simple, and secondly to get rid of some edge cases.
Liked Terry's suggestions for name. The name that jumped into my brain as I read was a reuse of the locals() or globals() callable with key words, that would change their behavior to what you suggest.
I like `this` because it is easy to follow in my opinion: " While this name assigned to an expression is greater than zero do... " But of course I'm open to any other spelling. I'm just wondering, if someone like this form as an alternative for assignment expression (`:=`).
With kind regards, -gdg
_______________________________________________ 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 Wed, May 23, 2018 at 12:32:36AM +0300, Kirill Balunov wrote:
Just one more variation on "assignment exression" syntax to make the list more complete :) Sorry, if something similar has already been suggested. The idea is to use function's call-like syntax in the from: `this( name = expr )`. [...] In this way it is somewhat possible to make an assignment in `while` and `if ` headers right now, which covers 90% cases, but it is damn slow. Maybe be it is worth to make `this` magic call-alike object work fast...on the other hand does anyone like `this`?
Apart from needing extra typing, what does the function-call syntax gain us? It looks like a function you could call from anywhere, but you want to limit it to just "while" and "if", I expect that will just give us a flood of questions on Stackoverflow and other forums, "why can't I use this() outside of if and while loops?" A good question. Why shouldn't we use assignment outside of if and while? Since this is special syntax, not a function, the parens don't give us any benefit: this name = expression The word "this" seems inappropriate. Surely "let" or "set" would be better: let name = expression which at least has the benefit of matching syntax chosen in other languages. But if the only reason we include "let" is to avoid the equals/assignment error, that seems needlessly verbose. We can say the same thing more compactly: name := expression The difference between "let name = expression" and "name := expression" is just spelling. -- Steve
2018-05-24 4:21 GMT+03:00 Steven D'Aprano
On Wed, May 23, 2018 at 12:32:36AM +0300, Kirill Balunov wrote:
Just one more variation on "assignment exression" syntax to make the list more complete :) Sorry, if something similar has already been suggested. The idea is to use function's call-like syntax in the from: `this( name = expr )`. [...] In this way it is somewhat possible to make an assignment in `while` and `if ` headers right now, which covers 90% cases, but it is damn slow. Maybe be it is worth to make `this` magic call-alike object work fast...on the other hand does anyone like `this`?
Apart from needing extra typing, what does the function-call syntax gain us?
This will allow us to temporarily avoid the introduction of a new syntax. Since this option does not require a new syntax, you can provide a provisional module containing. This will allow to understand more clearly the actual use cases and the attitude of users towards the general idea.
It looks like a function you could call from anywhere, but you want to limit it to just "while" and "if", I expect that will just give us a flood of questions on Stackoverflow and other forums, "why can't I use this() outside of if and while loops?"
I do not know how you decided that I propose to limit this call-alike variant only to `while` and `if`statements. I did not say that. I just said that personally I'm interested and see the advantages of using it only in `while` and `if` statements. Of course you are right that you can call it from anywhere.
A good question. Why shouldn't we use assignment outside of if and while?
Since this is special syntax, not a function, the parens don't give us any benefit:
this name = expression
The word "this" seems inappropriate. Surely "let" or "set" would be better:
let name = expression
which at least has the benefit of matching syntax chosen in other languages. But if the only reason we include "let" is to avoid the equals/assignment error, that seems needlessly verbose. We can say the same thing more compactly:
I'm not much attached to `this`. Ok let it be `let`.
name := expression
The difference between "let name = expression" and "name := expression" is just spelling.
The main point is to collect more information, since the idea of assignment expression will have a huge impact in all aspects of Python programming: how you structure your programm, how you write code, how you read code, how you parse code... Because at the moment the rule is simple that any name binding must occur only in statements. With kind regards, -gdg
On Sat, May 26, 2018 at 12:00:45PM +0300, Kirill Balunov wrote:
It looks like a function you could call from anywhere, but you want to limit it to just "while" and "if", I expect that will just give us a flood of questions on Stackoverflow and other forums, "why can't I use this() outside of if and while loops?"
I do not know how you decided that I propose to limit this call-alike variant only to `while` and `if`statements. I did not say that. I just said that personally I'm interested and see the advantages of using it only in `while` and `if` statements. Of course you are right that you can call it from anywhere.
My mistake, sorry. -- Steve
2018-05-26 11:00 GMT+02:00 Kirill Balunov
The main point is to collect more information, since the idea of assignment expression will have a huge impact in all aspects of Python programming: how you structure your programm, how you write code, how you read code, how you parse code... Because at the moment the rule is simple that any name binding must occur only in statements.
With kind regards, -gdg
Downside here is, if you first implement it like this, everyone will be used to that implementation. If after that a special syntax gets introduced, there will be people confusing it and having to use multiple libraries which use the two different ways. And most people will stick to the old way because it'll have more compatible python versions, no matter how much better a new syntax could be. Unless you want a deprecation cycle planning for a feature not even implemented yet ? I think that if implemented, it needs to be the final implementation right away.
participants (7)
-
Carl Smith
-
Jacco van Dorp
-
Kirill Balunov
-
Masayuki YAMAMOTO
-
Mike Miller
-
Steven D'Aprano
-
Terry Reedy