"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
# needs to set the same local name to work inside function def func(): val = ... while len( this( val = dummy() ) ) >= 0: print(val)
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

2018-05-23 9:05 GMT+03:00 Terry Reedy <tjreedy@udel.edu>:
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 6:32 GMT+09:00 Kirill Balunov <kirillbalunov@gmail.com>:
[*] https://pypi.org/project/let3/ -- Masayuki

2018-05-23 14:19 GMT+03:00 Masayuki YAMAMOTO <ma3yuki.8mamo10@gmail.com>:
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

On 2018-05-22 14:32, Kirill Balunov wrote:
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 17:54 GMT+03:00 Mike Miller <python-ideas@mgmiller.net>:
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.
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 <kirillbalunov@gmail.com> wrote:

On Wed, May 23, 2018 at 12:32:36AM +0300, Kirill Balunov wrote:
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 <steve@pearwood.info>:
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.
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.
I'm not much attached to `this`. Ok let it be `let`.
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

2018-05-26 11:00 GMT+02:00 Kirill Balunov <kirillbalunov@gmail.com>:
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.

2018-05-23 9:05 GMT+03:00 Terry Reedy <tjreedy@udel.edu>:
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 6:32 GMT+09:00 Kirill Balunov <kirillbalunov@gmail.com>:
[*] https://pypi.org/project/let3/ -- Masayuki

2018-05-23 14:19 GMT+03:00 Masayuki YAMAMOTO <ma3yuki.8mamo10@gmail.com>:
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

On 2018-05-22 14:32, Kirill Balunov wrote:
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 17:54 GMT+03:00 Mike Miller <python-ideas@mgmiller.net>:
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.
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 <kirillbalunov@gmail.com> wrote:

On Wed, May 23, 2018 at 12:32:36AM +0300, Kirill Balunov wrote:
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 <steve@pearwood.info>:
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.
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.
I'm not much attached to `this`. Ok let it be `let`.
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

2018-05-26 11:00 GMT+02:00 Kirill Balunov <kirillbalunov@gmail.com>:
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