std.v2020.algorithm etc[ WAS: Is run.d going to be expand for runtime and the phobos library?]
Paul Backus
snarwin at gmail.com
Sun Jun 28 16:37:23 UTC 2020
On Sunday, 28 June 2020 at 15:33:48 UTC, Stanislav Blinov wrote:
> On Sunday, 28 June 2020 at 14:12:39 UTC, Paul Backus wrote:
>
>> It sounds like what you are really trying to say here is that
>> input ranges and forward ranges should not use the same
>> interface, and that input ranges should instead implement only
>> `Option!T next()`.
>
> Not exactly. A given forward range may also implement such a
> `next`. [...] We should differentiate by some other artifact. I
> maintain that artifact should be copyability. Or we can keep
> the distinction based on the presence of save(), and live
> forever with the ambiguous semantics and the "don't use
> original after copy unless you know what you're doing"
> convention (yuck). Are there even other options besides
> accepting UB?
If input ranges are only required to implement next(), then the
distinction will be that forward ranges implement head()/tail()
and input ranges don't. (In this scenario, head() and tail() will
of course be required to return the same result if called
multiple times.)
For *some* forward ranges, it will be possible to implement
next() as well, in which case those ranges will be capable of
functioning as both input ranges and forward ranges. I don't see
anything wrong with that.
>> My example was a response to the specific claim that "an
>> immutable input range cannot exist." Specifically, it was a
>> counterexample demonstrating that the claim is false. As I'm
>> sure you can see, the claim is still false even if we agree to
>> use next() instead of tail() for input ranges, since next() is
>> obviously allowed to be impure.
>
> I can't see that. I don't see how you're falsifying that claim
> when in order to implement the range you need mutable state.
Ok, I'll show you. Here's the same range implemented using next()
instead of front() and tail():
// Just enough for the example to compile
struct Optional(T)
{
bool empty;
T value;
}
Optional!T some(T)(T value)
{
return Optional!T(false, value);
}
Optional!T no(T)()
{
return Optional!T(true, T.init);
}
auto fdByChar(int fd)
{
import core.sys.posix.unistd;
static struct Result
{
private int fd;
Optional!char next() const
{
char c;
ssize_t nread = read(fd, cast(void*) &c, 1);
if (nread == 0)
return no!char;
else if (nread == 1)
return some(c);
else
throw new Exception("Error reading file");
}
}
return Result(fd);
}
And here's the usage:
void each(alias fun, Range)(Range range)
{
for (auto e = range.next; !e.empty; e = range.next)
fun(e.value);
}
void main()
{
import std.stdio;
immutable stdinByChar = fdByChar(0);
stdinByChar.each!writeln;
}
Once again, `stdinByChar` is an input range, and it is immutable.
QED.
More information about the Digitalmars-d
mailing list