[Python-ideas] Re: Adding slice Iterator to Sequences (was: islice with actual slices)

2020-05-15 Thread Steven D'Aprano
On Fri, May 15, 2020 at 05:44:59PM -0700, Andrew Barnert wrote:

> Once you go with a separate view-creating function (or type), do we even need 
> the dunder?

Possibly not. But the beauty of a protocol is that it can work even if 
the object doesn't define a `__view__` dunder.

- If the object defines `__view__`, call it; this allows objects to 
  return an optimized view, if it makes sense to them; e.g. bytes 
  might simply return a memoryview.

- If not, fall back on a generic view object that just does index 
  arithmetic and delegation.



-- 
Steven
___
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/4R5CRI2MJP3R4PZPDRTDZFYOCDPSP3I2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Adding slice Iterator to Sequences (was: islice with actual slices)

2020-05-15 Thread Steven D'Aprano
On Fri, May 15, 2020 at 01:00:09PM -0700, Christopher Barker wrote:

> I know you winked there, but frankly, there isn't a clear most Pythonic API
> here. Surely you do'nt think PYhton should have no methods?

That's not what I said. Of course Python should have methods -- it's an 
OOP language after all, and it's pretty hard to have objects unless they 
have behaviour (methods). Objects with no behaviour are just structs.

But seriously, and this time no winking, Python's design philosophy is 
very different from that of Java and even Ruby and protocols are a 
hugely important part of that. Python without protocols wouldn't be 
Python, and it would be a much lesser language.

[Aside: despite what the Zen says, I think *protocols* are far more 
important to Python than *namespaces*.]

Python tends to have shallow inheritance hierarchies; Java has deep 
ones. Likewise Ruby tends to have related classes inherit from 
generic superclasses that provide default implementations.

In we were like Ruby, there would be no problem: we'd just add a view 
method to something like object.Collections.Sequence and instantly all 
lists, tuples, range objects, strings, bytes, bytearrays etc would have 
that method. But we're not. In practice, each type would have to 
implement it's own view method.

Python tends to use protocol-based top-level functions:

len, int, str, repr, bool, iter, list

etc are all based on *protocols*, not inheritance. The most notable 
counter-example to that was `iterator.next` which turned out to be a 
mistake and was changed in Python 3 to become a protocol based on a 
dunder.

That's not to say that methods aren't sometimes appropriate, or that 
there may not be grey areas where we could go either way. But in 
general, the use of protocols is such a notable part of Python, and 
so unusual in other OOP languages, that it trips up newcomers often 
enough that there is a FAQ about it:

https://docs.python.org/3/faq/design.html#why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list

although the answer is woefully incomplete. See here for a longer 
version:

http://effbot.org/pyfaq/why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list.htm

There is a *lot* of hate for Python's use of protocols, especially among 
people who have drunk the "not real object oriented" Koolaid, e.g. see 
comments here:

https://stackoverflow.com/questions/237128/why-does-python-code-use-len-function-instead-of-a-length-method

where this is described as "moronic". Let me be absolutely clear here: 
the use of protocols, as Python does, is a *brilliant* design, not a 
flaw, and in my opinion the haters are falling into the Blub trap:

http://paulgraham.com/avg.html

Using protocols looks moronic to them because they haven't seen how they 
add more power to the language and the coder. All they see are the ugly 
underscores. Why write a `__len__` method instead of a `len` method? 
There's no difference except four extra characters.

That's some real Blub thinking right there.

Unfortunately, len() hardly takes advantage of the possibilities of 
protocols, so it's an *obvious* example but not a *good* example. Here's 
a better example:

py> class NoContains:
... def __getitem__(self, idx):
... if idx < 10:
... return 1000+idx
... raise IndexError
...
py> 1005 in NoContains()
True

I wrote a class that doesn't define or inherit a `__contains__` method, 
but I got support for the `in` operator for free just by supporting 
subscripting. If you don't understand protocols, this is just weird. But 
that's your loss, not a design flaw.

Another good example is `next()`. When I write an iterator class, I can 
supply a `__next__` dunder. All it needs to do is provide the next 
value.

I've never needed to add support for default values in a `__next__` 
method, because the builtin `next()` handles it for me:

_SENTINEL = object()
try:
...
except StopIteration:
if default is not _SENTINEL:
return default
raise

I get support for default values for free, thanks to the use of a 
protocol. If this were Python 2, with a `next` method, I'd have needed 
to write those six lines a couple of hundred times so far in my life, 
plus tests, plus documentation. Multiply that by tens of thousands of 
Python coders.

Some day, if the next() builtin grows new functionality to change the 
exception raised:

next(iterator, raise_instead=ValueError)

not one single iterator class out of a million in the world will need to 
change a single line of code in order to get the new functionality.

This is amazingly powerful stuff when handled properly, and len() is 
perhaps the most boring and trivial example of it.

I'm going to be provocative: if (generic) you are not blown away by 
the possibilities of protocols, you don't understand them.




[Python-ideas] Re: Adding slice Iterator to Sequences (was: islice with actual slices)

2020-05-15 Thread Andrew Barnert via Python-ideas
On May 15, 2020, at 18:21, Christopher Barker  wrote:
> 
> Hmm, more thought needed.

Speaking of “more thought needed”, I took a first pass over cleaning up my 
quick slice view class and adding the slicer class, and found some 
bikesheddable options. I think in most cases the best answer is obvious, but 
I’ve been wrong before. :)

Assume s and t are Sequences of the same type, u is a Sequence or a different 
type, and vs, vt, and vu are view slices on those sequences. Also assume that 
we called the view slicer type vslice, and the view slice type SliceView, 
although obviously those are up for bikeshedding.

When s==t is allowed, is vs==vt? What about vs==t? Same for <, etc.? I think 
yes, yes, yes.

When s is hashable, is vs hashable? If so, is it the same hash an equivalent 
copy-slice would have? The answer to == constrains the answer here, of course. 
I think they can just not be hashable, but it’s a bit weird to have an 
immutable builtin sequence that isn’t. (Maybe hash could be left out but then 
added in a future version if there’s a need?)

When s+t is allowed, is vs+t? vs+vt? (Similarly when s+u is allowed, but that 
usually isn’t.) vs*3? I think all yes, but I’m not sure. (Imagine you create a 
million view slices but filter them down to just 2, and then concatenate those 
two. That makes sense, I think.)

Should there be a way to ask vs for the corresponding regular copy slice? Like 
vslice(s)[10:].strictify() == s[10:]? I’m not sure what it’s good for, but 
either __hash__ or __add__ seems to imply a private method for this, and then I 
can’t see any reason to prevent people from calling it. (Except that I can’t 
think of a good name.)

Should the underlying sequence be a public attribute? It seems easy and 
harmless and potentially useful, and memoryview has .obj (although dict views 
don’t have a public reference to the dict).

What about the original slice object? This seems less useful, since you don’t 
pass around slice objects that often. And we may not actually be storing it. 
(The simplest solution is to store slice.indices(len(seq)) instead of slice.) 
So I think no.

If s isn’t a Sequence, should vslice(s) be a TypeError. I think we want the C 
API sequence check, but not the full ABC check.

What does vslice(s)[1] do? I think TyoeError('not a slice').

Does the vslice type need any other methods besides __new__ and __getitem__? I 
don’t think so. The only use for vslice(s) besides slicing it is stashing it to 
be sliced later, just like the only use for a method besides calling it is 
stashing it to be called later. But it should have the sequence as a public 
attribute for debugging/introspection, just like methods make their self and 
function attributes public. 

Is the SliceView type public? (Only in types?) Or is “what the vslice slicer 
factory creates” an implementation detail, like list_iter. I think the latter.

What’s the repr for a SliceView? Something like vslice([1, 2, 10, 20])[::2] 
seems most useful, since that’s the way you construct it, even if it is a bit 
unusual. Although a tiny slice of a giant sequence would then have a giant repr.

What’s the str? I think same as the repr, but will people expect a view of a 
list/tuple/etc. to look “nice” like list/tuple/etc. do?

Does vs[:] return self? (And, presumably, vs[0:len(s)+100] and so on.) I think 
so, but that doesn’t need to be guaranteed (just like tuple, range, etc.).

If vs is an instance of a subclass of SliceView, is vs[10:20] a SliceView, or 
an instance of the subclass? I think the base class, just like tuple, etc.

___
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/X45QVVPMB5JOQDKI7OEV4JAQ7WMA4XHO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Adding slice Iterator to Sequences (was: islice with actual slices)

2020-05-15 Thread Andrew Barnert via Python-ideas
On May 15, 2020, at 18:21, Christopher Barker  wrote:
> 
>> On Fri, May 15, 2020 at 5:45 PM Andrew Barnert  wrote:
> 
>> On May 15, 2020, at 13:03, Christopher Barker  wrote:
>> > 
>> > Taking all that into account, if we want to add "something" to Sequence 
>> > behavior (in this case a sequence_view object), then adding a dunder is 
>> > really the only option -- you'd need a really compelling reason to add a 
>> > Sequence method, and since there are quite a few folks that think that's 
>> > the wrong approach anyway, we don't have a compelling reason.
>> > 
>> > So IF a sequence_view is to be added, then a dunder is really the only 
>> > option.
>> 
>> Once you go with a separate view-creating function (or type), do we even 
>> need the dunder?
> 
> Indeed -- maybe not. We'd need a dunder if we wanted to make it an "official" 
> part of the Sequence protocol/ABC, but as you point out there may be no need 
> to do that at all.

That’s actually a what triggered this thought. We need collections.abc.Sequence 
to support the dunder with a default implementation so code using it as a mixin 
works. What would that default implementation be? Basically just a class whose 
__getitem__ constructs the thing I posted earlier and that does nothing else. 
And why would anyone want to override that default?

Being able to override dunders like __in__ and regular methods like count is 
useful for multiple reasons: a string-like class needs to extend their behavior 
for substring searching, a range-like class can implement them without 
searching at all, etc. But none of those seemed to apply to overriding 
__viewslice__ (or whatever we’d call it).

> Hmm, more thought needed.

Yeah, certainly just because I couldn’t think of a use doesn’t mean there isn’t 
one.

But if I’m right that the dunder could be retrofitted in later (I want to try 
building an implementation without the dunder and then retrofitting one in 
along with a class that overrides it, if I get the time this weekend, to verify 
that it really isn’t a problem), that seems like a much better case for leaving 
it out.

Another point: now that we’re thinking generic function (albeit maybe a C 
builtin with fast-path code for list/tuple), maybe it’s worth putting an 
implementation on PyPI as soon as possible, so we can get some experience using 
it and make sure the design doesn’t have any unexpected holes and, if we’re 
lucky, get some uptake from people outside this thread.___
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/VSGQLYF6B25BB6KLZALMYST7IQWMVI3I/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Adding slice Iterator to Sequences (was: islice with actual slices)

2020-05-15 Thread Christopher Barker
On Fri, May 15, 2020 at 5:45 PM Andrew Barnert  wrote:

> On May 15, 2020, at 13:03, Christopher Barker  wrote:
> >
> > Taking all that into account, if we want to add "something" to Sequence
> behavior (in this case a sequence_view object), then adding a dunder is
> really the only option -- you'd need a really compelling reason to add a
> Sequence method, and since there are quite a few folks that think that's
> the wrong approach anyway, we don't have a compelling reason.
> >
> > So IF a sequence_view is to be added, then a dunder is really the only
> option.
>
> Once you go with a separate view-creating function (or type), do we even
> need the dunder?
>

Indeed -- maybe not. We'd need a dunder if we wanted to make it an
"official" part of the Sequence protocol/ABC, but as you point out there
may be no need to do that at all.

Hmm, more thought needed.

-CHB


>
> I’m pretty sure a generic slice-view-wrapper (that just does index
> arithmetic and delegates) will work correctly on every sequence type. I
> won’t promise that the one I posted early in this thread does, of course,
> and obviously we need a bit more proof than “I’m pretty sure…”, but can
> anyone think of a way a Sequence could legally work that would break this?
>
> And I can’t think of any custom features a Sequence might want add to its
> view slices (or its view-slice-making wrapper).
>
> I can definitely see how a custom wrapper for list and tuple could be
> faster, and imagine how real life code could use it often enough that this
> matters. But if it’s just list and tuple, CPython’s already full of
> builtins that fast-path on list and tuple, and there’s no reason this one
> can’t do the same thing.
>
> So, it seems like it only needs a dunder if there are likely to be
> third-party classes that can do view-slicing significantly faster than a
> generic view-slicer, and are used in code where it’s likely to matter. Can
> anyone think of such a case? (At first numpy seems like an obvious answer.
> Arrays aren’t Sequences, but I think as long as the wrapper doesn’t
> actually type-check that at __new__ time they’d work anyway. But why would
> anyone, especially when they care about speed, use a generic viewslice
> function on a numpy array instead of just using numpy’s own view slicing?)
>
> It seems like a dunder is something that could be added as a refinement in
> the next Python version, if it turns out to be needed. If so, then, unless
> we have an example in advance to disprove the YAGNI presumption, why not
> just do it without the dunder?
>
>
>

-- 
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
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/6OZYSHPJOAJWDHQAR5VITAP5KEPSVUKF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Improve handling of Unicode quotes and hyphens

2020-05-15 Thread Andrew Barnert via Python-ideas
On May 14, 2020, at 20:01, Stephen J. Turnbull 
 wrote:
> 
> Executive summary:
> 
> AFAICT, my guess at what's going on in the C tokenizer was exactly
> right.  It greedily consumes as many non-operator, non-whitespace
> characters as possible, then validates.  

Well, it like like it’s not quite “non-operator, non-whitespace characters”, 
but rather “ASCII identifier or non-ASCII characters”:

>  (c >= 'a' && c <= 'z')\
>   || (c >= 'A' && c <= 'Z')\
>   || c == '_'\
>   || (c >= 128))

(That’s the initial char rule; the continuing char rule is similar but of 
course allows digits.)

So it won’t treat a $ or a ^G as potentially part of an identifier, so the 
caret will show up in the right place for one of those, but it will treat an 
emoji as potentially part of an identifier, so (if that emoji is immediately 
followed by legal identifier characters, ASCII or otherwise) the caret will 
show up too far to the right.

I’m still glad the Python tokenizer doesn’t do this (because, as I said, I’ve 
relied on the documented behavior in import hooks for playing around with 
Python, and they use the Python tokenizer), but that doesn’t matter for the C 
tokenizer, because its output is not public, it’s only seen by the parser. And 
I think you can prove that the error caret placement is the only thing that 
could be affected by this shortcut.[1] And if it makes the tokenizer faster, or 
just simpler to maintain, that could easily be worth it.

(At least until one of those periodic “Python should add this Unicode operator” 
proposals actually gets some traction, but I don’t see that as likely any time 
soon.)

—-

[1] Python only allows non-ASCII characters in identifiers, strings, and 
comments. Therefore, any string of characters that should be tokenized as a 
sequence of 1 ERRORTOKEN followed by 0 or more NAME and ERRORTOKEN tokens by 
the documented rule (and the Python code) will still give you a sequence of 1 
ERRORTOKEN followed by 0 or more NAME and ERRORTOKEN tokens by the C code, just 
not necessarily the same such sequence. And any such sequence will be parsed as 
a SyntaxError pointing at the end of the initial ERRORTOKEN. So, the caret 
might be somewhere else within that block of identifier and non-ASCII 
characters, but it will be somewhere within that block.
___
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/LPLKLECRRW2UEONMN6RAROU5HKKQC6XO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Adding slice Iterator to Sequences (was: islice with actual slices)

2020-05-15 Thread Andrew Barnert via Python-ideas
On May 15, 2020, at 13:03, Christopher Barker  wrote:
> 
> Taking all that into account, if we want to add "something" to Sequence 
> behavior (in this case a sequence_view object), then adding a dunder is 
> really the only option -- you'd need a really compelling reason to add a 
> Sequence method, and since there are quite a few folks that think that's the 
> wrong approach anyway, we don't have a compelling reason.
> 
> So IF a sequence_view is to be added, then a dunder is really the only option.

Once you go with a separate view-creating function (or type), do we even need 
the dunder?

I’m pretty sure a generic slice-view-wrapper (that just does index arithmetic 
and delegates) will work correctly on every sequence type. I won’t promise that 
the one I posted early in this thread does, of course, and obviously we need a 
bit more proof than “I’m pretty sure…”, but can anyone think of a way a 
Sequence could legally work that would break this?

And I can’t think of any custom features a Sequence might want add to its view 
slices (or its view-slice-making wrapper).

I can definitely see how a custom wrapper for list and tuple could be faster, 
and imagine how real life code could use it often enough that this matters. But 
if it’s just list and tuple, CPython’s already full of builtins that fast-path 
on list and tuple, and there’s no reason this one can’t do the same thing.

So, it seems like it only needs a dunder if there are likely to be third-party 
classes that can do view-slicing significantly faster than a generic 
view-slicer, and are used in code where it’s likely to matter. Can anyone think 
of such a case? (At first numpy seems like an obvious answer. Arrays aren’t 
Sequences, but I think as long as the wrapper doesn’t actually type-check that 
at __new__ time they’d work anyway. But why would anyone, especially when they 
care about speed, use a generic viewslice function on a numpy array instead of 
just using numpy’s own view slicing?)

It seems like a dunder is something that could be added as a refinement in the 
next Python version, if it turns out to be needed. If so, then, unless we have 
an example in advance to disprove the YAGNI presumption, why not just do it 
without the dunder?

___
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/G3L6NP4PWPR2O2VSVXGGJNALYECKDG5G/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Adding slice Iterator to Sequences (was: islice with actual slices)

2020-05-15 Thread Andrew Barnert via Python-ideas
On May 15, 2020, at 03:50, Steven D'Aprano  wrote:
> 
> On Thu, May 14, 2020 at 09:47:36AM -0700, Andrew Barnert wrote:
>>> On May 14, 2020, at 03:01, Steven D'Aprano  wrote:
>>> 
>> Which is exactly why Christopher said from the start of this thread, 
>> and everyone else has agreed at every step of the way, that we can’t 
>> change the default behavior of slicing, we have to instead add some 
>> new way to specifically ask for something different.
> 
> Which is why I was so surprised that you suddenly started talking about 
> not being able to insert into a slice of a list rather than a view.

We’re talking about slice views. The sentence you quoted and responded to was 
about the difference between a slice view from a list and a slice view from a 
string. A slice view from a list may or may not be the same type as a slice 
view from a tuple (I don’t think there’s a reason to care whether they are or 
not), but either way, it being immutable will, I think, not surprise anyone. By 
contrast, a slice view from a string being not stringy _might_ surprise someone.

>> Not only that, but whatever gives 
>> you view-slicing must look sufficiently different that you notice the 
>> difference—and ideally that gives you something you can look up if you 
>> don’t know what it means. I think lst.view[10:20] fits that bill.
> 
> Have we forgotten how to look at prior art all of a sudden? Suddenly 
> been possessed by the spirits of deceased Java and Ruby programmers 
> intent on changing the look and feel of Python to make it "real object 
> oriented"? *wink*

No, we have remembered that language design is not made up of trivial rules 
like “functions good, methods bad”, but of understanding the tradeoffs and how 
they apply in each case. 

> We have prior art here:
> 
>b'abcd'.memoryview  # No, not this.
>memoryview(b'abcd')  # That's the one.

>'abcd'.iter  # No, not that either.
>iter('abcd')  # That's it
> 
> In fairness, I do have to point out that dict views do use a method 
> interface,

This is a secondary issue that I’ll come back to, but first: the whole thing 
that this started off with is being able to use slicing syntax even when you 
don’t want a copy.

The parallel to the prior art is obvious:

itertools.islice(seq, 10, 20) # if you don’t care about iterator or view
sliceviews.slice(seq, 10, 20) # if you do

The first one already exists. The second one takes 15 lines of code, which I 
slapped together and posted near the start of the thread.

The only problem is that they don’t solve the problem of “use slicing syntax”. 
But if that’s the entire point of the proposal (at least for Chris), that’s a 
pretty big problem.

Now, as we’d already been discussing (and as you quoted), you _could_ have a 
callable like this:

viewslice(seq)[10:20]

I can write that in only a few more lines than what I posted before, and it 
works. But it’s no longer parallel to the prior art. It’s not a function that 
returns a view, it’s a wrapper object that can be sliced to provide a view. 
There are pros and cons of this wrapper object vs. the property, but a false 
parallel with other functions is not one of them.

> 1. Dict views came with a lot of backwards-compatibility baggage; 
> they were initially methods that returned lists; then methods 
> that returned iterators were added, then methods that returned 
> views were added, and finally in 3.x the view methods were renamed and 
> the other six methods were removed.

This is, if anything, a reason they _shouldn’t_ have been methods. Changing the 
methods from 2.6 to 2.7 to 3.x, and in a way that tools like six couldn’t even 
help without making all of your code a bit uglier, was bad, and wouldn’t have 
been nearly as much of a problem if we’d just made them all functions in 2.6.

And yet, the reasons for them being methods were compelling enough that they 
remain methods in 3.x, despite that problem. That’s how tradeoffs work.

> 2. There is only a single builtin mapping object, dict, not like 
> sequences where there are lists, tuples, range objects, strings, byte 
> strings and bytearrays.

Well. there’s also mappingproxy, which is a builtin even if its name is only 
visible in types. And there are other mappings in the stdlib, as well as 
popular third-party libraries like SortedContainers. And they all support these 
methods. There are some legacy third-party libraries never fully updated for 
3.x still out there, but they don’t meet the Mapping protocol or its ABC.

So, how does this distinction matter?

Note that there is a nearly opposite argument for the wrapper object that 
someone already made that both seem a lot compelling to me: third-party types. 
We can’t change them overnight. And some of them might already have an 
attribute named view, or anything else we might come up with. Those are real 
negatives with the property design, in a way that “more of the code we _can_ 
easily change is in the Objects rather than Lib 

[Python-ideas] Re: Documenting iterators vs. iterables [was: Adding slice Iterator ...]

2020-05-15 Thread Andrew Barnert via Python-ideas
On May 14, 2020, at 20:17, Stephen J. Turnbull 
 wrote:
> 
> Andrew Barnert writes:
> 
>> Students often want to know why this doesn’t work:
>>   with open("file") as f:
>>   for line in file:
>>   do_stuff(line)
>>   for line in file:
>>   do_other_stuff(line)
> 
> Sure.  *Some* students do.  I've never gotten that question from mine,
> though I do occasionally see
> 
>   with open("file") as f:
>   for line in f:# ;-)
>   do_stuff(line)
>   with open("file") as f:
>   for line in f:
>   do_other_stuff(line)
> 
> I don't know, maybe they asked the student next to them. :-)

Or they got it off StackOverflow or Python-list or Quora or wherever. Those 
resources really do occasionally work as intended, providing answers to people 
who search without them having to ask a duplicate question. :)

>> The answer is that files are iterators, while lists are… well,
>> there is no word.
> 
> As Chris B said, sure there are words:  File objects are *already*
> iterators, while lists are *not*.  My question is, "why isn't that
> instructive?"

Well, it’s not _completely_ not instructive, it’s just not _sufficiently_ 
instructive.

Language is more useful when the concepts it names carve up the world in the 
same way you usually think about it.

Yes, it’s true that we can talk about “iterables that are not iterators”. But 
that doesn’t mean there’s no need for a word. We don’t technically need the 
word “liquid” because we could always talk about “compressibles that are not 
solid” (or “fluids that are not gas”); we don’t need the word “bird” because we 
could always talk about “diapsids that are not reptiles”; etc. Theoretically, 
English could express all the same propositions and questions and so on that it 
does today without those words. But practically, it would be harder to 
communicate with. And that’s why we have the words “bird” and “liquid”. And the 
reason we don’t have a word for all diapsids except birds and turtles is that 
we don’t need to communicate about that category. 

Natural languages get there naturally; jargon sometimes needs help.

>> We shouldn’t define everything up front, just the most important
>> things. But this is one of the most important things. People need
>> to understand this distinction very early on to use Python,
> 
> No, they don't.  They neither understand, nor (to a large extent) do
> they *need* to.

> ISTM that all we need to say is that
> 
> 1.  An *iterator* is a Python object whose only necessary function is
>   to return an object when next is applied to it.  Its purpose is to
>   keep track of "next" for *for*.  (It might do other useful things
>   for the user, eg, file objects.)
> 
> 2.  The *for* statement and the *next* builtin require an iterator
>   object to work.  Since for *always* needs an iterator object, it
>   automatically converts the "in" object to an iterator implicitly.
>   (Technical note: for the convenience of implementors of 'for',
>   when iter is applied to an iterator, it always returns the
>   iterator itself.)

I think this is more complicated than people need to know, or usually learn. 
People use for loops almost from the start, but many people get by with never 
calling next. All you need is the concept “thing that can be used in a for 
loop”, which we call “iterable”. Once you know that, everything else in Python 
that loops is the same as a for loop—the inputs to zip and enumerate are 
iterables, because they get looped over.

“Iterable” is the fundamental concept. Yeah, it sucks that it has such a clumsy 
word, but at least it has a word.

You don’t need the concept “iterator” here, much less need to know that looping 
uses iterables by calling iter() to get an iterator and then calling next() 
until StopIteration, until you get to the point of needing to read or write 
some code that iterates manually.

Of course you will need to learn the concept “iterator” pretty soon anyway, but 
only because Python actually gives you iterators all over the place. In a 
language (like Swift) where zip and enumerate were views, files weren’t 
iterable at all, etc., you wouldn’t need the concept “iterator” until very 
late, but in Python it shows up early. But you still don’t need to learn about 
next(); that’s as much a technical detail as the fact that they return self 
from iter(). You want to know whether they can be used in for loops—and they 
can, because (unlike in Swift) iterators are iterable, and you already 
understand that.

> 3.  When a "generic" iterator "runs out", it's exhausted, it's truly
>   done.  It is no longer useful, and there's nothing you can do but
>   throw it away.  Generic iterators do not have a reset method.
>   Specialized iterators may provide one, but most do not.

Yes, this is the next thing you need to know about iterators.

But you also need to know that many iterables don’t get consumed in this way. 
Lists, ranges, dicts, etc. do _not_ run out when you use 

[Python-ideas] Re: Adding slice Iterator to Sequences

2020-05-15 Thread Christopher Barker
 A

> > different method/property/class/function that gives you iterators
> > would be fine.
>
> We already have such.  It's called itertools.islice().
>

If you had read the proposal, you’d know that was brought up, obviously.

I'm sorry, but you're missing the point here.  You and Christopher seem
> to be having fun discussing this at great length, and that's fine.
> However at this point I've not grasped the proposal and I've lost the
> will to even contemplate the details.


Fair enough — I need to update the proposal with the new details.

What I have grasped is that no
> one else has offered much opinion, so saying that "everyone else has
> agreed at every step of the way" doesn't actually have the weight it
> pretends to.


Sure, but that was referring to a single point (changing how standard
Sequence slicing would work), and it’s not how I would have phrased it. I
might have said:

"no one has suggested otherwise"

If not one is proposing something, it doesn't much matter how many folks
have been involved in the conversation :-)

As for not many people having contributed to the conversation, I'm a bit
surprised -- there is a LOT of discussion about all kinds of ideas that are
never going to see the light of day.

Maybe that's a good sign -- if people don't pile on to tell me why it's a
bad idea, maybe it has a shot :-)

Or it's because I didn't put much text in email, but rather pointed to an
external git repo.

If/when I can find the time, I'll updated my ideas and post again.

-CHB
___
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/ZKGPR32CRJFH5VJ74GNCGOREJ5VRNICH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Documenting iterators vs. iterables

2020-05-15 Thread Christopher Barker
I think maybe some of the trouble here, particularly in teaching is the
word "is" (in English, not the Python keyword).

As in:

"A file object IS and iterator"
and
"A zip object IS an iterator"

I know in OO parlance, "is a" can be used to designate subclassing (or an
appropriate use for it) and it can be made a bit more generic to mean "has
the interface of" -- which is how we are using it here.

But in common language, there might be a bit of confusion:

something is an iterator among other things
vs
something is PRIMARILY an iterator

File objects are a good example:

A file object provides all sorts of things, and iteration is only a small
part of it. In fact, maybe due to my long history with working with
pre-iterator file objects (python 1.5! -- yes, I am that old) I see them as
fully featured objects that also happen to provide an iteration interface
to line-oriented access to text files as a convenience -- calling them "an
iterator" feels a bit odd.

Whereas things like the zip iterator, and many of the things in itertools,
do primarily (only) iteration -- calling them "an iterator" makes a huge
amount of sense. Even more so for things like list_iter, that are generally
hidden from the user, and exist only to provide iteration.

In fact, that's why I think file objects may be one of the worst ways to
introduce the iteration protocol to newbies. (though maybe because of the
confusion, it's a good example of why it matters to understand the
distinctions)

Iterables, on the other hand, usually provide a bunch of functionally other
than iterability -- and indeed, most are fully functional without the
iterator protocol at all. (maybe with ugly code :-) )

-CHB




On Fri, May 15, 2020 at 6:14 AM Steven D'Aprano  wrote:

> On Fri, May 15, 2020 at 05:58:16AM -0400, Ricky Teachey wrote:
>
> > Perhaps use the iter function name as the generic? "itered". As opposed
> to
> > "iterated" or "iterated over".
> >
> > Example:
> >
> > "the statement below iterates over an iterator, itered from a sequence"
>
> Or just avoid the issue:
>
> "The statement below iterates over a sequence"
>
> which is perfectly valid and correct.
>
> If we do feel the need to drill down into pedantic technical details,
> instead of making up ugly words that nobody will have any clue
> whatsoever what the meaning is[1], we could use one of many existing
> English words:
>
> built from
> formed from
> constructed from
> made from
> fabricated from
> created from
> put together from
>
> etc. And notice I avoided using terms which imply that the sequence
> itself is transformed into an iterator, such as "converting into".
>
>
>
>
> [1] "Iter" is an old term for a passage, in particular an anatomical
> term for a passage in the brain, so "itered" would be the past tense of
> a verb to turn something into a passage.
>
>
> --
> Steven
> ___
> 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/CQM25AACCSW4AG3M6OG6DGTKCGHOVB4N/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
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/GCO7224VEMRUHLR2Z3DIS34WKOFJRGBD/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Adding slice Iterator to Sequences (was: islice with actual slices)

2020-05-15 Thread Christopher Barker
TL;DR: no need to come to consensus about the most "Pythonic" API for a
sequence view -- due to potential name clashes, adding a dunder is pretty
much the only option.

Details below:

On Fri, May 15, 2020 at 3:50 AM Steven D'Aprano  wrote:

>  I think lst.view[10:20] fits that bill.
>
> Have we forgotten how to look at prior art all of a sudden? Suddenly
> been possessed by the spirits of deceased Java and Ruby programmers
> intent on changing the look and feel of Python to make it "real object
> oriented"? *wink*
>

I know you winked there, but frankly, there isn't a clear most Pythonic API
here. Surely you do'nt think PYhton should have no methods?


> We have prior art here:
> b'abcd'.memoryview  # No, not this.
> memoryview(b'abcd')  # That's the one.
>

That's not the ideal example, memoryviews are a real oddball -- they are
designed very much to be supported by third party applications. And a
memoryview object is a type, unlike, say, len(). Though I guess we'd be
talking about a "view" type here as well.

'abcd'.iter  # No, not that either.
> iter('abcd')  # That's it.
>

That's closer -- it certainly could have been added to the Iterable ABC.

>  In fairness, I do have to point out that dict views do use a method

> interface, but:
>
> 1. Dict views came with a lot of backwards-compatibility baggage;
>

I think this is really the key point here. Not so much the "baggage", but
the fact that dicts (and therefor Mappings) have always had .keys, .values,
and .items.

so adding the views didn't add or remove any new attributes,

2. There is only a single builtin mapping object, dict, not like
> sequences where there are lists, tuples, range objects, strings, byte
> strings and bytearrays.
>

True, but there are multiple Mapping objects in the Standard Library, at it
is the intenet that the Mapping ABCs can be used by third party classes --
so I'm not sure that is such a big distinction.

3. Dicts need three kinds of view, keys/items/values, not just one;
> adding three new builtin functions just for dicts is perhaps a bit
> excessive.
>

Well, one could have created a MappingView object with three attributes.
And maybe a full MApping view would be useful, though I can't think of a
use case at the moment.

1. No backwards-compatibility baggage; we can pick the interface which
> is the most Pythonic. That's a protocol based on a dunder, not a
> method.
>

I disagree here, but come to the same conclusion: adding an attribute to
the Sequence ABC will break backward compatibility -- any Sequence subclass
that already has an attribute with that name would break.

We can all argue about what the most Pythonic API is, but the fact is that
Python has both "OO" APIs and "function-based" APIs. So either one could be
acceptable. But when adding a new name, there is a different impact
depending on what namespace it is added to:

A) Adding a reserved word is a Really Big Deal -- only done when absolutely
necessary. (and completely off the table for this one)

B) Adding a name to an ABC is a Big Deal -- it could potentially invalidate
any subclasses of that ABC -- so suddenly subclasses that worked perfectly
fine would be broken. And in the case at hand, numpy arrays do, in fact,
already have a .view method that is not the same thing.

C) Adding a builtin name is a Medium Deal, but not too huge -- existing
code might overwrite it, but that's only an issue if they want to use the
new functionality.

E) Adding a new name to a standard library module is Small Deal -- no third
parties should be adding stuff to that namespace anyway (and import * is
not recommended) (not that adding new functionality to the stdlib isn't a
lift -- but I'm only talking about names now)

F) Adding a new dunder is a Medium Deal -- the dunder names are explicitly
documented as being reserved -- so while folks may (and do) use dunder
names in third party libraries, it's there problem if something breaks
later on. (for instance, numpy used a lot of dunders - though AFAICT, they
are all "__array_*", so kinda a numpy namespace.

Taking all that into account, if we want to add "something" to Sequence
behavior (in this case a sequence_view object), then adding a dunder is
really the only option -- you'd need a really compelling reason to add a
Sequence method, and since there are quite a few folks that think that's
the wrong approach anyway, we don't have a compelling reason.

So IF a sequence_view is to be added, then a dunder is really the only
option.

Then we need to decide on where to put the view-creating-function (and what
to call it).

I personally would like to see it as a built in, but I suspect we wont get
a lot of support for that on this list.

-CHB


-- 
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
Python-ideas mailing list -- 

[Python-ideas] Re: Documenting iterators vs. iterables [was: Adding slice Iterator ...]

2020-05-15 Thread Jonathan Fine
Oops, try again;

Here's an article about recent research. I found it fascinating.

https://www.quantamagazine.org/ideal-glass-would-explain-why-glass-exists-at-all-20200311/

It starts: Glass is anything that’s rigid like a crystal, yet made of
disordered molecules like a liquid. To understand why it exists,
researchers are attempting to create the perfect, still-hypothetical “ideal
glass.”

-- 
Jonathan
___
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/7ASSOKTZ724FTH33FAACV7XYWUMKBGBE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Documenting iterators vs. iterables [was: Adding slice Iterator ...]

2020-05-15 Thread Jonathan Fine
Here's an article about recent research:
___
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/VADKPWSWIKHRTBFKCYV5O55SSOYALJM3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Documenting iterators vs. iterables [was: Adding slice Iterator ...]

2020-05-15 Thread Greg Ewing

On 16/05/20 12:26 am, Steven D'Aprano wrote:


Arguments over the precise definition of states of matter are, to some
degree, futile. I've seen amorphous solids described as "liquids that
don't flow" and non-Newtonian liquids described as "solids that flow".


I think this just shows that nature doesn't always agree to fit
into the neat categories we would like it to!

--
Greg
___
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/IUVKD7TXL5TVWOOET44QJ74SSDZNX2YS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Documenting iterators vs. iterables [was: Adding slice Iterator ...]

2020-05-15 Thread David Mertz
On Thu, May 14, 2020, 11:20 PM Stephen J. Turnbull

>  > I can teach a child why a glass will break permanently when you hit
>  > it while a lake won’t by using the words “solid” and “liquid”.
>
> Terrible example, since a glass is just a geologically slow liquid. ;-)
>

It isn't though. I used to believe the old urban legend about glass being a
(very slow) liquid too. It makes for good "impress your friends" chatter at
a certain point. But it's not true, glass is an amorphous solid, and old
windows are thicker at the bottom because they hung them that way.

https://www.scientificamerican.com/article/fact-fiction-glass-liquid/
___
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/J3XVCONCHZRC4NPN567J6WG26SSXCMYY/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Documenting iterators vs. iterables

2020-05-15 Thread Steven D'Aprano
On Fri, May 15, 2020 at 05:58:16AM -0400, Ricky Teachey wrote:

> Perhaps use the iter function name as the generic? "itered". As opposed to
> "iterated" or "iterated over".
> 
> Example:
> 
> "the statement below iterates over an iterator, itered from a sequence"

Or just avoid the issue:

"The statement below iterates over a sequence"

which is perfectly valid and correct.

If we do feel the need to drill down into pedantic technical details, 
instead of making up ugly words that nobody will have any clue 
whatsoever what the meaning is[1], we could use one of many existing 
English words:

built from
formed from
constructed from
made from
fabricated from
created from
put together from

etc. And notice I avoided using terms which imply that the sequence 
itself is transformed into an iterator, such as "converting into".




[1] "Iter" is an old term for a passage, in particular an anatomical 
term for a passage in the brain, so "itered" would be the past tense of 
a verb to turn something into a passage.


-- 
Steven
___
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/CQM25AACCSW4AG3M6OG6DGTKCGHOVB4N/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Documenting iterators vs. iterables [was: Adding slice Iterator ...]

2020-05-15 Thread Steven D'Aprano
On Fri, May 15, 2020 at 12:17:56PM +0900, Stephen J. Turnbull wrote:

> Terrible example, since a glass is just a geologically slow liquid. ;-)

That's a myth :-)

The key test for a liquid is not whether is flows, since solids also 
flow. (In solids, this usually happens very, very slowly, and is 
usually called "creep".) The key test is whether it can *drip*, 
and glass does not drip (except when molten).

Glass is considered a non-crystaline or amorphous solid.

https://en.wikipedia.org/wiki/Amorphous_solid

Pitch, on the other hand, is a geologically slow liquid :-)

https://smp.uq.edu.au/pitch-drop-experiment

Arguments over the precise definition of states of matter are, to some 
degree, futile. I've seen amorphous solids described as "liquids that 
don't flow" and non-Newtonian liquids described as "solids that flow".


-- 
Steven
___
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/A5XZRBVTIZOBXKRGVWFWYGGR44MPEQW3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: [Suspected Spam]Re: Adding slice Iterator to Sequences (was: islice with actual slices)

2020-05-15 Thread Steven D'Aprano
On Wed, May 13, 2020 at 10:51:58AM -0700, Andrew Barnert via Python-ideas wrote:

> Students often want to know why this doesn’t work:

[snip example showing the difference between iterators which become 
exhausted after iteration, and sequences that don't]

> The answer is that files are iterators, while lists are… well, there 
> is no word.

Sequences. Containers. Non-iterator-iterables. There's three words :-)

Albeit one of them is hyphenated, but if we were German we might call it 
a noniteratoriterablesequenceobject and abbreviate it to NIISO :-)

Oh, there's also subscriptable, to describe things that can be 
subscripted. Or there's "list-like".

The glossary defines all of Iterator, Iterable, Sequence but not 
Container:

https://docs.python.org/3/glossary.html

There's no short, common word specifically for iterables that aren't 
iterators for the same reason that there's no short, common word 
specifically for dogs that aren't poodles, plants that aren't roses, or 
programming languages that aren't Python :-)


> A file object is a file, in the same way that a list object is a list 
> and an int object is an int.

A file object is a proxy to a file. It doesn't itself live in a file 
system, but it points to an entity which does. In the same way that it 
is both useful and necessary to distinguish between an iterable that 
obeys the iterator protocol and one that does not, it's useful and 
necessary to distinguish between an in-memory file object and the file 
it points to.

File objects have a close method; files don't. And as you point out, 
file objects are iterators, but files are just a bunch of bytes on a 
hard drive.


-- 
Steven
___
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/OZMHVGYZPS4CU4L75FGY6SU4EB26ONHP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: [Suspected Spam]Re: Adding slice Iterator to Sequences (was: islice with actual slices)

2020-05-15 Thread Steven D'Aprano
On Mon, May 11, 2020 at 02:37:15PM +0900, Stephen J. Turnbull wrote:

> I think part of the problem is that people rarely see explicit
> iterator objects in the wild.  Most of the time we encounter iterator
> objects only implicitly.  Nomenclature *is* a problem (I still don't
> know what a "generator" is: a function that contains "yield" in its
> def, or the result of invoking such a function),

Strictly speaking, a function containing yield is a "generator 
function", the object it returns is a "generator iterator", or just 
generator.

Analogy: "a float" is the object returned by the `float()` function, not 
the function itself.

People are often sloppy in their terminology, but the inspect module
makes it clear:

https://docs.python.org/3/library/inspect.html#inspect.isgeneratorfunction

Alas, the glossary is itself a bit sloppy: you have to read it with care 
to see it talks about *generator functions* and *generator iterators*. 
The entries for async generators are better.

https://docs.python.org/3/glossary.html


-- 
Steven
___
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/7QBQTUN5WMB2VR2ISGC3FU2C7O6ELBAB/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Adding slice Iterator to Sequences

2020-05-15 Thread Rhodri James

On 14/05/2020 19:56, Andrew Barnert wrote:

On May 14, 2020, at 10:45, Rhodri James
wrote:

On 14/05/2020 17:47, Andrew Barnert via Python-ideas wrote:

Which is exactly why Christopher said from the start of this
thread, and everyone else has agreed at every step of the way,
that we can’t change the default behavior of slicing, we have to
instead add some new way to specifically ask for something
different.



Erm, did someone actually ask for something different?  As far as I
can tell the original thread OP was asking for islice-maker
objects, which don't require the behaviour of slicing to change at
all.  Quite where the demand for slice views has come from I'm not
at all clear.

That doesn’t make any difference here.

If you want slicing sequences to return iterators rather than copies,
that would break way too much code, so it’s not going to happen. A
different method/property/class/function that gives you iterators
would be fine.


We already have such.  It's called itertools.islice().

I'm sorry, but you're missing the point here.  You and Christopher seem 
to be having fun discussing this at great length, and that's fine. 
However at this point I've not grasped the proposal and I've lost the 
will to even contemplate the details.  What I have grasped is that no 
one else has offered much opinion, so saying that "everyone else has 
agreed at every step of the way" doesn't actually have the weight it 
pretends to.


--
Rhodri James *-* Kynesim Ltd
___
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/M4NU47MCXQSNZPDP24VLTMLEWOVO3ULX/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Adding slice Iterator to Sequences (was: islice with actual slices)

2020-05-15 Thread Steven D'Aprano
On Thu, May 14, 2020 at 09:47:36AM -0700, Andrew Barnert wrote:
> On May 14, 2020, at 03:01, Steven D'Aprano  wrote:
> > 
> > On Mon, May 11, 2020 at 10:41:06AM -0700, Andrew Barnert via Python-ideas 
> > wrote:
> > 
> >> I think in general people will expect that a slice view on a sequence 
> >> acts like “some kind of sequence”, not like the same kind they’re 
> >> viewing—again, they won’t be surprised if you can’t insert into a 
> >> slice of a list.
> > 
> > o_O
> > 
> > For nearly 30 years, We've been able to insert into a slice of a list. 
> > I'm going to be *really* surprise if that stops working
> 
> Which is exactly why Christopher said from the start of this thread, 
> and everyone else has agreed at every step of the way, that we can’t 
> change the default behavior of slicing, we have to instead add some 
> new way to specifically ask for something different.

Which is why I was so surprised that you suddenly started talking about 
not being able to insert into a slice of a list rather than a view.


> Not only that, but whatever gives 
> you view-slicing must look sufficiently different that you notice the 
> difference—and ideally that gives you something you can look up if you 
> don’t know what it means. I think lst.view[10:20] fits that bill.

Have we forgotten how to look at prior art all of a sudden? Suddenly 
been possessed by the spirits of deceased Java and Ruby programmers 
intent on changing the look and feel of Python to make it "real object 
oriented"? *wink*

We have prior art here:


b'abcd'.memoryview  # No, not this.
memoryview(b'abcd')  # That's the one.

'abcd'.iter  # No, not that either.
iter('abcd')  # That's it.


In fairness, I do have to point out that dict views do use a method 
interface, but:

1. Dict views came with a lot of backwards-compatibility baggage; 
they were initially methods that returned lists; then methods 
that returned iterators were added, then methods that returned 
views were added, and finally in 3.x the view methods were renamed and 
the other six methods were removed.

2. There is only a single builtin mapping object, dict, not like 
sequences where there are lists, tuples, range objects, strings, byte 
strings and bytearrays.

3. Dicts need three kinds of view, keys/items/values, not just one; 
adding three new builtin functions just for dicts is perhaps a bit 
excessive.


So if we're to add a generic sequence view object, none of those factors 
are relevent:

1. No backwards-compatibility baggage; we can pick the interface which 
is the most Pythonic. That's a protocol based on a dunder, not a 
method.

2. At least six builtins, not one.

3. Only one kind of sequence view, not three.


-- 
Steven
___
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/JZ3CU2KSHEUZUYNFFP2DTZUXQU5KSKWD/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Documenting iterators vs. iterables

2020-05-15 Thread Ricky Teachey
On Fri, May 15, 2020 at 5:37 AM Chris Angelico  wrote:

> On Fri, May 15, 2020 at 7:23 PM Stephen J. Turnbull
>  wrote:
> >
> > Chris Angelico writes:
> >
> >  > I don't like this term "converted".
> >
> > I refuse to die on that hill. :-)  Suggest a better term, I'll happily
> > use it until something even better comes along.  Or I'll try to come
> > up with a better one as I think about the documentation issue.
> >
>
> Unfortunately I don't have a really good generic term, but I would be
> inclined to "get an iterator from" an object rather than "convert" it
> to an iterator. It's still not a great term, but at least it allows
> you to think about getting multiple iterators from the same thing,
> even potentially getting different types of iterator.
>

Perhaps use the iter function name as the generic? "itered". As opposed to
"iterated" or "iterated over".

Example:

"the statement below iterates over an iterator, itered from a sequence"
___
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/25FSQAXHYK344KRTVN2UPE4NZJT2HO2P/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Documenting iterators vs. iterables

2020-05-15 Thread Chris Angelico
On Fri, May 15, 2020 at 7:23 PM Stephen J. Turnbull
 wrote:
>
> Chris Angelico writes:
>
>  > > (Technical note: for the convenience of implementors of 'for',
>  > > when iter is applied to an iterator, it always returns the
>  > > iterator itself.)
>  >
>  > That's not a mere technical detail - that's actually part of the
>  > definition of an iterator, namely that iter(x) is x. That's how you
>  > can tell that it's an iterator.
>
> From the point of view of teaching iterators to novices, I think it
> *is* a technical detail.  As has been pointed out, there are languages
> where iterators are *never* iterable.  What's *necessary* to an
> iterator as a concept is that it have a __next__.  Python chooses to
> define the iterator protocol with __iter__ being the identity for
> iterators because it makes implementing *for* straightforward.

Fair enough. Doesn't make a lot of difference, though.

>  > I don't like this term "converted".
>
> I refuse to die on that hill. :-)  Suggest a better term, I'll happily
> use it until something even better comes along.  Or I'll try to come
> up with a better one as I think about the documentation issue.
>

Unfortunately I don't have a really good generic term, but I would be
inclined to "get an iterator from" an object rather than "convert" it
to an iterator. It's still not a great term, but at least it allows
you to think about getting multiple iterators from the same thing,
even potentially getting different types of iterator.

ChrisA
___
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/OP5P75BGGYYNX4JNWY6YOCDMH3XZTBD7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Documenting iterators vs. iterables

2020-05-15 Thread Stephen J. Turnbull
Chris Angelico writes:

 > > (Technical note: for the convenience of implementors of 'for',
 > > when iter is applied to an iterator, it always returns the
 > > iterator itself.)
 > 
 > That's not a mere technical detail - that's actually part of the
 > definition of an iterator, namely that iter(x) is x. That's how you
 > can tell that it's an iterator.

>From the point of view of teaching iterators to novices, I think it
*is* a technical detail.  As has been pointed out, there are languages
where iterators are *never* iterable.  What's *necessary* to an
iterator as a concept is that it have a __next__.  Python chooses to
define the iterator protocol with __iter__ being the identity for
iterators because it makes implementing *for* straightforward.

 > I don't like this term "converted".

I refuse to die on that hill. :-)  Suggest a better term, I'll happily
use it until something even better comes along.  Or I'll try to come
up with a better one as I think about the documentation issue.

Steve
___
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/GEHAU3QUWSIBTWS76DCH3WGMPWX3FMST/
Code of Conduct: http://python.org/psf/codeofconduct/