News for hackers. Stuff that matters.
Re:The Python Unicode Mess by wool_gather on Saturday October 06, 2018 @09:54AM (#18155129)
Why would this be a type error? "Are these two things equivalent?" has an unambiguous answer regardless of whether the things are of different types. When they are not the same kind of thing, the answer is simply `False`. There's no reason to have a third answer "You're not allowed to ask that" for that case.
Re:The Python Unicode Mess by uryga on Saturday October 06, 2018 @10:39AM (#18155348)
It's not unambiguous at all. If I do

    "część" == "część".encode('<some-obscure-encoding>')
should it return True? They are 'equivalent' after all. But that would mean it should work for any encoding, so testing `s == b` would entail trying to decode `b` as every known encoding to see if any of them gives `s`.

My point is, `s == b` is not a well-defined question. It only makes sense to ask it for a particular encoding: "Are these two things isomorphic according to cp-1252?"¹². Giving a type error is a decent way of signalling all this.

---

¹ And even then, I don't like automatic type conversions that enable things like `3 == "3"`, but I guess that's a matter of taste.

² Of course you could pick a convention like `s == b <=> s = b.decode("utf8")`, but that's a different question.

Re:The Python Unicode Mess by wool_gather on Saturday October 06, 2018 @05:47PM (#18157444)
No, it should return `False` because they're different types, as I said.

> I don't like automatic type conversions that enable things like `3 == "3"`

I didn't mention this, and Python, the language under discussion, doesn't do this.

Re:The Python Unicode Mess by uryga on Saturday October 06, 2018 @06:14PM (#18157581)
Okay, it looks like I misunderstood your original point:

> "Are these two things equivalent?" has an unambiguous answer regardless of whether the things are of different types.

as

"Isomorphic things should compare equal"

So, to respond to (what I think is) your actual point: in my view, equality is defined on values of a single type, so I prefer to distinguish

"a isn't equal to b" (= False)

and

"there's no defined way to compare a and b, because they have different types" (= some kind of error or a null-like value)

To me, conflating the two seems counterproductive, but perhaps this is personal preference (probably correlated with how much one likes static typing).

Re:The Python Unicode Mess by ubernostrum on Saturday October 06, 2018 @11:45PM (#18158736)
Python has operator overloading, though, so a flat rule that comparisons involving values of different types must always be a type error would actually reduce the power of the language. Granted, there aren't a ton of use cases where it's important to be able to do this, but it is useful on occasion.
Re:The Python Unicode Mess by uryga on Sunday October 07, 2018 @02:49PM (#18162040)
You're right – I guess I got too hung up on the types. What I meant to say is that I prefer to distinguish "`a` is not equal to `b`" and "equality between `a` and `b` is undefined"; the typing aspect is kind of orthogonal and muddles the discussion.

(I guess I ended up conflating equality and equivalence[1], but in my defense, most languages seem to do that too; and the presence of the `is` operator in Python mixes things up even more)

[1] https://en.m.wikipedia.org/wiki/Equality_(mathematics)#Relat...

Re:The Python Unicode Mess by minitech on Saturday October 06, 2018 @10:09AM (#18155176)
It would be a type error because that would be helpful. Since comparing a bytes to a str is not usually what you want, Python could make you be explicit about it. It’s too late now, and it might have been considered another backwards compatibility break (so a good thing to keep out of Python 3), but it’s not a bad idea on its own. Heterogeneous collections are pretty rare.

Also, `==` doesn’t always answer the question of whether two things are equivalent in Python:

  >>> 1.0 == 1
  True
  >>> {'a': 5} == OrderedDict({'a': 5})
  True
(OrderedDict equality isn’t transitive.)
Re:The Python Unicode Mess by gvx on Saturday October 06, 2018 @10:40AM (#18155356)
Pretty rare but not unheard of. I do know that most of the code bases I work in would require significant reworking if I have to expect `==` to throw a TypeError for basic builtin types.
Re:The Python Unicode Mess by guitarbill on Saturday October 06, 2018 @04:57PM (#18157225)
Not quite with ==, but there is precedence where operators with basic builtin types throw a TypeError when the operation doesn't make sense:

    >>> 0 > None
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: '>' not supported between instances of 'int' and 'NoneType'
Re:The Python Unicode Mess by wool_gather on Saturday October 06, 2018 @05:51PM (#18157457)
Absolutely; there's no good boolean answer for > when you have different types, so the `TypeError` is perfect there.
Re:The Python Unicode Mess by ubernostrum on Saturday October 06, 2018 @11:58PM (#18158776)
At the same time, this result is entirely dependent on the types involved. For example, "1.0 > 0" has a well-defined answer, and Python returns it.

Considering the expression "x > y", the full process is:

1. Call x.__gt__(y).

2. If that returns a bool, that's the result. If it raises an exception, propagate the exception.

3. If it returns the sentinel value NotImplemented, attempt the reflected version of the operation: y.__lt__(x).

4. If that returns a bool, that's the result. If it raises an exception, propagate the exception.

5. If it returns the sentinel value NotImplemented, raise TypeError and inform the programmer this operator is not valid on these types.

Re:The Python Unicode Mess by uryga on Saturday October 06, 2018 @10:47AM (#18155392)
Could you explain how your example shows that?
Re:The Python Unicode Mess by minitech on Saturday October 06, 2018 @11:35AM (#18155635)
Which “that”? If you’re asking about `OrderedDict`, I’m referring to equality between `OrderedDict`s:

  >>> a = OrderedDict([(1, 2), (3, 4)])
  >>> b = {1: 2, 3: 4}
  >>> c = OrderedDict(reversed(a.items()))
  >>> a == b == c
  True
  >>> a == c
  False
Re:The Python Unicode Mess by uryga on Saturday October 06, 2018 @05:53PM (#18157471)
I was referring to this:

> Also, `==` doesn’t always answer the question of whether two things are equivalent

because the examples you posteda kinda make it look like it does, i.e. `1.0 == 1` even though one is a float and the other is an int.

Re:The Python Unicode Mess by zbentley on Saturday October 06, 2018 @10:56AM (#18155431)
> "Are these two things equivalent?" has an unambiguous answer regardless of whether the things are of different types.

Absolutely not; that's basically the OG subjective question whose lack of an obvious right answer underpins a substantial quantity of the bugs in less strongly-typed languages.

Nor is an unambiguous answer possible symbolically, or in common logic, or the semantics of spoken languages.

Re:The Python Unicode Mess by wool_gather on Saturday October 06, 2018 @05:49PM (#18157451)
I think you stopped reading before my next sentence, which says the answer is "false" if the types are different.