std.v2020.algorithm etc[ WAS: Is run.d going to be expand for runtime and the phobos library?]

Stanislav Blinov stanislav.blinov at gmail.com
Sun Jun 28 14:00:42 UTC 2020


On Sunday, 28 June 2020 at 12:43:53 UTC, Joseph Rushton Wakeling 
wrote:
> On Sunday, 28 June 2020 at 11:33:39 UTC, Stanislav Blinov wrote:
>>> Does it even make _sense_ to be able to call `tail` twice on 
>>> the same input range instance?
>>
>> No, it does not, that's my point. "Don't do that" isn't the 
>> answer. "Can't do that" (statically disallowed, not present in 
>> the interface) is the answer.
>
> Indeed.  You seem to be thinking I'm disagreeing with you, when 
> actually we are in agreement on this point ;-)

Ah, that wasn't evident from the question :*)

>>> One of the problems with thinking about ranges -- and the 
>>> current range API reflects this -- is that it tends to start 
>>> by thinking about deterministic examples (e.g. arrays).
>>
>> Arrays are random access ranges (which are also forward). 
>> They're not input ranges :)
>
> That's not strictly true: one can reasonably _interpret_ an 
> array as an input range if that's what is desired.

That does not make arrays input ranges. They remain random-access 
ranges.

> What makes an input range distinct is not whether the actual 
> elements come from some impure input source (it can be 
> deterministic under the hood, whether from iterating over array 
> elements, or a deterministic generative mechanism like a PRNG, 
> or whatever), but what assumptions the caller can make about 
> how to use and interact with it.

That would be design by convention, which I'm strongly opposed 
to, and arguing against. There's no need to *document* caller's 
assumptions when we can devise an API that drives them. What 
makes an input range distinct is that, unlike other kinds, it can 
only be consumed once - there's no need for any other 
assumptions. The current range API does not enforce this in any 
way, hence the copying conundrum and Jonathan's "don't use 
original after you make a copy" or other similar statements that 
amount to "you should know what you're doing".

>> The current range API incorrectly treats any range as at least 
>> an input range. If we are talking about making changes to 
>> range API - that is one of the changes that needs to be made.
>
> That doesn't really make sense to me.  Why is it not possible 
> to interact with any other range via input range semantics?

Because they have different semantics! The current range API 
attempts to differentiate solely on interface (which can indeed 
appear intersecting) but not semantics. What I meant is, today in 
Phobos, there are algorithms that do this:

auto algo(Range)(Range range)
if (isInputRange!Range)
{
     /* ... */
     static if (isForwardRange!Range)
     {
         /* ... */
     }
}

Input ranges are treated as a subset of forward ranges. But 
they're not - they're distinct, non-intersecting sets. If we do 
change the API, the above will have to become either (depending 
on the algorithm):

auto algo(Range)(Range range)
if (isInputRange!Range)
{ /* ... */ }

auto algo(Range)(Range range)
if (isForwardRange!Range)
{ /* ... */ }

// OR, given a hypothetical `isSomeRange` test

auto algo(Range)(Range range)
if (isSomeRange!Range) // note: isSomeRange, not isInputRange
{
     /* use common API, if any ... */
     static if (isForwardRange!Range)
     {
         /* ... */
     }
}

> Right, _you cannot keep the original range and the tail_.  But 
> that doesn't block you having a method which takes the original 
> range as input, and returns the updated range.  The issue is 
> stopping you using the _original_ range (e.g. requiring it to 
> be passed into the method via a move rather than by reference?).

Yes, i.e. the free function implementation of `tail` that I 
posted previously (which would work correctly for both input 
ranges and forward ranges, *assuming* input ranges aren't 
copyable and forward ranges are).


More information about the Digitalmars-d mailing list