[Tutor] user overloaded

Avi Gross avigross at verizon.net
Wed Nov 28 12:56:32 EST 2018


OOPS,

Sorry Steve. Yes, I am on multiple mailing lists and the tutor list by
default replies to the sender and you need to edit it to reply to the group.
I will be careful.

Your other point is broader. There are lots of operations (not just ion
python) that are easy to misuse. Sometimes the same symbol is used in
multiple ways, such as how parentheses can mean a tuple even when you wanted
to use them for ordering. There was a recent discussion about how the try
statement changed after 2.x so instead of the part that used to say:

try ...
except ValueError, e:
...

You now need to do this format:

try ...
except ValueError as e:
...

Why the change?

I have not looked to see, but note the earlier version is sort of a tuple
without parentheses which Python allows in many contexts. As the keyword
"as" is now used in other places like import statements so why not make
things more consistent. But to others who just see a CHANGE and wonder why,
many things seem mysterious. Yes, read the manual but that is not something
new users seem to want to do, let alone know how to find what to read and
slog through lots of pages.

Back to your topic. "=" as a symbol has been used over the years in many
ways.  In normal mathematics, it is mostly seen as a comparison operator as
in tan(x) = sin(x)/cos(x)

Many programming languages used it instead to sort of mean MAKE EQUALS.

x = x + 5

is an example where it makes no mathematical sense. How can a number be
equal to itself when 5 is added? The meaning clearly is something like x
gets assigned a value by evaluating the current value of x and adding 5 to
that. When done, the old value of x is gone and it has a new value.

For this reason, some languages like PASCAL used := so the above became 

x := x + 5

Yes, same symbol we are discussing and NOT what Python intends.

Languages like R also decided to not use a naked "=" sign and encouraged
arrow notation like:

x <- x + 5
and even
x + x -> x

And yes, for global variables there are --> and <-- and worse.

But they still accept a naked "=" as well and use that alone in function
definitions and calls for setting values by name. Yes, it can confuse people
when an assignment is "<-" and a comparison is "<=" .

And there are forms of equality that some languages need to distinguish.
What does it mean if two (unordered) sets are equal? Must they be two
reference to the same set or is it shorthand for them being strict subsets
of each other in both directions? You can come up with additional
abstractions like whether a list is a shallow or deep copy of another and
how it effects your ideas about them being equal. You may want a way to say
things are approximately equal. In math, something like ~= is used. Python
has an operator called "is" that can be a variant on equality. But it can be
subtle when python reuses an immutable object and they seem to be the same
even when you try to make them different:

>>> a = "supercalifragilisticexpialidocious" * 20
>>> b  = "supercalifragilisticexpialidocious" * 10 +
"supercalifragilisticexpialidocious" * 10
>>> a == b
True
>>> a is b
True

Weird. Try that with mutables:

>>> a = [ 'hello' ]
	 
>>> b = [ 'hello' ]
	 
>>> a == b
	 
True
>>> a is b
	 
False

For people new to computer science or a particular programming language,
there can be too much and users get overloaded by all the overloading.

Adding yet another variant to have a side-effect within an expression using
":=" will extend some of the power of python but at a cost for some, and
especially new users.

Consider the concept of OR. Some languages spell it out when used in a
Boolean context. 

a or b

But python does something new with this. In some contexts the above
effectively becomes an IF.

>>> a = 5
	 
>>> b = 10
	 
>>> x = a or b
	 
>>> x
	 
5
>>> a = 0
	 
>>> x = a or b
	 
>>> x
	 
10


So because python has  a creative definition of what is True and What is
False, the above is sort of this code:

if ( a EVALUATES TO TRUE)
  x = a
else 
  x = WHATEVER b EVALUATES to

Since I chose integers, a is true whenever it is not precisely zero. For
lists and many other objects, they are True if not empty.

That is not the same meaning of "or" that many languages use. Add other
meanings like a "bitwise or", "exclusive or" or the union of two sets and
you can see people get confused especially when the same or similar symbols
are used. Many languages have a symbol like "|" and another like "||" for
example. 

Arguably python allows users to invent their own overloading in classes so
that using some version of "or" between two objects means whatever you want
it to mean. I recently (for fun) created a sort of auto-increment (as in the
C/C++ symbol ++) so that if you had a counter called x, then adding ANYTHING
to x using the += notation just incremented it by 1.

X =		odd_object(6) # X initialized to 6
X += 1		# X is now 7
X += 12		# X is now 8 as the __iadd__ method ignores the 12 and adds
just 1

The above abomination does not replace ++ as an autoincrement but can give
you some functionality but many users will have no idea what just happened.

I note it can be worse in languages that allow you to create your own
operators. I often use %>% in R for example and can make my own by placing
almost any nonsense between percent signs and binding it to a function.

As I understand it, back to Python, if adding a := to be used in expressions
does not break any existing code, it may not be so bad. I mean nobody is
supposed to be using that symbol now, so what does it hurt?

Ah, but wait. If I had the previously discussed notion of checking whether
the string I wanted to dynamically evaluate contained possibly dangerous
code, would it be looking for a ":=" ? Heck, if I am parsing something and
looking for a colon that indicates the beginning of a BODY, might it get
confused by finding this colon in a wrong context?

I conclude by saying life is complicated and then you die. I mean there are
many places where similar but not identical things happen in languages as
well as life.

-----Original Message-----
From: Tutor <tutor-bounces+avigross=verizon.net at python.org> On Behalf Of
Steven D'Aprano
Sent: Wednesday, November 28, 2018 4:13 AM
To: tutor at python.org
Subject: Re: [Tutor] PEP 572 -- Assignment Expressions

On Tue, Nov 27, 2018 at 08:26:04PM -0500, Avi Gross wrote:
> Ivo,

You've replied to the wrong mailing list. Ivo wrote to Python-List, not
Tutor.

But now that you've raised the issue...


[Ivo asked]
>    Why:
>          if (match := pattern.search(data)) is not None:
>                # Do something with match
> 
>    What is wrong with:
>          if match = pattern.search(data) is not None:
>                # Do something with match
> 
>    Assignment expression or assignment statement, it's an assignment,
right?
> It is very clear to everyone that it's an assignment! Can't it all 
> just be a "="?

It seems that Ivo didn't read the PEP because that is discussed:

https://www.python.org/dev/peps/pep-0572/#id32

Despite Ivo's statement that it is "clear to everyone", the problem is that
whenever you see an assignment x=y in an assignment, there's no obvious way
of telling whether they meant assignment or it was a mistyped equality test
x==y. So it is not clear at all.

In C, this confusion between = and == is a frequent source of serious bugs,
including one attempt at inserting a back-door into the Linux
kernel:

https://freedom-to-tinker.com/2013/10/09/the-linux-backdoor-attempt-of-2003/

https://lwn.net/Articles/57135/


Requiring the colon x:=y makes it less likely to mess up the assignment or
comparison.



-- 
Steve
_______________________________________________
Tutor maillist  -  Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor



More information about the Tutor mailing list