March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rikki Cattermole | On Sunday, 23 March 2014 at 01:07:27 UTC, Rikki Cattermole wrote:
> On Sunday, 23 March 2014 at 00:50:34 UTC, Walter Bright wrote:
>> It's become clear to me that we've underspecified what an InputRange is. The normal way to use it is:
>>
>> while (!r.empty) {
>> auto e = r.front;
>> ... do something with e ...
>> r.popFront();
>> }
>>
>> no argument there. But there are two issues:
>>
>> 1. If you know the range is not empty, is it allowed to call r.front without calling r.empty first?
>>
>> If this is true, extra logic will need to be added to r.front in many cases.
>>
>> 2. Can r.front be called n times in a row? I.e. is calling front() destructive?
>>
>> If true, this means that r.front will have to cache a copy in many cases.
>
> It would be nice to have ranges full stop described. And how to use/make them in D. I have yet to learn them because of no official documentation on them.
> On this topic we also need to work on common patterns and creating documentation on e.g. the site or wiki for it. Saw that we do have a bit in the wiki under tutorials. Maybe if I get some time I'll work on that.
I agree. I've been using ranges for a while now and have tried
different implementations based on advice given on this forum and
depending on each case. After reading this thread I looked at
some of my ranges and I have to say I still have no clue as to
what should and should _not_ be done (regardless of whether you
_can_ do it). For a while I thought that it's my lack of
understanding, but this thread shows that everyone has a
different view of ranges. Guidelines with use cases would be
great. I remember I mentioned this in another thread already. The
thing is that experimenting without proper guidelines leaves your
code in an inconsistent state where you have two or more ranges
doing technically the same thing but each with a different logic.
|
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Murphy | On Thu, 27 Mar 2014 02:44:13 -0000, Daniel Murphy <yebbliesnospam@gmail.com> wrote: > "Regan Heath" wrote in message news:op.xdb9a9v354xghj@puck.auriga.bhead.co.uk... > >> What guarantees range2 is longer than range1? The isArray case checks explicitly, but the generic one doesn't. Is it a property of being an output range that it will expand as required, or.. > > Some ranges will give you their length... Sure. And generally you could use it. copy() doesn't, and I was talking specifically about that example. :) R -- Using Opera's revolutionary email client: http://www.opera.com/mail/ |
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Thursday, 27 March 2014 at 04:17:16 UTC, Walter Bright wrote: > On 3/26/2014 7:55 PM, Steven Schveighoffer wrote: >> OK, but it's logical to assume you *can* avoid a call to empty if you know >> what's going on under the hood, no? Then at that point, you have lost the >> requirement -- people will avoid calling empty because they can get away with >> it, and then altering the under-the-hood requirements cause code breakage later. >> >> Case in point, the pull request I referenced, the author originally tried to >> just use empty to lazily initialize filter, but it failed due to existing code >> in phobos that did not call empty on filtered data before processing. He had to >> instrument all 3 calls. > > As with *any* API, if you look under the hood and make assumptions about the behavior based on a particular implementation, assumptions that are not part of the API, the risk of breakage inevitably follows. > > If you've identified Phobos code that uses ranges but does not follow the protocol, the Phobos code is broken - please file a bugzilla issue on it. I was originally going to do that, but then I took a closer look at the documentation, which says ([1] in the documentation of `isInputRange()`): "Calling r.front is allowed only if calling r.empty has, or would have, returned false." (And the same for `popFront()`.) That is, the documentation more or less explicitly states that you don't actually need to call `empty` if you know it returned `true`. [1] http://dlang.org/phobos/std_range.html |
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thu, 27 Mar 2014 02:19:13 -0000, Steven Schveighoffer <schveiguy@yahoo.com> wrote: > if(!r.empty) > { > auto r2 = map!(x => x * 2)(r); > do > { > auto x = r2.front; > ... > } while(!r2.empty); > } if(r.empty) return; auto r2 = map!(x => x * 2)(r); while(!r2.empty) { auto x = r2.front; ... r2.popFront(); //bug fix for your version which I noticed because I followed "the pattern" :D } ahh.. much better. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/ |
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | On Thu, 27 Mar 2014 10:49:42 -0000, Marc Schütz <schuetzm@gmx.net> wrote: > On Thursday, 27 March 2014 at 04:17:16 UTC, Walter Bright wrote: >> On 3/26/2014 7:55 PM, Steven Schveighoffer wrote: >>> OK, but it's logical to assume you *can* avoid a call to empty if you know >>> what's going on under the hood, no? Then at that point, you have lost the >>> requirement -- people will avoid calling empty because they can get away with >>> it, and then altering the under-the-hood requirements cause code breakage later. >>> >>> Case in point, the pull request I referenced, the author originally tried to >>> just use empty to lazily initialize filter, but it failed due to existing code >>> in phobos that did not call empty on filtered data before processing. He had to >>> instrument all 3 calls. >> >> As with *any* API, if you look under the hood and make assumptions about the behavior based on a particular implementation, assumptions that are not part of the API, the risk of breakage inevitably follows. >> >> If you've identified Phobos code that uses ranges but does not follow the protocol, the Phobos code is broken - please file a bugzilla issue on it. > > I was originally going to do that, but then I took a closer look at the documentation, which says ([1] in the documentation of `isInputRange()`): > > "Calling r.front is allowed only if calling r.empty has, or would have, returned false." > > (And the same for `popFront()`.) > > That is, the documentation more or less explicitly states that you don't actually need to call `empty` if you know it returned `true`. > > [1] http://dlang.org/phobos/std_range.html That's because up until now we've made no attempt to set this in stone, and as such many interpretations have surfaced. This documentation would, of course, change to match the final decision made. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/ |
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paulo Pinto | On Thursday, 27 March 2014 at 08:13:28 UTC, Paulo Pinto wrote:
> Why not?
>
> It is how iterators work in most OO languages.
Why not what? A query for "empty()" should not have any side effects. In what library does that happen? Tests should in general not have side effects unless the name suggest so.
Anyway, I wish D was more clear about use scenarios. If D is going to be efficient in the server space then it should also make low latency programming easier, meaning supporting async collections out-of-the-box.
|
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Thu, 27 Mar 2014 00:17:21 -0400, Walter Bright <newshound2@digitalmars.com> wrote: > On 3/26/2014 7:55 PM, Steven Schveighoffer wrote: >> OK, but it's logical to assume you *can* avoid a call to empty if you know >> what's going on under the hood, no? Then at that point, you have lost the >> requirement -- people will avoid calling empty because they can get away with >> it, and then altering the under-the-hood requirements cause code breakage later. >> >> Case in point, the pull request I referenced, the author originally tried to >> just use empty to lazily initialize filter, but it failed due to existing code >> in phobos that did not call empty on filtered data before processing. He had to >> instrument all 3 calls. > > As with *any* API, if you look under the hood and make assumptions about the behavior based on a particular implementation, assumptions that are not part of the API, the risk of breakage inevitably follows. Like range.save. It's "required", but frequently omitted, without any consequences. I'm not saying requiring it would be an invalid decision, I'm saying requiring it would be a futile gesture -- the requirement would be ignored. What happens when one of our "clients" code breaks severely because we make a change in phobos that assumes empty is always called first on a newly-created range? > If you've identified Phobos code that uses ranges but does not follow the protocol, the Phobos code is broken - please file a bugzilla issue on it. I think we should work on making a protocol that does not require awkward calls, rather than alienating developers who don't follow the awkward protocol. BTW, I think there has been recent talk about not focusing on dust when we are laying bricks. This would have my vote as useless dust. This does not solve the problem of streams-as-ranges, because streams don't make good ranges. It doesn't really solve any problems as far as I can tell. -Steve |
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thursday, 27 March 2014 at 12:35:04 UTC, Steven Schveighoffer wrote: > What happens when one of our "clients" code breaks severely because we make a change in phobos that assumes empty is always called first on a newly-created range? You probably can run-time test this in Debug builds, but… > I think we should work on making a protocol that does not require awkward calls, rather than alienating developers who don't follow the awkward protocol. This is it. There is way too much awkwardness in D already. And essentially, the closer the design is to mainstream the more annoying it is when you diverge and are inconsistent. Code should behave as expected without any need for memorizing. Having to differentiate between dialects is so much harder than differentiating between orthogonal languages. |
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | On 3/27/14, 3:49 AM, "Marc Schütz" <schuetzm@gmx.net>" wrote:
> I was originally going to do that, but then I took a closer look at the
> documentation, which says ([1] in the documentation of `isInputRange()`):
>
> "Calling r.front is allowed only if calling r.empty has, or would have,
> returned false."
Probably we need to amend that. For efficient ranges, front() and popFront() should only be guaranteed to work if either empty() or length() were evaluated first, and they returned false or nonzero, respectively.
Andrei
|
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 3/27/14, 5:35 AM, Steven Schveighoffer wrote:
> BTW, I think there has been recent talk about not focusing on dust when
> we are laying bricks. This would have my vote as useless dust. This does
> not solve the problem of streams-as-ranges, because streams don't make
> good ranges. It doesn't really solve any problems as far as I can tell.
I think byXchar are important and are not streams. -- Andrei
|
Copyright © 1999-2021 by the D Language Foundation