On Wed, Sep 30, 2015 at 9:53 AM, Neil Girdhar wrote:
Can you help understand how this is a Liskov substitution violation?  A Sequence is an Iterator.  Getting the sequence back should never hurt.

no but getting a non-sequence iterator back when you expect a sequence sure can hurt.

which is why I said that if you want a sequence back from enumerate, it should always return a sequence. which could (should) be lazy-evaluated.

I think Neil's point is that calling list() or tuple() on it requires that the entire sequence be evaluated and stored -- if you really only want one item (and especially not one at the end), that could be a pretty big performance hit.

Which makes me wonder why ALL iterators couldn't support indexing? It might work like crap in some cases, but wouldn't it always be as good or better than wrapping it in a tuple? And then some cases (like enumerate) could do an index operation efficiently when they are working with "real" sequences.

Maybe a generic lazy_sequence object that could be wrapped around an iterator to create a lazy-evaluating sequence??

-CHB

On Wed, Sep 30, 2015 at 12:43 PM Brett Cannon <brett@python.org> wrote:
On Wed, 30 Sep 2015 at 09:38 Neil Girdhar <mistersheik@gmail.com> wrote:
In fairness, one is a superset of the other.  You always get an Iterable.  You sometimes get a Sequence.  It's a bit like multiplication? with integers you get integers, with floats, you get floats.

No, it's not like multiplication. =) I hate saying this since I think it's tossed around too much, but int/float substitution doesn't lead to a Liskov substitution violation like substituting out a sequence for an iterator (which is what will happen if the type of the argument to `enumerate` changes). And since you can just call `list` or `tuple` on enumerate and get exactly what you're after without potential bugs cropping up if you don't realize from afar you're affecting an assumption someone made, I'm -1000 on this idea.

-Brett

On Wed, Sep 30, 2015 at 12:35 PM Brett Cannon <brett@python.org> wrote:
On Wed, 30 Sep 2015 at 08:28 Neil Girdhar <mistersheik@gmail.com> wrote:
What are the pros and cons of making enumerate a sequence if its argument is a sequence?

I found myself writing:

for vertex, height in zip(
self.cache.height_to_vertex[height_slice],
range(height_slice.start, height_slice.stop)):

I would have preferred:

for height, vertex in enumerate(
self.cache.height_to_vertex)[height_slice]:

Because you now suddenly have different types and semantics of what enumerate() returns based on its argument which is easy to mess up if self.cache.height_to_vertex became an iterator object itself instead of a sequence object. It's also not hard to simply do `tuple(enumerate(...))` to get the exact semantics you want: TOOWTDI.

IOW all I see are cons. =)

_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris.Barker@noaa.gov