cosmologicon / pywat

Python wats
1.22k stars 99 forks source link

Iterable types in comparisons #23

Open dmytrokyrychuk opened 9 years ago

dmytrokyrychuk commented 9 years ago

You're trying to compare different types. It is obvious that a list and a tuple are completely different objects.

>>> a = [0, 0]  # a is a list
>>> (x, y) = a  # unpacking a list; (x, y) is a tuple
>>> (x, y) == a  # comparing a tuple to a list 
False

Proof:

>>> a = [0, 0]
>>> type(a)
<class 'list'>
>>> (x, y) = a
>>> type((x, y))
<class 'tuple'>

sorted() always returns a list.

>>> type((1, 2, 3))
<class 'tuple'>
>>> type(sorted((1, 2, 3)))
<class 'list'>
cosmologicon commented 9 years ago

You're trying to compare different types. It is obvious that a list and a tuple are completely different objects.

See my response to issue #10. There are other cases where completely different types compare equal. Are you saying that these should "obviously" fail?

>>> 1 == 1.0 == 1 + 0j
True
>>> set([0]) == frozenset([0])
True
dmytrokyrychuk commented 9 years ago

In the first case all operands are kind of numbers. I don't think this one should fail. Neither should second case fail. frozenset is just an immutable implementation of set. Behavior of binary operations between sets and frozensets is described in the docs.

I am just pointing you to the examples whose content does not match the title. Please find the examples that actually describe the problem, or remove the wat.

Anyway, you don't seem interested in improving the list, so I'll just move forward. Sorry to bother you. Good luck!

cosmologicon commented 9 years ago

Yeah, I guess I don't see the distinction you're making, sorry. I don't see why you consider frozenset to be an immutable implementation of set, but you don't consider tuple to be an immutable implementation of list. They seem pretty analogous to me.

In the first case all operands are kind of numbers.

Right. And lists and tuples are both kinds of sequences. It seems so arbitrary to me. I just don't see where you're getting your intuition from. Just curious, do all of the following match your intuition?

>>> from collections import *
>>> from heapq import *
>>> from array import *
>>> OrderedDict() == dict()
True
>>> OrderedDict([(0,1),(2,3)]) == OrderedDict([(2,3),(0,1)])
False
>>> defaultdict(int) == dict()
True
>>> Counter() == dict()
True
>>> Counter() == OrderedDict()
False
>>> namedtuple("x", "a")(1) == (1,)
True
>>> namedtuple("x", "a")(1) == namedtuple("x", "b")(1)
False
>>> deque() == []
True
>>> heapify([]) == []
False
>>> array("u") == []
False
dmytrokyrychuk commented 9 years ago

I don't see why you consider frozenset to be an immutable implementation of set, but you don't consider tuple to be an immutable implementation of list.

That's what the python docs says.

And lists and tuples are both kinds of sequences.

So as strings. You don't think that '123' == ('1', '2', '3') should return True, don't you?

I just don't see where you're getting your intuition from. Just curious, do all of the following match your intuition?

I don't have any super powers, I have an experience. I just know the tools I work with. And I am simply trying to share my experience. Sorry if it was inappropriate or if my comments were incorrect.

If you're really curious, I didn't predict the result of statements involving namedtuple, heapq and array, because I rarely use them.

cosmologicon commented 8 years ago

That's what the python docs says.

That's the crux of the matter, in my humble opinion. Pretty much all wats can be explained if you go to the docs. Certainly all the JavaScript ones in the original wat talk fall into that category. There's nothing in the API or the way you interact with the types that tells you that set and frozenset are the same kind of thing, but list and tuple aren't. If your intuition on this matter comes from a careful reading of the documentation and nowhere else, that's a prime wat.

Strings and tuples, for instance, behave quite differently in a few important ways. The in operator is completely different, and when you call str(tuple(s)) you don't get the original string back. You need to use "".join. Most tuples in general can't be converted into strings at all, and even when it works, tuple("".join(t)) doesn't always give you back the original tuple. That's the sort of language feature that tells you these are different kinds of things. And I don't see anything like that when it comes to list/tuple, relative to set/frozenset. Again, just my opinion.

apragacz commented 8 years ago

I'm adding my argument here to the case of comparing list with list and iterator with iterator from issue #27 ("Fun with iterators" section is not a WAT):

The sorted function returns a list instead of an iterator. It's explicitly written in the documentation and therefore explains the behavior (you can compare lists structurally, but you can't do that obviously with the iterators without iterating them).