March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thu, 27 Mar 2014 11:40:59 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > 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 What's broken about those? -Steve |
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thu, 27 Mar 2014 11:19:15 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > 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. This is a misleading statement. An array is probably the most efficient of ranges, which does not require this. We should be more specific here. For certain types of *nonempty* ranges, front is only guaranteed to work if empty/length was called before front is called. I would not necessarily lump popFront into that requirement automatically, popFront may be able to cope with not having cached the first element without losing efficiency. Questions to answer: 1. What types of ranges does this rule apply to? 2. What is the cost of not requiring this in terms of efficiency and ease of implementation. 3. Is there a better mechanism to use than misusing empty? should we introduce another property/call? At the moment, the only candidates I can think of are lazy caching ranges. How many of those exist? -Steve |
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 3/27/14, 8:44 AM, Steven Schveighoffer wrote:
> On Thu, 27 Mar 2014 11:40:59 -0400, Andrei Alexandrescu
> <SeeWebsiteForEmail@erdani.org> wrote:
>
>> 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
>
> What's broken about those?
Speed.
|
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 3/27/14, 8:44 AM, Steven Schveighoffer wrote:
> At the moment, the only candidates I can think of are lazy caching
> ranges. How many of those exist?
filter comes to mind. -- Andrei
|
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thursday, 27 March 2014 at 15:19:37 UTC, Andrei Alexandrescu wrote:
> 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.
I just want to point out that I think allowing empty to have an *observable* side effect will have cataclysmic repercussion in validating a release build, what with all our "assert(!empty);" calls and all.
|
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thursday, 27 March 2014 at 15:45:14 UTC, Andrei Alexandrescu wrote: > On 3/27/14, 8:44 AM, Steven Schveighoffer wrote: >> On Thu, 27 Mar 2014 11:40:59 -0400, Andrei Alexandrescu >> <SeeWebsiteForEmail@erdani.org> wrote: >> >>> 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 >> >> What's broken about those? > > Speed. I call shenanigans. This is the code: @property bool empty() { if (nLeft) return false; if (r.empty) return true; If you initialized the next element in both constructor and popFront, then you'd get rid of both these checks. Furthermore, popFront() has a guaranteed "1 call" per element. Weareas "empty" and "front" may be called several times in a row for a single element. If you want efficiency, stop being "member-wise" lazy, and put some eagerness in your code. > filter comes to mind. -- Andrei You *just* turned down a pull that did exactly that, for exactly the same reasons. Have "byXChar" function like filter: construction and popFront do the work, and front/empty is 0(1), and const, and strongly pure to boot. I *know* the compiler likes that in terms of speed. |
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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.
Some thoughts:
- A while ago I realized I did not know how some of those underspecified details should be implemented (I think my initial doubt was if the range was expected/required to enforce(!empty)). Assuming it was just my ignorance (and incomplete or hard to find documentation), I asked in the IRC channel and, IIRC, the answer I got there was that ranges are an abstract concept, so such minutia were supposed to be implementation details. From this forum thread and that IRC feedback, it seems that, indeed, people have been operating under an illusion of a shared universal assumption. I'm very happy to see this addressed.
- (Lots of text deleted because I was no longer sure about it ...)
- Is it allowed for an InputRange to become empty and then not empty again? For a finite RandomAccessRange to increase in length? E.g.:
// Example 1: (with "outside" control flow)
if(someQueue.empty)
addStuffToQueue();
assert(!someQueue.empty);
// Example 2: (with only range-related control flow)
if(!someQueue.empty)
{
auto n = someQueue.length;
someQueue.popFront();
assert(someQueue.length == n-1); // can this fail?
}
- Is it allowed to not call front? E.g.:
void dropAll(Range)(Range range)
{
while(!empty)
range.popFront();
}
|
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Thu, 27 Mar 2014 12:02:16 -0400, monarch_dodra <monarchdodra@gmail.com> wrote:
> On Thursday, 27 March 2014 at 15:19:37 UTC, Andrei Alexandrescu wrote:
>> 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.
>
> I just want to point out that I think allowing empty to have an *observable* side effect will have cataclysmic repercussion in validating a release build, what with all our "assert(!empty);" calls and all.
This is an excellent point. assert(!empty) is everywhere.
-Steve
|
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 3/27/14, 9:12 AM, monarch_dodra wrote:
>> filter comes to mind. -- Andrei
>
> You *just* turned down a pull that did exactly that, for exactly the
> same reasons.
I was on the verge, and we need to discuss this more. A constructor that does arbitrary work for a lazy range doesn't sit well. -- Andrei
|
March 27, 2014 Re: protocol for using InputRanges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thursday, 27 March 2014 at 19:03:26 UTC, Andrei Alexandrescu wrote:
> On 3/27/14, 9:12 AM, monarch_dodra wrote:
>>> filter comes to mind. -- Andrei
>>
>> You *just* turned down a pull that did exactly that, for exactly the
>> same reasons.
>
> I was on the verge, and we need to discuss this more. A constructor that does arbitrary work for a lazy range doesn't sit well. -- Andrei
I still think there's ambiguity in the word "lazy". I think this is the distinction most make:
Not lazy:
//----
auto r = getSomeRange();
auto arr = someRange.array();
foreach( ref e ; arr)
doSomething;
remove!fun(arr);
return arr;
//----
Lazy:
//----
return getSomeRange()
.map!doSomething()
.filter!fun()
.array();
//----
What you are talking about (IMO) is better described as "eager" vs "not eager".
"A constructor does some work for a lazy range that does eager processing of its elements": I think this is a better description, and I think is acceptable.
|
Copyright © 1999-2021 by the D Language Foundation