Forward ranges in Phobos v2

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Thu Nov 4 15:29:59 UTC 2021


On 11/4/21 12:43 AM, Paul Backus wrote:
> On Thursday, 4 November 2021 at 04:06:15 UTC, Andrei Alexandrescu wrote:
>> On 11/3/21 11:25 PM, Paul Backus wrote:
>>>
>>> If we want to avoid copying, we can have `next` return a `Ref!T` in 
>>> the case where the forward range has lvalue elements:
>>>
>>> struct Ref(T)
>>> {
>>>      T* ptr;
>>>
>>>      ref inout(T) deref() inout
>>>      {
>>>          return *ptr;
>>>      }
>>>      alias deref this;
>>> }
>>>
>>> I've tested some simple uses of this wrapper on run.dlang.io, and it 
>>> seems like DIP 1000 is good enough to make it work in @safe code.
>>>
>>> If "returns either `T` or `Ref!T`" sounds like a suspect design for 
>>> an API, consider that it is basically the same thing as an `auto ref` 
>>> return value--just with the distinction between ref and non-ref 
>>> brought inside the type system.
>>
>> That was on the table, too, in the form of a raw pointer.
>>
>> I think it can be made to work, but for lvalue ranges only, and it 
>> will be difficult to make safe (scoped etc).
>>
>> Overall this seems to create more problems than it solves.
> 
> I'd be curious to see any examples of such problems you have in mind.
> 
> As far as I'm aware, no special effort should be required to make this 
> @safe, aside from enabling -preview=dip1000 (which, granted, is still a 
> work in progress).

Pointers are problematic because of aliasing and lifetime (what if the 
pointer survives the data structure it points into). So the `Ref` 
structs needs to be qualified appropriately with `scope`. So yes DIP1000 
would need to be tight.

Usability is another matter that hasn't been quite looked at. Once you 
have a scoped pointer wrapper, what can and what can't you do with it 
easily? I'm not very sure.

Alias this is just poorly done. I think we shouldn't base a fundamental 
API on it.

Anyway, I'm cautiously optimistic. At the very least this should be 
explored.

Note that the whole thing still doesn't address unbuffered ranges. There 
must be a buffer of at least one element somewhere. That's... problematic.



More information about the Digitalmars-d mailing list