On Fri, Jul 31, 2020 at 4:12 PM Christopher Barker firstname.lastname@example.org wrote:
On Fri, Jul 31, 2020 at 2:56 PM Marco Sulla Marco.Sulla.Python@gmail.com wrote:
Yes. Since now dicts are ordered by insertion, also keys, values and items are ordered the same way.
Preservation of oider was codified in version 3.7 (? at some point, anyway). And while it may not explicitly say that the views will present the same order, I haven't heard anyone complain about that in this discussion.
It happened in the implementation in 3.6, and in 3.7 we added it as a guarantee to the language reference. But this means you can count on it since 3.6.
So: dicts preserve order the dict_views preserve this same order
Some think that we can't call them "ordered", because somehow that implies other things, like the ability to insert, etc, but while I don't get that argument, fine, let's call them "order preserving".
Meh, who cares. (The confusion is usually between "ordered" and "sorted" but we're past that here, so let's just keep saying "ordered".)
So in terms of what is defined by the language, and what is technically
possible, dict views could be indexed and sliced with clear semantics. Most other Sequence operations are not possible, so no, dicts are not Sequences, and the dict views aren't either. So we won't register them with the Sequence ABC, no problem.
So why not add this? Form what I can tell from this thread, there are these reasons:
- Because adding ANYTHING new is taking on a commitment to preserve it in
the future, and it's more code to write, maintain, and document. So regardless of any other argument, it shouldn't be added without a reasonable use case(s) -- what's reasonable is subjective, of course.
- Because it could be an "attractive nuisance" while dicts are order
preserving, their internal structure is such that you cannot find the nth item without iterating through n items, making access O(n), rather than O(1) for access by key or access of the usual Sequences -- Folks expect numerical indexing to be O(1), so it could be tricky. However, the only other way to get an n'th item is to copy everything into a Sequence, which is a lot slower, or to use islice or next() to do the order N access by hand. So this is an attractive nuisance in the use case of wanting to take multiple items by index, in which case, making a sequence first would be better than directly accessing the dict_view object.
If true this would be a huge argument against adding indexing and slicing (other than the special case starting with 0). However, I don't think it's true. The dict implementation (again, starting in 3.6) actually stores the list of keys in a compact array, in the insertion order. The hash table stores indices into this array. Moreover, in order to implement the ordered property, you pretty much have to do this (since the hash table *definitely* isn't going to be ordered :-). So indexing and slicing into this array would seem to be possible, unless I am missing something. I'm CC"ing Inada Naoki because it's his code -- maybe he can enlighten us.
- dicts are not Sequences, they are Mappings, so they shouldn't have
Sequence features. dict_views are Sets, not Sequences, so they shouldn't have Sequence features.
Right, I said this (with more words) in my last email, a few minutes ago.
Point 3) I may have misrepresented it, it was explained in a lot more
detail, but I'm pretty sure that's what it comes down to. But I'm going to talk about my understanding of the point, which is pretty much how I wrote it. If I really did misrepresent it, then feel free to kibitz some more....
It seems like I have a different philosophy about typing and duck typing than some in this converstaion. I appreciate the ABCs, and that they clearly nail down what types need to be in order to "BE" one of the ABCs -- and see how this is useful. But I don't see it as restrictive. An object is not a Sequence unless it fully conforms to the Sequence ABC, sure. But that doesn't mean an object can't have some, but not all, of the behavior of a Sequence without having all the rest. In this example, implementing integer indexing and slicing on dict_views would not make them a Sequence, but that doesn't mean you can't do it. It's also the case that any type can BE a particular ABC, and still have other functionality. So, in this case, the dict_views are Sets, but we can add other things to them of course.
And indeed, here our philosophies diverge (see my last email).
So on to "duck typing" -- the term is comes from the aphorism: "If it looks like a duck, swims like a duck, and quacks like a duck, then it probably *is* a duck" (https://en.wikipedia.org/wiki/Duck_test).
So that pretty much maps to ABCs: the ABC for a duck specifies what a duck is -- it's something that looks, swims, and quacks like a duck.
But I've always taken a more flexible view on duck typing -- if I want to know if it's a duck, yes, I need the ABC. But I don't usually care if it's a duck -- I care if it does the one or two things I need it to do. So if I need a quacker, then anything that quacks like a duck is fine with me, even if it can't swim.
We all used to think this way, until we discovered that it's *really* hard to tell whether something's a mapping or a sequence if the only operation you care about is `__getitem__`, since they both support that, but with very different semantics. So people started checking for the presence of a `keys` method to tell these apart, and that's really quite appalling. Hence the ABCs. I don't want to get into a similar situation with Set and Sequence, ever.
And even though currently they *don't* have overlapping operations, the concrete types `list` and `set` *do* run into this kind of thing for comparison operators -- lists (and tuples) compare itemwise until a difference is found, while sets use comparisons to implement subset/superset tests. The ice really is rather thin here.
I don't have anything to add to the rest of your post, so I'll leave that out (but thanks for writing it).