On May 14, 2020, at 03:35, Steven D'Aprano <st...@pearwood.info> wrote: > > On Sun, May 10, 2020 at 09:36:14PM -0700, Andrew Barnert via Python-ideas > wrote: > > >>> for i in itertools.seq_view(a_list)[::2]: >>> ... >>> >>> I still think I prefer this though: >>> >>> for i in a_list.view[::2]: >>> ... > >> Agreed. A property on sequences would be best, > > Why?
Because the whole point of this is for something to apply slicing syntax to. And compare: lst.view[10:20] view(lst)[10:20] vjew(lst, 10, 20) The last one is clearly the worst, because it doesn’t let you use slicing syntax. The others are both OK, but the first seems the most readable. I’ll give more detailed reasons below. (There may be reasons why it can’t or shouldn’t be done, which is why I ranked all of the options in order rather than just insisting that we must have the first one or I hate his whole idea.) > This leads to the same problem that len() solves by being a function, > not a method on list and tuple and str and bytes and dict and deque and > .... Making views a method or property means that every sequence type > needs to implement it's own method, or inherit from the same base class, But len doesn’t solve that problem at all, and isn’t meant to. It just means that every sequence type has to implement __len__ instead of every sequence type having to implement len. Protocols often provide some added functionality. iter() doesn’t just call __iter__, it can also fall back to old-style sequence methods, and it has the 2-arg form. Similarly, str() falls back to __repr__, and has other parameter forms, and doubles as the constructor for the string type. And next() even changed from being a normal method to a protocol and function, breaking backward compatibility, specifically to make it easier to do the 2-arg form. But len() isn’t like that. There is no fallback, no added behavior, nothing. It doesn’t add anything. So why do we have it? Guido’s argument is in the FAQ. It starts off with “For some operations, prefix notation just reads better than postfix”. He then backs up the general principle that this is sometimes true by appeal to math. And then he explains the reasons this is one of those operations by arguing that “len”’is the most important piece of information here so it belongs first. It’s the same principle here, but the specific answer is different. View-ness is not more important than the sequence and the slicing, so it doesn’t call out to be fronted. In fact, view-ness is (at least in the user’s mind) strongly tied to the slicing, so it calls out to be near the slice. And it’s not like this is some unprecedented thing. Most of the collection types, and corresponding ABCs, have regular methods as well as protocol dunders. Is anyone ever confused by having to write xs.index(x) instead of index(xs, x)? I don’t think so. In fact, I think the latter would be _more_ confusing, because “index” has so many different meanings that “list.index” is useful to nail it down. (Notice that we already _have_ a dunder named __index__, and it does something totally different…) And the same is true for “view”. In fact, everything in your argument is so generic that it acts as an argument against not just .index() but against any public methods or attributes on anything. Obviously you didn’t intend it that way, but once you actually target it so that it argues against .len() but not .index(), I don’t think there’s any argument against .view left. > and that's why in the Java world nobody agrees what method to call to > get the length of an object. Nobody can agree on what function to call in C or PHP even though they’re functions rather than methods in those languages. Everyone can agree on what method to use in C++ and Smalltalk even though they’re methods in those languages, just like Java. (In fact, C++ even loosely enforces consistency the same way Python loosely does, except at compile time instead of run time—if your class doesn’t have a size() method, it doesn’t duck type as a collection and therefore can’t be used in templates that want a collection.) Or just look at Python: nobody is confused about how to spell the .index method even though it’s a method. So the problem in Java has nothing to do with methods. (We don’t have to get into what’s wrong with Java here; it’s not relevant.) > So if we are to have a generic view proxy object, as opposed to the very > much non-generic dict views, then it ought to be a callable function We don’t actually _know_ how generic it can/should be yet. That’s something we’ve been discussing in this thread. It might well be a quality-of-implementation issue that has different best answers in different Pythons. Or it might not. It’s not obvious. Which implies that whatever the answer is, it’s not something that people should have to grasp it to understand the feature. You wouldn’t want to users to base their understanding of iter on knowing whether there’s one generic sequence iterator type or one for each type (especially since neither is true in CPython, but something halfway between and more complicated). And I think the same is true here. So you’re arguing for a callable function because it strongly implies a generic implementation, but I see that as an argument _against_ a function, not for it, and I also don’t think the argument holds anyway because it doesn’t imply any such thing for iter. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/RUR25QPBCANNSH2V7JHMX2EW7LBWLWHS/ Code of Conduct: http://python.org/psf/codeofconduct/