Re: [Tutor] user overloaded

2018-11-28 Thread Steven D'Aprano
On Wed, Nov 28, 2018 at 12:56:32PM -0500, Avi Gross wrote:

> try ...
> except ValueError, e:
> ...
> 
> You now need to do this format:
> 
> try ...
> except ValueError as e:
> ...
> 
> Why the change?

Because the first form was a trap and a bug magnet:

try:
block
except TypeError, ValueError, KeyError:
print "surprise! this will not catch key errors!"



[...]
> 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)

That's not a comparison, that's an identity. The tangent function is (or 
at least can be) defined as sine divided by cosine.


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

That's usually called "assignment" or "binding".


> x = x + 5
> 
> is an example where it makes no mathematical sense. How can a number be
> equal to itself when 5 is added? 

There is no solution there in the normal real number system, but there 
are forms of arithmetic where it does, e.g. "clock arithmetic". If your 
clock only has values 0 through 4, then adding 5 to any x will give you 
x back again.

Although normally we write "congruent" rather than "equals" for clock 
arithmetic: 

x ≡ x + 5 (mod 5)


In any case, just because there is no solution doesn't mean that the 
question makes no sense:

x = x*5

makes perfect sense and has solution 0. Likewise:

x = x**2 + k

makes perfect sense too, and can have zero, one or two solutions 
depending on the value of k.



> 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.

Actually, it is precisely what Python intends, except for two minor 
differences:

1. in Pascal, := assignment is a statement, not an expression, 
   while in Python it will be an expresion;

2. Python will discourage people from using the := expression
   form as a de facto statement, where = will do.


[...]
> 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.

The "is" operator is in no way, shape or form an equality test. It is an 
*identity* test, which returns True if and only if the two operands are 
the same object.

Equality does not imply identity:

py> x = []
py> (x == []) and (x is not [])
True


nor does identity imply equality:

py> NAN = float(NAN)
py> (NAN is NAN) and (NAN != NAN)
True

Anyone using "is" when then test for equality is programming in a state 
of sin.


> 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.

This is called a "short-circuiting boolean operator", and it was old, 
old old when Python started using it 25+ years ago. I believe Lisp was 
the first to introduce them, in the 1950s.

https://en.wikipedia.org/wiki/Short-circuit_evaluation



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


[Tutor] user overloaded

2018-11-28 Thread Avi Gross
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 #