Mailing List Archive

New assignmens ...
Hi!

Why doesn't this work
if (self.ctr:=self.ctr-1)<=0:
while this works
if (ctr:=ctr-1)<=0:

Thanks
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On 2021-10-22, Stefan Ram <ram@zedat.fu-berlin.de> wrote:
> Paulo da Silva <p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> writes:
>>Why doesn't this work
>> if (self.ctr:=self.ctr-1)<=0:
>>while this works
>> if (ctr:=ctr-1)<=0:
>
> assignment_expression ::= [identifier ":="] expression,
> but the attribute references "self.ctr" is no identifier!

This seems a surprising omission. You'd expect at least 'attributeref'
and 'subscription' to be allowed, if not the whole of 'target'.
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Sat, Oct 23, 2021 at 6:24 AM Jon Ribbens via Python-list
<python-list@python.org> wrote:
>
> On 2021-10-22, Stefan Ram <ram@zedat.fu-berlin.de> wrote:
> > Paulo da Silva <p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> writes:
> >>Why doesn't this work
> >> if (self.ctr:=self.ctr-1)<=0:
> >>while this works
> >> if (ctr:=ctr-1)<=0:
> >
> > assignment_expression ::= [identifier ":="] expression,
> > but the attribute references "self.ctr" is no identifier!
>
> This seems a surprising omission. You'd expect at least 'attributeref'
> and 'subscription' to be allowed, if not the whole of 'target'.

That's not the primary use-case for assignment expressions, and they
were highly controversial. It is much easier to expand it afterwards
than to restrict it, or to have the feature rejected because people
are scared of some small aspect of it.

If you want to propose relaxing the restrictions, make your use-case
and attempt to convince people of the value.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On 23/10/2021 08.34, Chris Angelico wrote:
> On Sat, Oct 23, 2021 at 6:24 AM Jon Ribbens via Python-list
> <python-list@python.org> wrote:
>>
>> On 2021-10-22, Stefan Ram <ram@zedat.fu-berlin.de> wrote:
>>> Paulo da Silva <p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> writes:
>>>> Why doesn't this work
>>>> if (self.ctr:=self.ctr-1)<=0:
>>>> while this works
>>>> if (ctr:=ctr-1)<=0:
>>>
>>> assignment_expression ::= [identifier ":="] expression,
>>> but the attribute references "self.ctr" is no identifier!
>>
>> This seems a surprising omission. You'd expect at least 'attributeref'
>> and 'subscription' to be allowed, if not the whole of 'target'.
>
> That's not the primary use-case for assignment expressions, and they
> were highly controversial. It is much easier to expand it afterwards
> than to restrict it, or to have the feature rejected because people
> are scared of some small aspect of it.


ie neither can one use subscripted elements, eg list-elements, as the
LHS of an assignment expression.
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
With apologies for pressing Send too early...

On 23/10/2021 08.41, dn via Python-list wrote:
> On 23/10/2021 08.34, Chris Angelico wrote:
>> On Sat, Oct 23, 2021 at 6:24 AM Jon Ribbens via Python-list
>> <python-list@python.org> wrote:
>>>
>>> On 2021-10-22, Stefan Ram <ram@zedat.fu-berlin.de> wrote:
>>>> Paulo da Silva <p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> writes:
>>>>> Why doesn't this work
>>>>> if (self.ctr:=self.ctr-1)<=0:
>>>>> while this works
>>>>> if (ctr:=ctr-1)<=0:
>>>>
>>>> assignment_expression ::= [identifier ":="] expression,
>>>> but the attribute references "self.ctr" is no identifier!
>>>
>>> This seems a surprising omission. You'd expect at least 'attributeref'
>>> and 'subscription' to be allowed, if not the whole of 'target'.
>>
>> That's not the primary use-case for assignment expressions, and they
>> were highly controversial. It is much easier to expand it afterwards
>> than to restrict it, or to have the feature rejected because people
>> are scared of some small aspect of it.
>
>
> ie neither can one use subscripted elements, eg list-elements, as the
> LHS of an assignment expression.

Whereas, creating a list (or tuple...) is legal because the structure's
name is an "identifier"!

if ( l := [ 1, 2, 3 ] > [ 1, 2 ] ):
print( "True" )

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On 23/10/21 8:49 am, dn wrote:
> Whereas, creating a list (or tuple...) is legal because the structure's
> name is an "identifier"!

No, the restriction only applies to the LHS. The list construction
is on the RHS.

--
Greg

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Às 20:34 de 22/10/21, Chris Angelico escreveu:
> On Sat, Oct 23, 2021 at 6:24 AM Jon Ribbens via Python-list
> <python-list@python.org> wrote:
>>
>> On 2021-10-22, Stefan Ram <ram@zedat.fu-berlin.de> wrote:
>>> Paulo da Silva <p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> writes:
>>>> Why doesn't this work
>>>> if (self.ctr:=self.ctr-1)<=0:
>>>> while this works
>>>> if (ctr:=ctr-1)<=0:
>>>
>>> assignment_expression ::= [identifier ":="] expression,
>>> but the attribute references "self.ctr" is no identifier!
>>
>> This seems a surprising omission. You'd expect at least 'attributeref'
>> and 'subscription' to be allowed, if not the whole of 'target'.
>
> That's not the primary use-case for assignment expressions, and they
> were highly controversial. It is much easier to expand it afterwards
> than to restrict it, or to have the feature rejected because people
> are scared of some small aspect of it.
>
> If you want to propose relaxing the restrictions, make your use-case
> and attempt to convince people of the value.
>
Well, I didn't follow the discussion of this new feature, but the reason
I can see behind allowing it seems so valid for for ctr:=ctr-1 as for
self.ctr:=self.ctr-1. The kind of use is exactly the same. One is for a
normal function, the other for a method.
IMHO this makes no sense at all. Arguable may be for example LHS
ctrs[i], or something like that. But self.ctr ...! Too weird.

Thanks
Paulo
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Sat, Oct 23, 2021 at 12:24 PM Paulo da Silva
<p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> wrote:
>
> Às 20:34 de 22/10/21, Chris Angelico escreveu:
> > On Sat, Oct 23, 2021 at 6:24 AM Jon Ribbens via Python-list
> > <python-list@python.org> wrote:
> >>
> >> On 2021-10-22, Stefan Ram <ram@zedat.fu-berlin.de> wrote:
> >>> Paulo da Silva <p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> writes:
> >>>> Why doesn't this work
> >>>> if (self.ctr:=self.ctr-1)<=0:
> >>>> while this works
> >>>> if (ctr:=ctr-1)<=0:
> >>>
> >>> assignment_expression ::= [identifier ":="] expression,
> >>> but the attribute references "self.ctr" is no identifier!
> >>
> >> This seems a surprising omission. You'd expect at least 'attributeref'
> >> and 'subscription' to be allowed, if not the whole of 'target'.
> >
> > That's not the primary use-case for assignment expressions, and they
> > were highly controversial. It is much easier to expand it afterwards
> > than to restrict it, or to have the feature rejected because people
> > are scared of some small aspect of it.
> >
> > If you want to propose relaxing the restrictions, make your use-case
> > and attempt to convince people of the value.
> >
> Well, I didn't follow the discussion of this new feature, but the reason
> I can see behind allowing it seems so valid for for ctr:=ctr-1 as for
> self.ctr:=self.ctr-1. The kind of use is exactly the same. One is for a
> normal function, the other for a method.
> IMHO this makes no sense at all. Arguable may be for example LHS
> ctrs[i], or something like that. But self.ctr ...! Too weird.
>

I've never used ctr:=ctr-1 either, though, so I don't know the actual
use cases. Why is this being used in an assignment expression? Is it
an ersatz loop?

Common use-cases include:

if m := re.match(...):

while data := thing.read():

etc. All of them are doing exactly two things: testing if something is
empty, and if it isn't, using it in a block of code.

In what situations do you need to mutate an attribute and also test
it, and how much hassle is it to simply break it out into two lines?
The onus is on you to show that it needs to be more flexible.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On 23/10/2021 12.51, Greg Ewing wrote:
> On 23/10/21 8:49 am, dn wrote:
>> Whereas, creating a list (or tuple...) is legal because the structure's
>> name is an "identifier"!
>
> No, the restriction only applies to the LHS. The list construction
> is on the RHS.


That contention (above) may have been taken slightly out-of-context.

Referring back to the previous contribution: mutating a list-element is
not legal, because just like an object's attribute addressed with
dotted-notation, a subscripted object is not regarded as an identifier.
Whereas creating a (whole) new list (for example) IS legal, because the
list's name IS an identifier.

Yes, the LHS must be an identifier - the point that was made in the
first response (quoting "Python Language Reference") and since.
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On 2021-10-23, Chris Angelico <rosuav@gmail.com> wrote:
> I've never used ctr:=ctr-1 either, though, so I don't know the actual
> use cases. Why is this being used in an assignment expression? Is it
> an ersatz loop?
>
> Common use-cases include:
>
> if m := re.match(...):
>
> while data := thing.read():
>
> etc. All of them are doing exactly two things: testing if something is
> empty, and if it isn't, using it in a block of code.
>
> In what situations do you need to mutate an attribute and also test
> it, and how much hassle is it to simply break it out into two lines?

It's not hard to imagine something like:

def get_expensive(self):
return self.expensive or self.expensive := self.calculate_expensive()

> The onus is on you to show that it needs to be more flexible.

Is it though? It seems to me that the onus is on you to show that
this special case is special enough to be given its own unique
existence. It's a bit surprising that the PEP doesn't discuss this
decision at all.
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Sun, Oct 24, 2021 at 4:39 AM Jon Ribbens via Python-list
<python-list@python.org> wrote:
>
> On 2021-10-23, Chris Angelico <rosuav@gmail.com> wrote:
> > I've never used ctr:=ctr-1 either, though, so I don't know the actual
> > use cases. Why is this being used in an assignment expression? Is it
> > an ersatz loop?
> >
> > Common use-cases include:
> >
> > if m := re.match(...):
> >
> > while data := thing.read():
> >
> > etc. All of them are doing exactly two things: testing if something is
> > empty, and if it isn't, using it in a block of code.
> >
> > In what situations do you need to mutate an attribute and also test
> > it, and how much hassle is it to simply break it out into two lines?
>
> It's not hard to imagine something like:
>
> def get_expensive(self):
> return self.expensive or self.expensive := self.calculate_expensive()

I usually write this sort of thing the other way:

def get_expensive(self, key):
if key not in self.cache:
self.cache[key] = ...
return self.cache[key]

and then if you don't like the duplication, the cleanest way is to put
the expensive calculation into the __missing__ method of a dict
subclass.

> > The onus is on you to show that it needs to be more flexible.
>
> Is it though? It seems to me that the onus is on you to show that
> this special case is special enough to be given its own unique
> existence. It's a bit surprising that the PEP doesn't discuss this
> decision at all.

The PEP was accepted. Thus it is now up to someone proposing a change
to show that the change is worthwhile.

Python has frequently started with a more restricted rule set, with
the option to make it less restricted in the future. Case in point:
Decorator syntax used to be limited to a small set of options, aimed
at the known use-cases at the time. Then very recently, that was
opened up to basically any expression.

https://www.python.org/dev/peps/pep-0614/

Read over that document for an excellent example of how to take a
tight proposal and recommend that it be made more flexible. Assignment
expressions are currently in the restricted form, allowing only simple
names, and it's up to you to propose and demonstrate the value of the
increased flexibility.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On 2021-10-23, Chris Angelico <rosuav@gmail.com> wrote:
> On Sun, Oct 24, 2021 at 4:39 AM Jon Ribbens via Python-list
><python-list@python.org> wrote:
>> On 2021-10-23, Chris Angelico <rosuav@gmail.com> wrote:
>> > In what situations do you need to mutate an attribute and also test
>> > it, and how much hassle is it to simply break it out into two lines?
>>
>> It's not hard to imagine something like:
>>
>> def get_expensive(self):
>> return self.expensive or self.expensive := self.calculate_expensive()
>
> I usually write this sort of thing the other way:
>
> def get_expensive(self, key):
> if key not in self.cache:
> self.cache[key] = ...
> return self.cache[key]
>
> and then if you don't like the duplication, the cleanest way is to put
> the expensive calculation into the __missing__ method of a dict
> subclass.

Sure, but if "there's already another way of doing it" was a winning
argument then assignment expressions wouldn't have been accepted into
the language at all.

>> > The onus is on you to show that it needs to be more flexible.
>>
>> Is it though? It seems to me that the onus is on you to show that
>> this special case is special enough to be given its own unique
>> existence. It's a bit surprising that the PEP doesn't discuss this
>> decision at all.
>
> The PEP was accepted. Thus it is now up to someone proposing a change
> to show that the change is worthwhile.
>
> Python has frequently started with a more restricted rule set, with
> the option to make it less restricted in the future. Case in point:
> Decorator syntax used to be limited to a small set of options, aimed
> at the known use-cases at the time. Then very recently, that was
> opened up to basically any expression.
>
> https://www.python.org/dev/peps/pep-0614/
>
> Read over that document for an excellent example of how to take a
> tight proposal and recommend that it be made more flexible. Assignment
> expressions are currently in the restricted form, allowing only simple
> names, and it's up to you to propose and demonstrate the value of the
> increased flexibility.

I think we're allowed to discuss things in this group without them
having to turn into formal proposals. Personally I've never written
a Python assignment expression, and I think it'll be a few years
before Python 3.8 is old enough for them to be conveniently usable.
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On 10/23/21 6:42 AM, Jon Ribbens via Python-list wrote:
> On 2021-10-23, Chris Angelico wrote:

>> The onus is on you to show that it needs to be more flexible.
>
> Is it though?

Yes.

> It seems to me that the onus is on you to show that
> this special case is special enough to be given its own unique
> existence.

It already has existence, so no further proof is needed.

> It's a bit surprising that the PEP doesn't discuss this
> decision at all.

In conversations as long as that one was, I'm not surprised this and maybe a couple other options didn't make it back to
the PEP. Nevertheless, I recall the decision to start simple, and expand later if needed.

--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Sun, Oct 24, 2021 at 7:48 AM Jon Ribbens via Python-list
<python-list@python.org> wrote:
>
> On 2021-10-23, Chris Angelico <rosuav@gmail.com> wrote:
> > On Sun, Oct 24, 2021 at 4:39 AM Jon Ribbens via Python-list
> ><python-list@python.org> wrote:
> >> On 2021-10-23, Chris Angelico <rosuav@gmail.com> wrote:
> >> > In what situations do you need to mutate an attribute and also test
> >> > it, and how much hassle is it to simply break it out into two lines?
> >>
> >> It's not hard to imagine something like:
> >>
> >> def get_expensive(self):
> >> return self.expensive or self.expensive := self.calculate_expensive()
> >
> > I usually write this sort of thing the other way:
> >
> > def get_expensive(self, key):
> > if key not in self.cache:
> > self.cache[key] = ...
> > return self.cache[key]
> >
> > and then if you don't like the duplication, the cleanest way is to put
> > the expensive calculation into the __missing__ method of a dict
> > subclass.
>
> Sure, but if "there's already another way of doing it" was a winning
> argument then assignment expressions wouldn't have been accepted into
> the language at all.

There is always another way of doing it. The question is not so much
"is this something that's currently absolutely impossible?" but more
"how ugly is the current way of doing things?". Ugly is, of course,
somewhat subjective, but if the current way of doing things involves a
lot of extra hassle, or is error-prone, etc, etc, then there's room to
show improvement.

The original PEP showed this improvement in ways that involved simple
names. Expanding on this is a separate proposal.


> > Read over that document for an excellent example of how to take a
> > tight proposal and recommend that it be made more flexible. Assignment
> > expressions are currently in the restricted form, allowing only simple
> > names, and it's up to you to propose and demonstrate the value of the
> > increased flexibility.
>
> I think we're allowed to discuss things in this group without them
> having to turn into formal proposals. Personally I've never written
> a Python assignment expression, and I think it'll be a few years
> before Python 3.8 is old enough for them to be conveniently usable.

Well, if you don't use them, then you don't really have a horse in
this race, so it doesn't matter. Someone who *does* want to make use
of them can read over that document etc etc, and demonstrate the value
of the proposal.

BTW, it doesn't have to be a "formal proposal" in any sense; it just
needs to be a logical and reasonable argument showing the value of the
improvement (or the problems with the status quo).

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
It seemed weird to me that only an identifier was allowed to be the
target of an assignment expression. Then it occurred to me that
function definitions are another place where only identifiers are
allowed, but where I could imagine an attributeref or a subscription
being used. E.g.

def table[i](x):
...

would mean the same thing as:

def _temp_(x):
...
table[i] = _temp_

I don't immediately see that this would screw up the grammar in any way,
so why not allow it? A `def` statement is just another form of
assignment, so just as for `:=` expressions, we should allow the target
to be as general as possible!

I'm guessing that about 70% of you will think that this is a horrible
idea, 10% of you will find it compelling, and the remaining 20% will
find themselves conflicted. You can count me in that last category...

--
Alan Bawden
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 23/10/2021 om 03:22 schreef Stefan Ram:
> Paulo da Silva <p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> writes:
>> Well, I didn't follow the discussion of this new feature, but the reason
>> I can see behind allowing it seems so valid for for ctr:=ctr-1 as for
>> self.ctr:=self.ctr-1. The kind of use is exactly the same. One is for a
>> normal function, the other for a method.
> The intention of the introduction of the assignment expression
> was to allow grab the values of subexpressions so as to be able
> to later use these value. This can be done with an identifier:
>
> if env_base := os.environ.get( "PYTHONUSERBASE", None ):
> return env_base
>
> . I am wondering what use cases are there for having something
> different than an identifier on the left side.

Well I have the following use case:

while (temp_result := calculate_next_couple(a, b))[1]:
a, b = temp_result
more calculations

Which IMO would be clearer if I could just write:

while ((a, b) := calculate_next_couple(a,b))[1]:
more calculations

Of course it would even more clear if I could write something like:

while (a, b) := calculate_next_couple(a, b); b:
more calculations

or

do:
a, b = calculate_next_couple(a, b)
while b:
more calculations

--
Antoon.

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Mon, Oct 25, 2021 at 2:13 AM Alan Bawden <alan@csail.mit.edu> wrote:
>
> It seemed weird to me that only an identifier was allowed to be the
> target of an assignment expression. Then it occurred to me that
> function definitions are another place where only identifiers are
> allowed, but where I could imagine an attributeref or a subscription
> being used. E.g.
>
> def table[i](x):
> ...
>
> would mean the same thing as:
>
> def _temp_(x):
> ...
> table[i] = _temp_
>
> I don't immediately see that this would screw up the grammar in any way,
> so why not allow it? A `def` statement is just another form of
> assignment, so just as for `:=` expressions, we should allow the target
> to be as general as possible!
>
> I'm guessing that about 70% of you will think that this is a horrible
> idea, 10% of you will find it compelling, and the remaining 20% will
> find themselves conflicted. You can count me in that last category...

This has come up periodically, but it's a bit tricky to define some of
the edge cases, like what the function's name should be. But it would
definitely help with building dispatch tables. Currently, I tend to
build them with a decorator:

tools = {}
def tool(f):
tools[f.__name__] = f
return f

@tool
def frobnicate(): ...

@tool
def spamify(): ...

In theory, it would be possible to do this:

def tools["frobnicate"](): ...

But I'm not sure that it's truly better.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
RE: New assignmens ... [ In reply to ]
No, many things need not be as general as possible once you consider how
much work it may take to develop code and how many bugs and oddities might
be introduced and even how much it may slow the interpreter.

I could make an argument that everywhere you can put in a character string
should also allow a regular expression but why? It makes no sense to allow
you to supply a filename to create using a regular expression as you are not
matching anything. Worse, perfectly valid string that may contain a dollar
sign or period or many other characters used in regular expression may
really be messed up if evaluated as a regular expression. So is it any
wonder NOBODY suggests the above be done?

As Chris has said, something was added to Python that is a partial
implementation. There are fairly reasonable ways to do additional things and
until recently, those were the proper and only way. But the recent change
does not preclude a later upgrade if anyone is not only convinced it is
worth doing but of higher priority than the scarce resources needed to do
lots of other worthy and requested things including fixing bugs.

I imagine you can create some fairly complex examples you can suggest should
be handled for generality including some very indirect references created
dynamically. The code to recognize any abstract use of symbols may not only
slow down every operation of even the simplest type but generate all kinds
of error messages nobody will understand, let alone translate into other
languages properly! Right now, it is simpler. An error message can say that
only certain simple usages are allowed.

Now if anyone wants to donate a few hundred thousand dollars if used to make
the change, or offer to do it free, who knows? Of course, this means anyone
using the feature may need to check your version of Python to see if the
feature exists before ...



-----Original Message-----
From: Python-list <python-list-bounces+avigross=verizon.net@python.org> On
Behalf Of Alan Bawden
Sent: Sunday, October 24, 2021 3:53 AM
To: python-list@python.org
Subject: Re: New assignmens ...

It seemed weird to me that only an identifier was allowed to be the target
of an assignment expression. Then it occurred to me that function
definitions are another place where only identifiers are allowed, but where
I could imagine an attributeref or a subscription being used. E.g.

def table[i](x):
...

would mean the same thing as:

def _temp_(x):
...
table[i] = _temp_

I don't immediately see that this would screw up the grammar in any way, so
why not allow it? A `def` statement is just another form of assignment, so
just as for `:=` expressions, we should allow the target to be as general as
possible!

I'm guessing that about 70% of you will think that this is a horrible idea,
10% of you will find it compelling, and the remaining 20% will find
themselves conflicted. You can count me in that last category...

--
Alan Bawden
--
https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On 25/10/2021 01:46, Avi Gross via Python-list wrote:
> No, many things need not be as general as possible once you consider how
> much work it may take to develop code and how many bugs and oddities might
> be introduced and even how much it may slow the interpreter.
...
> I imagine you can create some fairly complex examples you can suggest should
> be handled for generality including some very indirect references created
> dynamically. The code to recognize any abstract use of symbols may not only
> slow down every operation of even the simplest type but generate all kinds
> of error messages nobody will understand, let alone translate into other
> languages properly! Right now, it is simpler. An error message can say that
> only certain simple usages are allowed.

I don't consider this a strong argument. Limiting the scope of the walrus operator
will just force people organizing there code where they will use a normal assignment.
So the resulting code will not be faster, less complex or generate less error messages
because the complexity of the assignment that is needed is still the same.

Or you force people to be "creative" as follows:

Suppose I would like to write a loop as follows:

while ((a, b) := next_couple(a, b))[1]:
do needed calculations


What I can do is write it as follows:

while [tmp := next_couple(a,b), a := tmp[0], b := tmp[1]][-1]:
do needed calculations

I really don't see what is gained by "forcing" me to right the second code over the first.

--
Antoon Pardon

--
https://mail.python.org/mailman/listinfo/python-list
RE: New assignmens ... [ In reply to ]
Antoon,

Just to be clear. I am talking about a different measure of efficiency. If
you have code that handles a limited functionality properly it can be quite
simple. If you then expand the code to handle ever more situations, then it
may do things like a series of IF statements to determine which of many
things to do so it now takes a while to just reach the part that does the
most common case. I have seen people use code that knows what arguments to
expect and just does things simply, like adding two integers together. Then
the code is improved so it detects if either argument is floating point and
now does any needed conversions. Soon you add support for complex numbers or
character strings that look like "23" and then even parse "twelve dollars
and forty two cents" in English and then a few other languages. Next you
accept range objects and other things that make sense to add and accept an
undefined number of arguments and name the darn thing sum_everything() and
proudly show it off. It now has an amazing number of errors it can propagate
or warn about. But, you can still use it to add 2 and 2.

Now, yes, nobody needs a function to just add two numbers. If that bothers
you, make is add the absolute values or something a tad more interesting.
But the point is that any code that invokes sum_everything() may now pay a
penalty in terms of performance just in the beginning part where it tests
how many arguments it got, what types they are, and so on.

The topic here is the Python run-time parser though. It is reading your code
and doing whatever complex set of things it has to do to parse from a fairly
large set of possible valid programs as well as invalid ones. I have never
looked deeply at how it works but my guess is that somewhere in there are
concepts like:

simple_asignment_expression can look like THIS.
complex _assignment expression can look like simple_assignment_expression OR
THAT OR ...

So to parse code you often need to look at alternate ways of connecting
symbols and hopefully find the one and only way it has to be looked at.
Parentheses as an example have many possible meanings and you may not know
which meaning when you encounter it until you keep going and see where there
may be a matching one but ignore any within a character string. I won't go
on but the point is that the parser can jump through more hoops even in the
most usual cases when it has to look for new cases not originally designed
in.

Your argument that people using other techniques to get the functionality
they want is not really relevant as I do not deny it. My point is that the
most common ways NORMALLY used are the ones that drive the efficiency of a
system. So if adding functionality to include new cases/situations doubles
the time it takes to do the most common case and that is used 98% of the
time, then how much overall gain for the other 2% is needed to
counterbalance it?

I find a common pattern in software that often looks like extra layers
around a function call. There may be a function to create an object given a
character string argument like vector("integer", 1, 2, 3") or
vector("character", "a", "b") that lets you create all kinds of vectors.
Someone comes along with a bright idea to make programmers instead call
make_integer(1, 2, 3) and make_character("a", "b") and more like that. We
now have lots of new function that are just going to turn around and call
vector() with a different appropriate string as the first argument and pass
along the rest. We now have a function calling a second function. Yes, there
are many possible advantages here including ways to check if you are using
your code as intended. But there is overhead. And in a tight loop repeated
millions of times, can you blame a programmer who knows, if they just call
vector() directly, or perhaps a deeper function that vector() calls when it
knows it is using integers?

I will end with this. If someone wants to design a new language from scratch
and with a goal of starting with as general a set of concepts as they can,
fine. Design it carefully. Build it and if it works well enough, use it. But
to ask an existing language to add features or expand existing ones is not
at all the same thing and requires much more care. In python, you can find
areas that are a bit confusing such as how multiple inheritance in objects
is done. It can require some tweaking to make your objects in ways that the
right thing is inherited from the other objects the way you want if more
than one has the same method and you can have subtle errors. Arguably the
darn thing is too general and many other languages instead decide not to
support multiple inheritance and may use other interesting ways to get
similar functionality. But although this can be a very nice feature allowing
you to design quite sophisticated sets of objects that inherit all kinds of
nifty powers from other existing objects, it can be a drag on performance if
it does a search through a big mess to find the right function to call at
run time! Sometimes it may be easier to not use multiple inheritance in some
part of your code and use a work-around to get what you want.

I am not against extending Python in the direction someone wants. I am FOR
careful examination and study before making the change and weighing whether
this is likely to be more useful than other things being asked for and other
relative costs. Many things turn out not to be needed. I recall programs
designed to use every letter of the alphabet (and other symbols) whether
needed or not. I mean things like "d" for delete and "a" for add and "t" for
transpose. Just to be complete, make up something that "q" or "z" do. Why?
Not because anyone wants or needs those. I have seen projects like that then
take longer to create and harder to test and the users mostly thought it was
too complex and rarely or never used some functionality. I have made macros
that allow something in an emacs editor like transpose-letter and
transpose-word and continued with sentences, paragraphs, chapters and
something beyond like transpose-on-paste-buffers. But most people actually
just do a cut and move and paste operation for the more complex scenarios
even if they remember the fancy version exists and is bound to some
forgotten series of keys clicked together like control-X control-alt-t or
something.



-----Original Message-----
From: Python-list <python-list-bounces+avigross=verizon.net@python.org> On
Behalf Of Antoon Pardon
Sent: Monday, October 25, 2021 5:21 AM
To: python-list@python.org
Subject: Re: New assignmens ...

On 25/10/2021 01:46, Avi Gross via Python-list wrote:
> No, many things need not be as general as possible once you consider
> how much work it may take to develop code and how many bugs and
> oddities might be introduced and even how much it may slow the
interpreter.
...
> I imagine you can create some fairly complex examples you can suggest
> should be handled for generality including some very indirect
> references created dynamically. The code to recognize any abstract use
> of symbols may not only slow down every operation of even the simplest
> type but generate all kinds of error messages nobody will understand,
> let alone translate into other languages properly! Right now, it is
> simpler. An error message can say that only certain simple usages are
allowed.

I don't consider this a strong argument. Limiting the scope of the walrus
operator will just force people organizing there code where they will use a
normal assignment.
So the resulting code will not be faster, less complex or generate less
error messages because the complexity of the assignment that is needed is
still the same.

Or you force people to be "creative" as follows:

Suppose I would like to write a loop as follows:

while ((a, b) := next_couple(a, b))[1]:
do needed calculations


What I can do is write it as follows:

while [tmp := next_couple(a,b), a := tmp[0], b := tmp[1]][-1]:
do needed calculations

I really don't see what is gained by "forcing" me to right the second code
over the first.

--
Antoon Pardon

--
https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Message: 8
Date: Mon, 25 Oct 2021 11:20:52 +0200
From: Antoon Pardon <antoon.pardon@vub.be>
To: python-list@python.org
Subject: Re: New assignmens ...
Message-ID: <5761dd65-4e87-8b8c-1400-edb8212048db@vub.be>
Content-Type: text/plain; charset=utf-8; format=flowed
On 25/10/2021 11:20, Anton Pardon wrote:
> Suppose I would like to write a loop as follows:

> while ((a, b) := next_couple(a, b))[1]:
> do needed calculations


> What I can do is write it as follows:

> while [tmp := next_couple(a,b), a := tmp[0], b := tmp[1]][-1]:
> do needed calculations

> I really don't see what is gained by "forcing" me to right the second code over the first.

No, nobody is forcing you to right it the second way over the first.
Nobody is forcing you to use the walrus operator at all!

Instead, I would recommend something more like:

while b:
do needed calculations
(a,b) = next_couple(a,b)

This requires even less typing than what you had before!

But it also raises a whole lot of problems with this particular example:
-- neither a nor b is defined in your sample while loop. It seems you would
need to initialize a and b before your while loop (and mine)
-- is b truly a boolean value, or are you short-cutting some other value?
-- are a and b truly necessary parameters to next_couple, or are they just
there to remind the function of its previous return values?
If the latter, poerhaps you want a stream or list or something with yield

This example (and some of the others I have seen) just highlight how
programmers will take advantage of any new tool to help them write
worse code than if they did not have the tool. In my mind, the walrus
operator was designed to serve a particular niche case like this one:

while (x := input()) > 0:

where not having the operator required duplicating the input() operation
both before the loop and at the end of the loop -- or more complicated
cases where some additional operations had to be performed to get
that test value for the while condition (such as getting the b out of (a,b)).

But the walrus only adds a benefit if it is there to avoid the duplication
of the code that is used to obtain that test condition. This next_couple
example does not qualify, since apparently (a,b) are initialized by some
other means (and not be a call to next_couple with undefined values)

Or the other abuse I saw recently about using the walrus operator:

while (self.ctr := self.ctr-1) > 0:

-- there was no compelling reason for a loop counter to be a class variable
(anyone who peeks at this counter when the loop is down would only see a zero)
-- this requires self.ctr to be initialized to a value one higher than the first
meaningful value (start at 11 if you want to count down from 10)
So my recommended alternative, which furthermore also takes less typing:

while ctr > 0:
...
ctr = ctr-1

TL;DR: The Walrus operator serves the purpose as described in its PEP
just as it is, and I see no compelling reason to expand its use.
It is there to reduce code size by eliminating a duplication of code,
If the code you write using the walrus operator is longer or more
complicated than the code would be without it, you are misusing it.

Roger Christman
Pennsylvania State University
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Tue, Oct 26, 2021 at 3:07 AM Avi Gross via Python-list
<python-list@python.org> wrote:
> I will end with this. If someone wants to design a new language from scratch
> and with a goal of starting with as general a set of concepts as they can,
> fine. Design it carefully. Build it and if it works well enough, use it.

I'll add to this: Please do exactly that! It's a great mental
exercise. Sometimes you'll end up using it as a domain-specific
language, or maybe it'll become a sort of ersatz command interpreter,
or something; other times, you do the work of designing it purely for
the effect of trying it, and you've learned how languages work.

What you'll find is that there are extremes that are utterly and
completely useless, such as Turing tarpits (almost no language
facilities, but technically possible to write anything), or things so
generic that they are nothing more than containers ("a script in this
language is whatever code will make it happen"). In between, every
programming language has to make decisions. What are its goals? What
kinds of problems should be easy to solve in this language? Is it
meant to be general-purpose and able to do most things, or
special-purpose but extremely elegant within its domain?

And along the way, you'll gain a better appreciation for every
language you work with, plus a mental comprehension that lets you
understand WHY this language or that language is good for some task.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 25/10/2021 om 18:06 schreef Avi Gross via Python-list:
> Antoon,
>
> Just to be clear. I am talking about a different measure of efficiency.

No you are not.

>
> The topic here is the Python run-time parser though.

Yes and that is what I am talking about.

> It is reading your code
> and doing whatever complex set of things it has to do to parse from a fairly
> large set of possible valid programs as well as invalid ones. I have never
> looked deeply at how it works but my guess is that somewhere in there are
> concepts like:
>
> simple_asignment_expression can look like THIS.
> complex _assignment expression can look like simple_assignment_expression OR
> THAT OR ...
>
> So to parse code you often need to look at alternate ways of connecting
> symbols and hopefully find the one and only way it has to be looked at.
> Parentheses as an example have many possible meanings and you may not know
> which meaning when you encounter it until you keep going and see where there
> may be a matching one but ignore any within a character string. I won't go
> on but the point is that the parser can jump through more hoops even in the
> most usual cases when it has to look for new cases not originally designed
> in.

IMO that extra complexity is insignificant. You really don't reduce the complexity of your
parser much if you would limit it so that indexes can only be names so that the programmer
instead of being able to write:

var = tab[some expression]

is forced to write it as:

index = some expression
var = tab[index]

Because all that machinery to evaluate some expression needs to be there anyway.

In the same way we have already all the machinery present for assignments.

By putting limits on the walrus code, you are not reducing complexity, you are increasing it.
You are increasing complexity because you can't just reuse the code that handles an ordinary
assignment. You now need specific code to limit it's use.

--
Antoon Pardon.

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Tue, Oct 26, 2021 at 5:35 AM Antoon Pardon <antoon.pardon@vub.be> wrote:
> By putting limits on the walrus code, you are not reducing complexity, you are increasing it.
> You are increasing complexity because you can't just reuse the code that handles an ordinary
> assignment. You now need specific code to limit it's use.
>

What does this code do?

while x, y := foo():
...

Is it more complicated or less complicated when arbitrary assignment
targets are permitted?

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 25/10/2021 om 20:39 schreef Chris Angelico:
> On Tue, Oct 26, 2021 at 5:35 AM Antoon Pardon <antoon.pardon@vub.be> wrote:
>> By putting limits on the walrus code, you are not reducing complexity, you are increasing it.
>> You are increasing complexity because you can't just reuse the code that handles an ordinary
>> assignment. You now need specific code to limit it's use.
>>
> What does this code do?
>
> while x, y := foo():
> ...
>
> Is it more complicated or less complicated when arbitrary assignment
> targets are permitted?

Well I would guess it would do something similar to

while [x, y := foo()]:
...

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Tue, Oct 26, 2021 at 7:18 AM Antoon Pardon <antoon.pardon@vub.be> wrote:
>
> Op 25/10/2021 om 20:39 schreef Chris Angelico:
> > On Tue, Oct 26, 2021 at 5:35 AM Antoon Pardon <antoon.pardon@vub.be> wrote:
> >> By putting limits on the walrus code, you are not reducing complexity, you are increasing it.
> >> You are increasing complexity because you can't just reuse the code that handles an ordinary
> >> assignment. You now need specific code to limit it's use.
> >>
> > What does this code do?
> >
> > while x, y := foo():
> > ...
> >
> > Is it more complicated or less complicated when arbitrary assignment
> > targets are permitted?
>
> Well I would guess it would do something similar to
>
> while [x, y := foo()]:
> ...
>

And does it unpack what foo returns?

Should it?

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
RE: New assignmens ... [ In reply to ]
We have had discussions debating if Python is a good language for teaching.
The short answer is NO unless you only teach a small subset and the students
know there is more they can learn as needed. The language is too rich and
has too many ways to do seemingly anything and that is before you add more
functionality. But that can make it a great language for developers.

Assignments in middle of expressions are often syntactic sugar that may be
re-arranged internally to similar code than what could be done other ways
without it. It can lead to ambiguities. And it can make it harder for anyone
other than the programmer that wrote it (or them a day later) to understand.

So, while we are at it, why not add the ++ and --- operators that were
deliberately NOT included in Python? Why not throw back pointers?

The short answer is that there are plenty of programming languages to choose
from and some of those do have the features you want and some do not want
them. Sure, you might push in what you want but have you considered all the
places it might be tried? Can you do it in a comprehension where an
assignment is implicitly being done?

[ var := 5 in range(10) ]

The old adage is that some people will be given a finger and take a hand. I
had NOTHING to do with the process but others here know more. Chris suggests
that there was a compromise of sorts here and a choice to implement a
limited subset of fuller functionality for NOW without ruling out doing some
more later. So those wanting more, feel free to petition for it as an
ADDITION but I suggest a more polite tone than trying to say the people who
did it were idiots who did it badly.

Personally, I don't care what is done and suspect I will rarely feel much
need to use the current walrus operator, let alone an enhanced Odobenus
rosmarus operator like ::== ...

-----Original Message-----
From: Python-list <python-list-bounces+avigross=verizon.net@python.org> On
Behalf Of Christman, Roger Graydon
Sent: Monday, October 25, 2021 12:48 PM
To: python-list@python.org
Subject: Re: New assignmens ...

Message: 8
Date: Mon, 25 Oct 2021 11:20:52 +0200
From: Antoon Pardon <antoon.pardon@vub.be>
To: python-list@python.org
Subject: Re: New assignmens ...
Message-ID: <5761dd65-4e87-8b8c-1400-edb8212048db@vub.be>
Content-Type: text/plain; charset=utf-8; format=flowed On 25/10/2021 11:20,
Anton Pardon wrote:
> Suppose I would like to write a loop as follows:

> while ((a, b) := next_couple(a, b))[1]:
> do needed calculations


> What I can do is write it as follows:

> while [tmp := next_couple(a,b), a := tmp[0], b := tmp[1]][-1]:
> do needed calculations

> I really don't see what is gained by "forcing" me to right the second code
over the first.

No, nobody is forcing you to right it the second way over the first.
Nobody is forcing you to use the walrus operator at all!

Instead, I would recommend something more like:

while b:
do needed calculations
(a,b) = next_couple(a,b)

This requires even less typing than what you had before!

But it also raises a whole lot of problems with this particular example:
-- neither a nor b is defined in your sample while loop. It seems you
would
need to initialize a and b before your while loop (and mine)
-- is b truly a boolean value, or are you short-cutting some other value?
-- are a and b truly necessary parameters to next_couple, or are they just
there to remind the function of its previous return values?
If the latter, poerhaps you want a stream or list or something with
yield

This example (and some of the others I have seen) just highlight how
programmers will take advantage of any new tool to help them write
worse code than if they did not have the tool. In my mind, the walrus
operator was designed to serve a particular niche case like this one:

while (x := input()) > 0:

where not having the operator required duplicating the input() operation
both before the loop and at the end of the loop -- or more complicated
cases where some additional operations had to be performed to get that test
value for the while condition (such as getting the b out of (a,b)).

But the walrus only adds a benefit if it is there to avoid the duplication
of the code that is used to obtain that test condition. This next_couple
example does not qualify, since apparently (a,b) are initialized by some
other means (and not be a call to next_couple with undefined values)

Or the other abuse I saw recently about using the walrus operator:

while (self.ctr := self.ctr-1) > 0:

-- there was no compelling reason for a loop counter to be a class variable
(anyone who peeks at this counter when the loop is down would only see a
zero)
-- this requires self.ctr to be initialized to a value one higher than the
first meaningful value (start at 11 if you want to count down from 10) So my
recommended alternative, which furthermore also takes less typing:

while ctr > 0:
...
ctr = ctr-1

TL;DR: The Walrus operator serves the purpose as described in its PEP
just as it is, and I see no compelling reason to expand its use.
It is there to reduce code size by eliminating a duplication of code, If the
code you write using the walrus operator is longer or more complicated than
the code would be without it, you are misusing it.

Roger Christman
Pennsylvania State University
--
https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Tue, Oct 26, 2021 at 8:42 AM Avi Gross via Python-list
<python-list@python.org> wrote:
> Personally, I don't care what is done and suspect I will rarely feel much
> need to use the current walrus operator, let alone an enhanced Odobenus
> rosmarus operator like ::== ...
>

..... wait what?

Ah. Had to look that one up. :)

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On 26/10/2021 10.45, Chris Angelico wrote:
> On Tue, Oct 26, 2021 at 8:42 AM Avi Gross via Python-list
> <python-list@python.org> wrote:
>> Personally, I don't care what is done and suspect I will rarely feel much
>> need to use the current walrus operator, let alone an enhanced Odobenus
>> rosmarus operator like ::== ...
>>
>
> ..... wait what?
>
> Ah. Had to look that one up. :)


Each year I assist friends who own one of local orchards, at harvest
time. I usually run the sealing machine, to preserve fruit which will be
transported refrigerated. It is such a novelty to be asked to fill-out
a time-sheet. Under "name" it asks for "position", so I entered
"Erignathus barbatus" (bearded seal), which caused similar
consternation, and for some days, until someone thought to look it up...


Back on-topic, I am slightly curious:-

aside from 'starting small' with an option to widen/'open-up' later, is
there a particular reason why 'the walrus' has not been made available
(could not be ...?) for use with object-attributes?
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Tue, Oct 26, 2021 at 9:19 AM dn via Python-list
<python-list@python.org> wrote:
> Back on-topic, I am slightly curious:-
>
> aside from 'starting small' with an option to widen/'open-up' later, is
> there a particular reason why 'the walrus' has not been made available
> (could not be ...?) for use with object-attributes?

I can't think of any other reasons. But the one you cite is quite an
important one. In order to get real-world usage examples, the feature
was rolled out in the restricted form, because threads like this are
*exactly* how the value can be judged. So I do not in any way regret
that assignment expressions were accepted in their current form, but
also, don't be afraid to propose an opening up of the syntax. Be
specific, and cite usage examples that would benefit.

TBH, I don't think there's a lot of value in multiple-assignment,
since it has a number of annoying conflicts of syntax and few viable
use-cases. But if you have great examples of "x.y :=" or "x[y] :=",
then by all means, post on python-ideas to propose widening the scope.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
RE: New assignmens ... [ In reply to ]
Stefan,

Yes, I often pass even fairly trivial functions like "add" or "+" or
whatever the language makes me say, to other functions in various forms of
functional programing. My point is that my example may seem trivial and not
necessary as an EXAMPLE of the greater point that may be easier to
understand than something complex. A sum() is often a generalization of
adding two things by allowing a second addition to the sub-sum and so on.
But in a straightforward program where I am asking to add exactly two
things, few would use sum(a,b) versus just a+b. On the other hand, in
agreement with you, if I have two vectors or matrices or some other such
data holder and I want to add each position to a corresponding position,
then some kind of call to a function where I pass the two objects and the
name of a function that adds two things, is a decent way to go. But it need
not be a souped-up generalized_sum() function when a simple one will do and
be faster when invoked so many times.

And note often what is used is a temporary lambda anonymous function that
may look like \(x,y) x+y ... or whatever syntax your language uses.


-----Original Message-----
From: Python-list <python-list-bounces+avigross=verizon.net@python.org> On
Behalf Of Stefan Ram
Sent: Monday, October 25, 2021 12:57 PM
To: python-list@python.org
Subject: Re: New assignmens ...

"Avi Gross" <avigross@verizon.net> writes:
>Now, yes, nobody needs a function to just add two numbers.

If one uses a framework like "functools.reduce", the only
way to reduce an iterable to its sum, is to do just that:
Write a function to add two numbers.

Of course, one can circumvent "functools.reduce" (or use
"operator.add"), but in other cases there are frameworks
that need to be used and where one sometimes does need to
write functions (callbacks) as simple as "lambda: None".


--
https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 25/10/2021 om 23:03 schreef Chris Angelico:
> On Tue, Oct 26, 2021 at 7:18 AM Antoon Pardon <antoon.pardon@vub.be> wrote:
>> Op 25/10/2021 om 20:39 schreef Chris Angelico:
>>> On Tue, Oct 26, 2021 at 5:35 AM Antoon Pardon <antoon.pardon@vub.be> wrote:
>>>> By putting limits on the walrus code, you are not reducing complexity, you are increasing it.
>>>> You are increasing complexity because you can't just reuse the code that handles an ordinary
>>>> assignment. You now need specific code to limit it's use.
>>>>
>>> What does this code do?
>>>
>>> while x, y := foo():
>>> ...
>>>
>>> Is it more complicated or less complicated when arbitrary assignment
>>> targets are permitted?
>> Well I would guess it would do something similar to
>>
>> while [x, y := foo()]:
>> ...
>>
> And does it unpack what foo returns?
>
> Should it?

1) No it doesn't.

2) I don't care. This is IMO not a question of what should or should not, but just a
question of deciding how you want to treat this. I guess that since it doesn't unpack
already, this behaviour is more or less fixed for futere releases. Should the python
developers in the future decide that de walrus operator can unpack things. The above
code will not unpack in order to not break already existing code and if you want
to unpack one will have to write something like:

while [(x, y) := foo()]:
...

But the answer to that second question has very little relevance to how complicated the
parser will be. It is just deciding which of , or := has a higher precedence. Since that
decision has already been more or less made, there is not much to decide here either.

--
Antoon Pardon.

--
https://mail.python.org/mailman/listinfo/python-list
RE: New assignmens ... [ In reply to ]
Why force unpacking? Why not assign a tuple? That would look like a simple assignment: x := (alpha, beta, gamma)
And you could access x[0], x[1] and x[2].

I think asking := to support x, y := alpha, beta is a request to address an unnecessary, easily worked around, issue. And as previously pointed out you can still just use = .

--- Joseph S.


Teledyne Confidential; Commercially Sensitive Business Data

-----Original Message-----
From: Chris Angelico <rosuav@gmail.com>
Sent: Monday, October 25, 2021 6:25 PM
To: Python <python-list@python.org>
Subject: Re: New assignmens ...

On Tue, Oct 26, 2021 at 9:19 AM dn via Python-list <python-list@python.org> wrote:
> Back on-topic, I am slightly curious:-
>
> aside from 'starting small' with an option to widen/'open-up' later,
> is there a particular reason why 'the walrus' has not been made
> available (could not be ...?) for use with object-attributes?

I can't think of any other reasons. But the one you cite is quite an important one. In order to get real-world usage examples, the feature was rolled out in the restricted form, because threads like this are
*exactly* how the value can be judged. So I do not in any way regret that assignment expressions were accepted in their current form, but also, don't be afraid to propose an opening up of the syntax. Be specific, and cite usage examples that would benefit.

TBH, I don't think there's a lot of value in multiple-assignment, since it has a number of annoying conflicts of syntax and few viable use-cases. But if you have great examples of "x.y :=" or "x[y] :=", then by all means, post on python-ideas to propose widening the scope.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 25/10/2021 om 18:47 schreef Christman, Roger Graydon:
> Message: 8
> Date: Mon, 25 Oct 2021 11:20:52 +0200
> From: Antoon Pardon <antoon.pardon@vub.be>
> To: python-list@python.org
> Subject: Re: New assignmens ...
> Message-ID: <5761dd65-4e87-8b8c-1400-edb8212048db@vub.be>
> Content-Type: text/plain; charset=utf-8; format=flowed
> On 25/10/2021 11:20, Anton Pardon wrote:
>> Suppose I would like to write a loop as follows:
> > while ((a, b) := next_couple(a, b))[1]:
> > do needed calculations
>
>
>> What I can do is write it as follows:
>> while [tmp := next_couple(a,b), a := tmp[0], b := tmp[1]][-1]:
> > do needed calculations
>
>> I really don't see what is gained by "forcing" me to right the second code over the first.
> No, nobody is forcing you to right it the second way over the first.
> Nobody is forcing you to use the walrus operator at all!
>
> Instead, I would recommend something more like:
>
> while b:
> do needed calculations
> (a,b) = next_couple(a,b)

But AIU the walrus operator was introduced so we no longer needed, to write such code,
with the calculation of the next candidate at the bottom and the test at the top.
You just confirmed the walrus operator is not very useful once the next candidate is
no longer just a name.

--
Antoon.

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 26/10/2021 om 19:46 schreef Schachner, Joseph:
> Why force unpacking? Why not assign a tuple? That would look like a simple assignment: x := (alpha, beta, gamma)
> And you could access x[0], x[1] and x[2].
>
> I think asking := to support x, y := alpha, beta is a request to address an unnecessary, easily worked around, issue. And as previously pointed out you can still just use = .

Because the names usually have meaning, while the tuple has not.

And you just confirmed my point that the walrus operator isn't very useful here
by suggesting that I should abandon it and use an assignment.

--
Antoon Pardon.

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 26/10/2021 om 00:24 schreef Chris Angelico:
> TBH, I don't think there's a lot of value in multiple-assignment,
> since it has a number of annoying conflicts of syntax and few viable
> use-cases. But if you have great examples of "x.y :=" or "x[y] :=",
> then by all means, post on python-ideas to propose widening the scope.

I think you should seperate the costs from the benefits. It is not because
the costs can be high there is little value.

And how do you count use cases? What about the following pattern:

while (a, b) := next_couple(a,b)[-1]:
...

Is that one use case or is that a use case for each kind of couple?

And even if the benefits are little per case, they can add up with every
occasion such a case pops up.

--
Antoon Pardon.

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Wed, Oct 27, 2021 at 6:00 PM Antoon Pardon <antoon.pardon@vub.be> wrote:
>
>
>
> Op 26/10/2021 om 00:24 schreef Chris Angelico:
> > TBH, I don't think there's a lot of value in multiple-assignment,
> > since it has a number of annoying conflicts of syntax and few viable
> > use-cases. But if you have great examples of "x.y :=" or "x[y] :=",
> > then by all means, post on python-ideas to propose widening the scope.
>
> I think you should seperate the costs from the benefits. It is not because
> the costs can be high there is little value.
>
> And how do you count use cases? What about the following pattern:
>
> while (a, b) := next_couple(a,b)[-1]:
> ...
>
> Is that one use case or is that a use case for each kind of couple?
>
> And even if the benefits are little per case, they can add up with every
> occasion such a case pops up.
>

I'm not sure that it's much of a use-case; isn't it an infinite loop as written?

And that's the problem. With multiple-assignment, the overall value is
going to be the tuple, so you then have to add extra parentheses and
subscripting to get what you want to check. That makes it far less
clean, far less tempting, far less valuable. You have to parenthesize
the assignment target (otherwise it'll build a tuple out of one value
and the assigned target), then parenthesize again, and subscript at
the end.

So if you want this added, show a use-case that makes it look way
better than the alternatives (including a generator, a mid-loop break,
etc).

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 27/10/2021 om 10:05 schreef Chris Angelico:
> On Wed, Oct 27, 2021 at 6:00 PM Antoon Pardon <antoon.pardon@vub.be> wrote:
>>
>>
>> Op 26/10/2021 om 00:24 schreef Chris Angelico:
>>> TBH, I don't think there's a lot of value in multiple-assignment,
>>> since it has a number of annoying conflicts of syntax and few viable
>>> use-cases. But if you have great examples of "x.y :=" or "x[y] :=",
>>> then by all means, post on python-ideas to propose widening the scope.
>> I think you should seperate the costs from the benefits. It is not because
>> the costs can be high there is little value.
>>
>> And how do you count use cases? What about the following pattern:
>>
>> while (a, b) := next_couple(a,b)[-1]:
>> ...
>>
>> Is that one use case or is that a use case for each kind of couple?
>>
>> And even if the benefits are little per case, they can add up with every
>> occasion such a case pops up.
>>
> I'm not sure that it's much of a use-case; isn't it an infinite loop as written?

>
> And that's the problem. With multiple-assignment, the overall value is
> going to be the tuple, so you then have to add extra parentheses and
> subscripting to get what you want to check. That makes it far less
> clean, far less tempting, far less valuable. You have to parenthesize
> the assignment target (otherwise it'll build a tuple out of one value
> and the assigned target), then parenthesize again, and subscript at
> the end.
>
> So if you want this added, show a use-case that makes it look way
> better than the alternatives (including a generator, a mid-loop break,
> etc).
>
> ChrisA

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On 24/10/2021 22.23, O365 Dict wrote:
> Well I have the following use case:
>
> while (temp_result := calculate_next_couple(a, b))[1]:
> a, b = temp_result
> more calculations
>
> Which IMO would be clearer if I could just write:
>
> while ((a, b) := calculate_next_couple(a,b))[1]:
> more calculations
>
> Of course it would even more clear if I could write something like:
>
> while (a, b) := calculate_next_couple(a, b); b:
> more calculations
>
> or
>
> do:
> a, b = calculate_next_couple(a, b)
> while b:
> more calculations


Found (all of) the above less-than-obvious to read. Putting it in front
of trainees this morning caused only confusion - even the
currently-legal variation.


Accordingly: is this a job for the walrus operator at all? Let's "talk
of many [other] things"*.


Is this an algorithmic complexity, or a complicated way to look at (and
manipulate) data?

Well, judging from the code (above), use of the walrus certainly
presumes the former. Instead let's review any possibility of the latter
(if only for academic interest)...


What do we want out of the first line? (in no particular order)

1 use calculate_next_couple() to compute (new) a from an (old) a and b
2 use calculate_next_couple() to compute (new) b from an (old) a and b
3 use (new) b to decide if the loop should execute or terminate

The 'problem' then, has been phrased as these three objectives ask too
much of the (current implementation of the) walrus-operator.


NB after one (or more) cycles, when the loop 'returns to the top', what
I've termed 'new' a and b (above), will become (my reference) the 'old'
pair/tuple.


That all looks simple. What is dn complaining about?


Could we use a data structure to continue to keep things straight-forward?

class my_class():
def __init__( self, a, b )->None;
self.a = a
self.b = b

instance = my_class( a, b )


Sorry, you're probably becoming impatient with me. Surely I'm typing
more code than necessary? Maybe, but there are other measures of
code-quality/good-practice/etc, and there's likely more to 'it' than
just these few lines...


First consideration: the algorithm needs us to 'feed' the
while-condition. So let's flesh-out:

def is_more( self )->bool:
# you know what goes here - I don't, but that's not the issue
# the return value is all that matters
return is_there_any_more_data_to_calculate?

In which case, the loop becomes:

while instance.is_more():
more calculations

and 'readability' improves immeasurably!

NB for extra credit, turn the boolean function into a "property", and be
able to omit the (unsightly?) parentheses from the 'call'!


But, not so fast - what about the calculation itself, currently embedded
in calculate_next_couple()?

Well, those details are out of my sight, and I'm assuming include
reasonable complexity - otherwise you wouldn't propose this as a
good-example. Allow me to muddle-through with:

def calculate_next_couple( self )->None:
self.a = calculation of 'new' a
self.b = calculation of 'new' b

To avoid an 'extra' call against the instance from the while-loop,
execute the 'calculate' method from either __init__() or is_more(), as
appropriate (given that it likely needs to precede the return from the
latter - particularly if the computation is 'expensive'). The choice may
be subject-dependent ...


Now within "more calculations", one assumes, references to "a" and "b"
will need to be amended to become 'instance.a' and 'instance.b'. More
typing! What about preserving our fingers?


Readability will further improve when "a" and "b" (etc) are replaced by
'real names'.

The processing steps within "more calculations" could be reviewed. Some
may be candidates for inclusion as my_class methods - which would even
enable further simplifications and/or encapsulation of code-suites
relevant to the application, and/or "a" and "b" and the processes around
them.

If the "calculation" of 'next_couple' currently involves looking-up
another data-structure, eg a list of data-points, then combining such
with/into my_class may well yield further simplifications,
encapsulations, and benefits - but all in-theory and complete ignorance
of your application...


Hope the above gives you some ideas/pause for thought!


* this gratuitous and somewhat awkward expression is me claiming to be
clever by quoting Lewis Carroll - if he isn't sick of me
baiting-the-hook, it might earn extra brownie-points (or another groan)
from @Chris...
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 27/10/2021 om 10:05 schreef Chris Angelico:
> On Wed, Oct 27, 2021 at 6:00 PM Antoon Pardon <antoon.pardon@vub.be> wrote:
>>
>>
>> Op 26/10/2021 om 00:24 schreef Chris Angelico:
>>> TBH, I don't think there's a lot of value in multiple-assignment,
>>> since it has a number of annoying conflicts of syntax and few viable
>>> use-cases. But if you have great examples of "x.y :=" or "x[y] :=",
>>> then by all means, post on python-ideas to propose widening the scope.
>> I think you should seperate the costs from the benefits. It is not because
>> the costs can be high there is little value.
>>
>> And how do you count use cases? What about the following pattern:
>>
>> while (a, b) := next_couple(a,b)[-1]:
>> ...
>>
>> Is that one use case or is that a use case for each kind of couple?
>>
>> And even if the benefits are little per case, they can add up with every
>> occasion such a case pops up.
>>
> I'm not sure that it's much of a use-case; isn't it an infinite loop as written?
>
> And that's the problem. With multiple-assignment, the overall value is
> going to be the tuple, so you then have to add extra parentheses and
> subscripting to get what you want to check. That makes it far less
> clean, far less tempting, far less valuable. You have to parenthesize
> the assignment target (otherwise it'll build a tuple out of one value
> and the assigned target), then parenthesize again, and subscript at
> the end.

That is only a problem if you want to consider it one. This wouldn't be the
only place in python where you have to be careful with parentheses. IMO it
should be the responsibility of each programmer to decide which way to
program will be most clean. Maybe you are completly right and at the
same time it could still be more clean than the other possibilitie python
allows.

> So if you want this added, show a use-case that makes it look way
> better than the alternatives (including a generator, a mid-loop break,
> etc).

Way better according to which criteria? IMO to realy make something like
this you would need a one and a half loop. But although at some time there
was a strong indication it would get included, the idea was eventually discarted.

So I'll argue for incremental better if I see a possibility. A few incremental
betters can eventually result in something that is way better than the original.

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Wed, Oct 27, 2021 at 7:46 PM Antoon Pardon <antoon.pardon@vub.be> wrote:
> > So if you want this added, show a use-case that makes it look way
> > better than the alternatives (including a generator, a mid-loop break,
> > etc).
>
> Way better according to which criteria? IMO to realy make something like
> this you would need a one and a half loop. But although at some time there
> was a strong indication it would get included, the idea was eventually discarted.
>
> So I'll argue for incremental better if I see a possibility. A few incremental
> betters can eventually result in something that is way better than the original.

According to any criteria you like. Remember, the onus is not on the
status quo to justify itself; the onus is on someone who wants to make
a change.

Demonstrate that a change is needed by showing the benefits.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Wed, Oct 27, 2021 at 7:39 PM dn via Python-list
<python-list@python.org> wrote:
> Accordingly: is this a job for the walrus operator at all? Let's "talk
> of many [other] things"*.

+1

> Could we use a data structure to continue to keep things straight-forward?
>
> class my_class():
> def __init__( self, a, b )->None;
> self.a = a
> self.b = b
>
> instance = my_class( a, b )
>
>
> Sorry, you're probably becoming impatient with me. Surely I'm typing
> more code than necessary? Maybe, but there are other measures of
> code-quality/good-practice/etc, and there's likely more to 'it' than
> just these few lines...
>
>
> First consideration: the algorithm needs us to 'feed' the
> while-condition. So let's flesh-out:
>
> def is_more( self )->bool:
> # you know what goes here - I don't, but that's not the issue
> # the return value is all that matters
> return is_there_any_more_data_to_calculate?
>
> In which case, the loop becomes:
>
> while instance.is_more():
> more calculations
>
> and 'readability' improves immeasurably!

I'd be inclined to write all of this as a generator function, yielding
a series of tuples, but YMMV.

> * this gratuitous and somewhat awkward expression is me claiming to be
> clever by quoting Lewis Carroll - if he isn't sick of me
> baiting-the-hook, it might earn extra brownie-points (or another groan)
> from @Chris...

Given that you were talking about a walrus, I think it was quite apt :)

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 27/10/2021 om 10:38 schreef dn via Python-list:
> On 24/10/2021 22.23, O365 Dict wrote:
>> Well I have the following use case:
>>
>> while (temp_result := calculate_next_couple(a, b))[1]:
>> a, b = temp_result
>> more calculations
>>
>> Which IMO would be clearer if I could just write:
>>
>> while ((a, b) := calculate_next_couple(a,b))[1]:
>> more calculations
>>
>> Of course it would even more clear if I could write something like:
>>
>> while (a, b) := calculate_next_couple(a, b); b:
>> more calculations
>>
>> or
>>
>> do:
>> a, b = calculate_next_couple(a, b)
>> while b:
>> more calculations
>
> Found (all of) the above less-than-obvious to read. Putting it in front
> of trainees this morning caused only confusion - even the
> currently-legal variation.

A lot of python idioms are less than obvious for trainees when they first
encounter them. I don't think "Is obvious for trainess" is a good measure
to evaluate possible future programming constructs.

> Accordingly: is this a job for the walrus operator at all? Let's "talk
> of many [other] things"*.
>
> ...
>
>
> That all looks simple. What is dn complaining about?
>
>
> Could we use a data structure to continue to keep things straight-forward?

Yes off course we could. Before the walrus operator was introduced, we could
also introduce extra code so that we wouldn't need the walrus operator at all.


> ...
> Hope the above gives you some ideas/pause for thought!

No they don't. You have taken an example to illustrate an idea and
treated it as if it was some production code you had to review.

What you are suggesting boils downto that if one has a loop in which
one has two work variables, with a condition on those variable to
control a loop. In order to make use of the walrus operator we should
combine those two work variables into some kind of instance no matter
how contrived.

--
Antoon Pardon.


--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 27/10/2021 om 10:49 schreef Chris Angelico:
> On Wed, Oct 27, 2021 at 7:46 PM Antoon Pardon <antoon.pardon@vub.be> wrote:
>>> So if you want this added, show a use-case that makes it look way
>>> better than the alternatives (including a generator, a mid-loop break,
>>> etc).
>> Way better according to which criteria? IMO to realy make something like
>> this you would need a one and a half loop. But although at some time there
>> was a strong indication it would get included, the idea was eventually discarted.
>>
>> So I'll argue for incremental better if I see a possibility. A few incremental
>> betters can eventually result in something that is way better than the original.
> According to any criteria you like. Remember, the onus is not on the
> status quo to justify itself; the onus is on someone who wants to make
> a change.

Then don't answer that I can justify it according to any criteria I like.
It will have to be done according to criteria that are important to the
people who like the status quo. That it will be justified according to
criteria I like, will be totally unimportant.

> Demonstrate that a change is needed by showing the benefits.

Nothing is needed. But the walrus operator wasn't needed either. Asking to
show something is needed is putting a burden on who wants to advocate for
this, that isn't put on others.

--
Antoon Pardon.

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On 2021-10-27 19:05:52 +1100, Chris Angelico wrote:
> On Wed, Oct 27, 2021 at 6:00 PM Antoon Pardon <antoon.pardon@vub.be> wrote:
> > while (a, b) := next_couple(a,b)[-1]:
> > ...
[...]

> I'm not sure that it's much of a use-case; isn't it an infinite loop as written?
>
> And that's the problem. With multiple-assignment, the overall value is
> going to be the tuple, so you then have to add extra parentheses and
> subscripting to get what you want to check.

Right. I think for that you would want something like what Go does in
if:

if [assignment-statement ;] condition {
statements
}

Then you could write

while a, b = next_couple(a,b); b:
...

That doesn't even need the walrus operator.

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
Re: New assignmens ... [ In reply to ]
On 2021-10-24 11:23:48 +0200, O365 Dict wrote:
> do:
> a, b = calculate_next_couple(a, b)
> while b:
> more calculations

I actually like that syntax.

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
Re: New assignmens ... [ In reply to ]
On Wed, Oct 27, 2021 at 8:20 PM Antoon Pardon <antoon.pardon@vub.be> wrote:
>
>
>
> Op 27/10/2021 om 10:49 schreef Chris Angelico:
> > On Wed, Oct 27, 2021 at 7:46 PM Antoon Pardon <antoon.pardon@vub.be> wrote:
> >>> So if you want this added, show a use-case that makes it look way
> >>> better than the alternatives (including a generator, a mid-loop break,
> >>> etc).
> >> Way better according to which criteria? IMO to realy make something like
> >> this you would need a one and a half loop. But although at some time there
> >> was a strong indication it would get included, the idea was eventually discarted.
> >>
> >> So I'll argue for incremental better if I see a possibility. A few incremental
> >> betters can eventually result in something that is way better than the original.
> > According to any criteria you like. Remember, the onus is not on the
> > status quo to justify itself; the onus is on someone who wants to make
> > a change.
>
> Then don't answer that I can justify it according to any criteria I like.
> It will have to be done according to criteria that are important to the
> people who like the status quo. That it will be justified according to
> criteria I like, will be totally unimportant.
>
> > Demonstrate that a change is needed by showing the benefits.
>
> Nothing is needed. But the walrus operator wasn't needed either. Asking to
> show something is needed is putting a burden on who wants to advocate for
> this, that isn't put on others.
>

You can argue the word "need" all you like, but the fact remains that
YOU want a change, so YOU have to convince people of the benefits.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 27/10/2021 om 11:59 schreef Chris Angelico:
> You can argue the word "need" all you like, but the fact remains that
> YOU want a change, so YOU have to convince people of the benefits.

That is true. But there is nothing wrong in asking what might convince
people.

But I'll give you my thought below and you can decide in how far this
is convincing to you.

I regularly come with a problem for which a one and a half loop is very
suited to solve it. Unfortunately python doesn't have a one and a half
loop. However with the introduction of the walrus operator there is a
way to simulate a significant number of one and a half loops.

Consider the following:

do
a = expr1
b = expr2
while 2 * a > b:
more calculations

We could write that now as

while [.
a := expr1,
b := expr2,
2 * a > b][-1]:
more calculations

Now there is some ugly side on the above and it may not be obvious at first
what is going on, but once you understand it is a rather easy idiom. I certainly
prefer it over writing something like

while True:
a = expr1
b = expr2
if not (2 * a > b):
break
more calculations.

So for me any limitation on the walrus operator that is removed is a plus because
it will allow me to write more one and a half loops in more natural way.

Off course should the python developers decide to intoduce a real one and a half
loop all the above is probably a whole let useful.

--
Antoon Pardon

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On 27/10/2021 8:28, Anton Pardon wrote:
>>> Suppose I would like to write a loop as follows:
>>. > while ((a, b) := next_couple(a, b))[1]:
>> > do needed calculations
>>
>>
>>> What I can do is write it as follows:
>>> while [tmp := next_couple(a,b), a := tmp[0], b := tmp[1]][-1]:
>> > do needed calculations
>>
>>> I really don't see what is gained by "forcing" me to right the second code over the first.
>> No, nobody is forcing you to write it the second way over the first.
>> Nobody is forcing you to use the walrus operator at all!
>>
>> Instead, I would recommend something more like:
>>
>> while b:
>> do needed calculations
>> (a,b) = next_couple(a,b)

> But AIU the walrus operator was introduced so we no longer needed, to write such code,
> with the calculation of the next candidate at the bottom and the test at the top.
> You just confirmed the walrus operator is not very useful once the next candidate is
> no longer just a name.

I must disagree with the first sentence here regarding why the walrus operator was introduced.
I read through the PEP, and saw nothing about that in the Rationale. I do see the loop-and-a-half
example, but that actually had its next candidate value near the top (just before a break).

I'm going to provide two loop-and-a-half segments to illustrate my interpretation
of this PEP and the purpose of the walrus operator:

Without the walrus:

total = 0
value = input()
while value >= 0:
total += value
value = input()
print(total)

With the walrus:

total = 0
while (value := input()) > 0:
total += value
print(total)

In terms of the PEP -- I want to compare each input value to 0 for the loop test,
but I also want to preserve that value, to add to the total. There is a subexpression
(input()) within a larger expression (compared to 0) that I wish to name for reuse.

Now contrast with this example:

Without the walrus:

replay = True
while replay:
play_game()
replay = input("Play again? ") in ['y','Y','yes','Yes']

(I think it silly to ask about playing again at first).

With the walrus:

replay = None
while replay==None or (replay := input("Play again? ") in ['y','Y','yes','Yes']:
play_game()

To use the walrus operator here, I have to fabricate a value that would
allow me to bypass the input operation, that cannot be otherwise produced.
I do not find this second version any clearer or more intuitive than the first
(and the PEP did emphasize the value of clarity).

Now reading this in terms of the PEP, where I subexpression (the input)
in a larger expression (seeing if it is the list), I do not really seem to have
a compelling reason to name the value of that subexpression, since I am
not using it for any other purpose, so I could keep the input in the while
condition without using the walrus operator:

first_play = True
while first_play or input("Play again? ") in ['y','Y','yes','Yes']:
play_game()
first_play = False

I do not find this particularly clearer or better than my first version
with the test at the bottom, again since it requires me to do some extra
machinery to avoid the undesired input before the first repetition.
But I might also still argue that this is a little bit clearer than the
walrus alternative above.

My claim from these two examples is that the walrus is helpful to
reduce duplicating or recomputing subexpressions, not simply just
to facilitate code movement. It is not at all useful for a while loop
condition if the subexpression you wish to evaluate depends on
whether or not this is the first iteration of the loop.

Which then gets me back to your own illustrated use-case for
which I had raised a few questions/objections to before:

while ((a, b) := next_couple(a, b))[1]:
do needed calculations

What is the name of the value you wish to test? b
What is this actually testing? element [1] of a tuple

So already the code is unclear (and was made worse
when you said the existing walrus operator forced you
to make a list of three elements, two assigned with the
walrus, and then using a subscript of [-1] to get what you wanted.
My proposed solution explicitly tested b, since that
seemed to be what was of interest:

while b:
do needed calculations
(a,b) = next_couple(a,b)

To which you had replied:
> But AIU the walrus operator was introduced so we no longer needed, to write such code,
> with the calculation of the next candidate at the bottom and the test at the top.
> You just confirmed the walrus operator is not very useful once the next candidate is
> no longer just a name.

Okay, I would be happy to confirm my belief that the walrus is not very useful
when the thing you wish to test is not the same as the thing you with to assign.

But to relate this use case to my earlier loop-and-a-half examples:

(a,b) := next_couple(a,b)

presumes that there is are values for a and b to begin with for that first call to next_couple.
How do you initialize them correctly?

If you initialize them to the "first" couple (whatever that is), then your loop will
start off finding the second couple and you would be missing your first iteration.

Do you put special code in next_couple() to recognize that the provided arguments
are actually the first couple so it can return those unmodified, but then require its
own mental note not to give you an infinite loop forever returning that first couple?

Do you have to define a special case such as (a,b) = (0,0) or (None,None) to tell
next_couple that you really want the first one? That seems a little counter-intuitive
to have something named "next" need a special input to mean "first",

Not to mention whatever you use to initialize is probably not going to be very meaningful or
clear on its own terms. In my earlier note, I objected to "(ctr := ctr-1) > 0" on the grounds
that it required initializing the counter to 11 when you really wanted to count down from 10.

I favor using the walrus operator when it actually makes the code simpler and clearer;
I don't favor using it willy-nilly just because you wish to do an assignment operation
inside of a test condition, if its usage makes the code less clear. I interpret the PEP
has using the walrus to define a name for a particular value that would be both tested
and reused, and not that it would be used to assign to a value that was not being
tested (such as the a part of (a,b)).

Or in short, I do not find your choice of use-case really lines up with the rationale
given for walrus operator. You are free to disagree with me, but fortunately, we have
one of those PEP authors participating in this list regularly if you want his opinion.

Roger Christman
Pennsylvania State University


--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On 27/10/2021 at 12:45 Antoon Pardon wrote:
> However with the introduction of the walrus operator there is a
> way to simulate a significant number of one and a half loops.

> Consider the following:

> do
> a = expr1
> b = expr2
> while 2 * a > b:
> more calculations

> We could write that now as

> while [.
> a := expr1,
> b := expr2,
> 2 * a > b][-1]:
> more calculations

Why don't you try this?

while 2 * (a := expr1) > (b := expr2):
more calculations

It seems you are just compelled to create tuple and lists
in all of your use-cases, even when they serve no purpose.

Roger Christman
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 27/10/2021 om 18:16 schreef Christman, Roger Graydon:
> On 27/10/2021 at 12:45 Antoon Pardon wrote:
>> However with the introduction of the walrus operator there is a
>> way to simulate a significant number of one and a half loops.
>> Consider the following:
> > do
> > a = expr1
> > b = expr2
> > while 2 * a > b:
> > more calculations
>
>> We could write that now as
> > while [.
> > a := expr1,
> > b := expr2,
> > 2 * a > b][-1]:
> > more calculations
>
> Why don't you try this?

Because this is about a general idea, not about the specifics of the example.

> while 2 * (a := expr1) > (b := expr2):
> more calculations
>
> It seems you are just compelled to create tuple and lists
> in all of your use-cases, even when they serve no purpose.

Do you have a procedure that will always eliminate a list and will be
more or less as readable as the one and a half loop?

I know the list serves no purpose, other than to provide a way to
easily write the calculations in the order that seems most natural.

But being able to write calculations in the order that makes them
more understandable is IMO worth more than eliminating the list.
Even if the list serves no real purpose in the calculations.

So suppose I have an arbitrary number of simple statements. The
latter possible using results from previous assignment and at the
end a condition to control the one and a half loop. How do you write
the python code so that the one and a half loop is easy to recognize?

--
Antoon Pardon

--
https://mail.python.org/mailman/listinfo/python-list
RE: New assignmens ... [ In reply to ]
I think anyone who suggests we should separate costs from benefits belongs
securely within the academic world and should remain there.

Practical things need to be built considering costs. Theoretical things,
sure, cost is not an issue.

Python is not only a real-world set of applications but an evolving one with
a huge embedded base. We have seen how hard it was for some to move when 2.X
and 3.X versions were not upward compatible. Some have refused to move. So
adding new features must not only be done carefully with an eye for path
upward but also to not destroy existing programs when possible. When a
change is needed, it is often done in stages with some things being
deprecated for a while before the change.

So the half-submerged walrus operator was added instead of the flying
walrus operator with anti-gravity built in. If the proposal had been to
allow EVERYTHING you and others are suggesting, it is quite possible we
would never have had anything changed and no walrus. True, in another decade
or so, they might have gotten around to adding the unrestricted walrus. or
not.

What we have today is a path that may lead to more functionality
incrementally. If people are using the walrus and like it and it makes
coding easier AND they ask for more, it may come, at incremental cost.

-----Original Message-----
From: Python-list <python-list-bounces+avigross=verizon.net@python.org> On
Behalf Of Antoon Pardon
Sent: Wednesday, October 27, 2021 2:59 AM
To: python-list@python.org
Subject: Re: New assignmens ...



Op 26/10/2021 om 00:24 schreef Chris Angelico:
> TBH, I don't think there's a lot of value in multiple-assignment,
> since it has a number of annoying conflicts of syntax and few viable
> use-cases. But if you have great examples of "x.y :=" or "x[y] :=",
> then by all means, post on python-ideas to propose widening the scope.

I think you should seperate the costs from the benefits. It is not because
the costs can be high there is little value.

And how do you count use cases? What about the following pattern:

while (a, b) := next_couple(a,b)[-1]:
...

Is that one use case or is that a use case for each kind of couple?

And even if the benefits are little per case, they can add up with every
occasion such a case pops up.

--
Antoon Pardon.

--
https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Thu, Oct 28, 2021 at 4:03 AM Antoon Pardon <antoon.pardon@vub.be> wrote:
>
> So suppose I have an arbitrary number of simple statements. The
> latter possible using results from previous assignment and at the
> end a condition to control the one and a half loop. How do you write
> the python code so that the one and a half loop is easy to recognize?
>

The most general way to write a loop-and-a-half is to invert the
condition and break. For cases too complicated to fit into the loop
header, that would be the obvious solution.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Thu, Oct 28, 2021 at 4:34 AM Christman, Roger Graydon <dvl@psu.edu> wrote:
> Do you put special code in next_couple() to recognize that the provided arguments
> are actually the first couple so it can return those unmodified, but then require its
> own mental note not to give you an infinite loop forever returning that first couple?
>
> Do you have to define a special case such as (a,b) = (0,0) or (None,None) to tell
> next_couple that you really want the first one? That seems a little counter-intuitive
> to have something named "next" need a special input to mean "first",

In some cases, there is a very real special startup value (a seed).
For instance, if we're calculating something relating to the
Mandelbrot set:

# The point we're working with
c = (0.25 + 0.125j)
# Always start here
z = (0 + 0j) # or just 0
while abs(z := z*z+c) < 2:
...


Though in this case, you don't look for a next_couple, you look for a
single next value, and the other value is constant.

But it all depends on the exact process being done, which is why I've
been asking for real examples.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
I no longer track the threads on the subject ... Many simultaneous ones
ongoing!

Kind Regards,

Abdur-Rahmaan Janhangeer
about <https://compileralchemy.github.io/> | blog
<https://www.pythonkitchen.com>
github <https://github.com/Abdur-RahmaanJ>
Mauritius
--
https://mail.python.org/mailman/listinfo/python-list
RE: New assignmens ... [ In reply to ]
Dave,

You make me wonder about unintended side effects. Are we allowing the ++ and
--- operations into Python through a side door?

any context that allows you to insert the walrus operator like:

index := index + 1
index := index - 1

Is now similar to notations in C/C++ and others like
++index
--index

If you can set or reset a variable this way, it can even look more efficient
that counting by 2 or more which in C would look like:

++(++index)

Of course we now would get suggestions to just add the pre-increment
operator to Python, and while we are added, for completeness, add the
post-increment version of index++ ...

I mean if cost is no object, and worrying how it may impact current programs
or conflicts is nothing to be concerned about in the interest of some
academic purity ...


-----Original Message-----
From: Python-list <python-list-bounces+avigross=verizon.net@python.org> On
Behalf Of dn via Python-list
Sent: Wednesday, October 27, 2021 4:38 AM
To: python-list@python.org
Subject: Re: New assignmens ...

On 24/10/2021 22.23, O365 Dict wrote:
> Well I have the following use case:
>
> while (temp_result := calculate_next_couple(a, b))[1]:
> a, b = temp_result
> more calculations
>
> Which IMO would be clearer if I could just write:
>
> while ((a, b) := calculate_next_couple(a,b))[1]:
> more calculations
>
> Of course it would even more clear if I could write something like:
>
> while (a, b) := calculate_next_couple(a, b); b:
> more calculations
>
> or
>
> do:
> a, b = calculate_next_couple(a, b)
> while b:
> more calculations


Found (all of) the above less-than-obvious to read. Putting it in front of
trainees this morning caused only confusion - even the currently-legal
variation.


Accordingly: is this a job for the walrus operator at all? Let's "talk of
many [other] things"*.


Is this an algorithmic complexity, or a complicated way to look at (and
manipulate) data?

Well, judging from the code (above), use of the walrus certainly presumes
the former. Instead let's review any possibility of the latter (if only for
academic interest)...


What do we want out of the first line? (in no particular order)

1 use calculate_next_couple() to compute (new) a from an (old) a and b
2 use calculate_next_couple() to compute (new) b from an (old) a and b
3 use (new) b to decide if the loop should execute or terminate

The 'problem' then, has been phrased as these three objectives ask too much
of the (current implementation of the) walrus-operator.


NB after one (or more) cycles, when the loop 'returns to the top', what I've
termed 'new' a and b (above), will become (my reference) the 'old'
pair/tuple.


That all looks simple. What is dn complaining about?


Could we use a data structure to continue to keep things straight-forward?

class my_class():
def __init__( self, a, b )->None;
self.a = a
self.b = b

instance = my_class( a, b )


Sorry, you're probably becoming impatient with me. Surely I'm typing more
code than necessary? Maybe, but there are other measures of
code-quality/good-practice/etc, and there's likely more to 'it' than just
these few lines...


First consideration: the algorithm needs us to 'feed' the while-condition.
So let's flesh-out:

def is_more( self )->bool:
# you know what goes here - I don't, but that's not the issue
# the return value is all that matters
return is_there_any_more_data_to_calculate?

In which case, the loop becomes:

while instance.is_more():
more calculations

and 'readability' improves immeasurably!

NB for extra credit, turn the boolean function into a "property", and be
able to omit the (unsightly?) parentheses from the 'call'!


But, not so fast - what about the calculation itself, currently embedded in
calculate_next_couple()?

Well, those details are out of my sight, and I'm assuming include reasonable
complexity - otherwise you wouldn't propose this as a good-example. Allow me
to muddle-through with:

def calculate_next_couple( self )->None:
self.a = calculation of 'new' a
self.b = calculation of 'new' b

To avoid an 'extra' call against the instance from the while-loop, execute
the 'calculate' method from either __init__() or is_more(), as appropriate
(given that it likely needs to precede the return from the latter -
particularly if the computation is 'expensive'). The choice may be
subject-dependent ...


Now within "more calculations", one assumes, references to "a" and "b"
will need to be amended to become 'instance.a' and 'instance.b'. More
typing! What about preserving our fingers?


Readability will further improve when "a" and "b" (etc) are replaced by
'real names'.

The processing steps within "more calculations" could be reviewed. Some may
be candidates for inclusion as my_class methods - which would even enable
further simplifications and/or encapsulation of code-suites relevant to the
application, and/or "a" and "b" and the processes around them.

If the "calculation" of 'next_couple' currently involves looking-up another
data-structure, eg a list of data-points, then combining such with/into
my_class may well yield further simplifications, encapsulations, and
benefits - but all in-theory and complete ignorance of your application...


Hope the above gives you some ideas/pause for thought!


* this gratuitous and somewhat awkward expression is me claiming to be
clever by quoting Lewis Carroll - if he isn't sick of me baiting-the-hook,
it might earn extra brownie-points (or another groan) from @Chris...
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Thu, Oct 28, 2021 at 11:08 AM Avi Gross via Python-list
<python-list@python.org> wrote:
>
> Dave,
>
> You make me wonder about unintended side effects. Are we allowing the ++ and
> --- operations into Python through a side door?
>

class IncrementableInteger(int):
def __pos__(self): return HalfIncremented(self)
def __neg__(self): return HalfDecremented(self)

class HalfIncremented(IncrementableInteger):
def __pos__(self): return IncrementableInteger(self + 1)

class HalfDecremented(IncrementableInteger):
def __neg__(self): return IncrementableInteger(self - 1)

Up to you to make the actual mutation work but have fun making a
nightmare for subsequent maintainers!

ChrisA
PS. Nobody's ever stopping you from def __add_(self, other): return
self * other + 3
Just sayin'.
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 27/10/2021 om 20:20 schreef Avi Gross:
> I think anyone who suggests we should separate costs from benefits belongs
> securely within the academic world and should remain there.
>
> Practical things need to be built considering costs. Theoretical things,
> sure, cost is not an issue.

Seperating costs from benefits doesn't mean costs are not an issue. It means
you don't deny de benefits because there are costs. Sure in the end the costs
may outweight the benefits but that is still not the same as there being no
benefits at all.

If you want to weight the costs against the benefits you need to acknowledge
both and not start by denying the benefits because you presume they will
not outweight the costs.

--
Antoon.

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 27/10/2021 om 17:05 schreef Christman, Roger Graydon:
> I'm going to provide two loop-and-a-half segments to illustrate my interpretation
> of this PEP and the purpose of the walrus operator:
>
> [ first example ]
>
> Now contrast with this example:
>
> Without the walrus:
>
> replay = True
> while replay:
> play_game()
> replay = input("Play again? ") in ['y','Y','yes','Yes']
>
> (I think it silly to ask about playing again at first).
>
> With the walrus:
>
> replay = None
> while replay==None or (replay := input("Play again? ") in ['y','Y','yes','Yes']:
> play_game()
>
> To use the walrus operator here, I have to fabricate a value that would
> allow me to bypass the input operation, that cannot be otherwise produced.
> I do not find this second version any clearer or more intuitive than the first
> (and the PEP did emphasize the value of clarity).

But the above is not a one and a half loop. The above is essentially a do
loop (repeat loop in pascal), where you have the test at the end of the
loop body. But because python doesn't have that loop you have to use a
boolean to control the loop that is initialized to True and then later
assign that boolean the result of the test which you use to control this
loop.

Should I think it worth the trouble to rewrite your example, quod non,
it would be like below, with that unneeded list.

while [
play_game(),
input("Play again? ") in ['y', 'Y', 'yes', 'Yes']][-1]:
pass

--
Antoon Pardon.

--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On 2021-10-28, Paul Rubin <no.email@nospam.invalid> wrote:
> Chris Angelico <rosuav@gmail.com> writes:
>> But it all depends on the exact process being done, which is why I've
>> been asking for real examples.
>
> My most frequent use case for walrus is so common that I have sometimes
> implemented a special class for it:
>
> if g := re.search(pat1, text):
> hack(g.group(1))
> elif g := re.search(pat2, text):
> smack(g.group(2), "foo")
> ...
>
> It's way messier if you have to separate the assignment and test the old
> way. That said, I'm still on Python 3.7 so I haven't yet gotten to use
> walrus or the new match statement (or is it expression).
>
> I do feel surprised that you can't use an arbitrary lvalue (to use C
> terminology) on the lhs of a walrus. That seems downright weird to me.
> But, I haven't studied the PEP so I don't know if there was a particular
> rationale.

Well, that's what I was saying: there's no rationale - the limitation
is not even mentioned, let alone explained.
--
https://mail.python.org/mailman/listinfo/python-list
RE: New assignmens ... [ In reply to ]
Antoon,



You keep beating a dead horse. NOBODY denies there are benefits to suggestions like the one we are describing. It is a logical fallacy to keep arguing this way.



And nobody (meaning me) suggests costs are a dominant factor in decisions no matter the benefits. The realistic suggestion is to not only weight costs and benefits for one proposal but for all reasonable proposals and then choose.



I have no idea what the actual cost of changing the parser is. It may be trivial or very nontrivial. I do not know if the actual chosen change, from a range of possible implementations, will leave the speed of typical programs untouched or will add lots of overhead for all programs including the ones not using this feature. Nor do I know how many existing features might clash with the choice of implementation and need to be changed to resolve them or face lots of bug reports later.



So what I and others have said here is not based completely on known and measured facts. But before approving a proposal, some analysis and estimates must be made including a decision to just cancel any work if it over-runs targeted costs of various kinds.



Now for a dumb question. Many languages allow a form of setting a variable to a value like:



assign(var, 5+sin(x))



If we had a function that then returned var or the value of var, cleanly, then would that allow an end run on the walrus operator?



if (assign(sign, 5+sin(x)) <= assign(cosign, 5+cos(x))) …



Not necessarily pretty and I am sure there may well be reasons it won’t work, but I wonder if it will work in more places than the currently minimal walrus operator.



From: Antoon Pardon <antoon.pardon@vub.be>
Sent: Thursday, October 28, 2021 3:03 AM
To: Avi Gross <avigross@verizon.net>; python-list@python.org
Subject: Re: New assignmens ...





Op 27/10/2021 om 20:20 schreef Avi Gross:

I think anyone who suggests we should separate costs from benefits belongs
securely within the academic world and should remain there.

Practical things need to be built considering costs. Theoretical things,
sure, cost is not an issue.


Seperating costs from benefits doesn't mean costs are not an issue. It means
you don't deny de benefits because there are costs. Sure in the end the costs
may outweight the benefits but that is still not the same as there being no
benefits at all.

If you want to weight the costs against the benefits you need to acknowledge
both and not start by denying the benefits because you presume they will
not outweight the costs.

--
Antoon.
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
On Fri, Oct 29, 2021 at 4:37 AM Avi Gross via Python-list
<python-list@python.org> wrote:
> Now for a dumb question. Many languages allow a form of setting a variable to a value like:
>
> assign(var, 5+sin(x))
>
> If we had a function that then returned var or the value of var, cleanly, then would that allow an end run on the walrus operator?
>
> if (assign(sign, 5+sin(x)) <= assign(cosign, 5+cos(x))) …
>
> Not necessarily pretty and I am sure there may well be reasons it won’t work, but I wonder if it will work in more places than the currently minimal walrus operator.

For that to work, the language needs one of three things:

1) A way to pass an lvalue to a function, which it can then change
2) A form of pointer or reference (same thing, but you'd adorn it at
the call site - eg in C, you can write &var)
3) Magical compiler support for the assign function, so it isn't
really a function, just something that looks like one.

(Are there any other ways? I can't think of any.)

Python currently doesn't have any of those, so you'd have to pick
which one you're advocating for and show how it would be beneficial.
Personally, I'm dubious of all three, but I would be most interested
in the second option and its consequences.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 28/10/2021 om 19:36 schreef Avi Gross via Python-list:
> Antoon,
>
>
> You keep beating a dead horse. NOBODY denies there are benefits to suggestions like the one we are describing. It is a logical fallacy to keep arguing this way.

Please point to the specific logical falacy you think I am commiting. Don't hand wave about what I supposedly
am doing.

> And nobody (meaning me) suggests costs are a dominant factor in decisions no matter the benefits. The realistic suggestion is to not only weight costs and benefits for one proposal but for all reasonable proposals and then choose.

So what if *you* don't suggest that. Others have. Then when I responded to those with a remark about seperating
costs and benefits, you budded in with the assertion that those who suggest seperating benefits and cost belong
in the accademic world because you understood that remark as implying costs are not as issue. I then explain you
misunderdood en now you come with the above.

Maybe you should be more aware of the history of a thread before coming with this kind of statements.

--
Antoon Pardon
--
https://mail.python.org/mailman/listinfo/python-list
Re: New assignmens ... [ In reply to ]
Op 28/10/2021 om 19:36 schreef Avi Gross via Python-list:
> Now for a dumb question. Many languages allow a form of setting a variable to a value like:
>
>
>
> assign(var, 5+sin(x))
>
>
>
> If we had a function that then returned var or the value of var, cleanly, then would that allow an end run on the walrus operator?
>
>
>
> if (assign(sign, 5+sin(x)) <= assign(cosign, 5+cos(x))) …
>
>
>
> Not necessarily pretty and I am sure there may well be reasons it won’t work, but I wonder if it will work in more places than the currently minimal walrus operator.

This was the orginal code to illustrate the question:

if (self.ctr:=self.ctr-1)<=0

So if I understand your sugested solution it would be something like:

def setxattr(obj, attr, value):
setattr(obj, attr, value)
return value

if setxattr(self, 'ctr', self.ctr - 1) <= 0

Did I get that right?

--
Antoon Pardon.



--
https://mail.python.org/mailman/listinfo/python-list
RE: New assignmens ... [ In reply to ]
Antoon,

As long as we understand that my suggestion is not meant to be taken seriously, your extension is along the lines I intended.

You might indeed have a family of helper functions whose purpose is to bot make a change on the side and return the value to be used in a computation. Your specific implementation of something like that:

def setxattr(obj, attr, value):
setattr(obj, attr, value)
return value

Would need to have access to the original object and change it in a way that propagates properly. So when you do this:

if setxattr(self, 'ctr', self.ctr - 1) <= 0 :

Then assuming passing it 'ctr' as a string makes sense, and the object self is passed by reference, I can see it working without a walrus operator.

But it is extra overhead. This being python, setting values WITHIN an object is a challenge. I mean there are ways to make a value readable but not writeable or writeable only using a designated method, or an attempt to set the value may be intercepted and the interceptor may choose to do something different such as ignoring the request if someone tries to set the time to thirteen o'clock or even setting it to 1 o'clock instead. The above kind of code perhaps should not return value but obj.attr so we see what was stored. But again, Python lets you intercept things in interesting ways so I can imagine it showing something other that what you stored.

Sigh

As noted, the general case implemented walrus style may have challenges and even efforts like the above may not always be straightforward.

Language design is not as trivial as some think and like with many things, adding a neat new feature may open up holes including security holes if people figure out how to abuse it. Shutting down some such abilities is exactly why people code defensively and try to hide the inner aspects of an object by doing things like having a proxy in front of it and creating getters and setters.


-----Original Message-----
From: Python-list <python-list-bounces+avigross=verizon.net@python.org> On Behalf Of Antoon Pardon
Sent: Friday, October 29, 2021 10:04 AM
To: python-list@python.org
Subject: Re: New assignmens ...



Op 28/10/2021 om 19:36 schreef Avi Gross via Python-list:
> Now for a dumb question. Many languages allow a form of setting a variable to a value like:
>
>
>
> assign(var, 5+sin(x))
>
>
>
> If we had a function that then returned var or the value of var, cleanly, then would that allow an end run on the walrus operator?
>
>
>
> if (assign(sign, 5+sin(x)) <= assign(cosign, 5+cos(x))) …
>
>
>
> Not necessarily pretty and I am sure there may well be reasons it won’t work, but I wonder if it will work in more places than the currently minimal walrus operator.

This was the orginal code to illustrate the question:

if (self.ctr:=self.ctr-1)<=0

So if I understand your sugested solution it would be something like:

def setxattr(obj, attr, value):
setattr(obj, attr, value)
return value

if setxattr(self, 'ctr', self.ctr - 1) <= 0

Did I get that right?

--
Antoon Pardon.



--
https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list