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

Paul Backus snarwin at gmail.com
Sat Jun 27 17:16:10 UTC 2020


On Saturday, 27 June 2020 at 13:11:09 UTC, Stanislav Blinov wrote:
> On Saturday, 27 June 2020 at 12:25:34 UTC, Joseph Rushton 
> Wakeling wrote:
>
>> But -- for example -- what would it mean to have an input 
>> range as part of a const or immutable data structure?  Forget 
>> the strict interpretation of the current D keywords, let's 
>> just think conceptually for a moment.  Do we want to think of 
>> an immutable input range as just a source of input, with any 
>> under-the-hood mutability just an implementation detail that 
>> shouldn't be of interest to the external caller?  Do we 
>> consider it a contradiction in terms?
>
> An immutable or const input range just cannot be. An input 
> range can't not be mutable.
> If a range itself can implement a `tail()`, it's not an input 
> range, it's a forward range.

This is false.

While it is true that a pure input range cannot exist without the 
presence of mutable state *somewhere*, it does not follow that 
the mutable state must be stored in (or pointed to by) the range 
itself. Consider the following example:

     auto fdByChar(int fd)
     {
         import core.sys.posix.unistd;

         static struct Result
         {
             private int fd;
             bool empty;
             char front;

             Result tail() const
                 in (!empty)
             {
                 char next;
                 ssize_t nread = read(fd, cast(void*) &next, 1);

                 if (nread == 0)
                     return Result(fd, true, char.init);
                 else if (nread == 1)
                     return Result(fd, false, next);
                 else
                     throw new Exception("Error reading file");
             }
         }

         return Result(fd, false, char.init).tail;
     }


This is a pure input range. Copying it and iterating the copy 
will invalidate the original. Yet it is perfectly capable of 
being `immutable`. Here's an example of usage:

     void each(alias fun, Range)(Range range)
     {
         if (range.empty) return;
         fun(range.front);
         range.tail.each!fun;
     }

     void main()
     {
         import std.stdio;
         immutable stdinByChar = fdByChar(0);
         stdinByChar.each!writeln;
     }


Of course, there is mutable state involved here, but that state 
is not in the range--it's in the kernel. So the `immutable` 
qualifier on the range does not apply to it.


More information about the Digitalmars-d mailing list