RFP - name for input range method

Steven Schveighoffer schveiguy at gmail.com
Thu Apr 2 14:09:14 UTC 2020


I thought of this today. Skip to the TLDR if you just want to answer the 
question.

As it's been said before, there's a thorn in D's side in the range API. 
Ranges are copyable, even when iterating an input range destroys all copies.

The latest example comes from this WTF: 
https://forum.dlang.org/post/vrhshjszqlwkpeckaqxx@forum.dlang.org

As I said in the response, the issue with BinaryHeap is that it must 
destroy it's internal range as it iterates. So it has no choice but to 
be a simple input range, and not a forward range. If it wanted to 
implement `save`, it would have to duplicate the underlying storage, 
which is not considered cheap.

The draconian solution is to make input ranges not copyable. That is, 
you have to be made aware that making a copy can destroy the original 
range. Then we can eliminate `save`, and a forward range just becomes a 
copyable input range.

But at the same time, a good point from Jonathan Davis buried somewhere 
in a recent thread is that making ranges not copyable is quite painful. 
The most obvious example is that foreach(elem; range) makes a copy of 
range. What if you make a copy and just don't use the original (like 
when you pass to a function)? What if you only just use front on the 
original? What if you actually *want* to iterate some of the data off of 
the range in the copy, and do the rest with the original?

The current situation is going to result constantly in more of these WTF 
instances.

But what if instead of opting-in to copying for copyable ranges (which 
continually is forgotten), you opt in to copying for non-copyable 
ranges? That is, move the `save` function really to input ranges, and 
make simple copying the new `save`?

=========
TL;DR:

what is the name of the function that we could put on input ranges that 
says "copy this, even though I know the original might be affected"? 
It's kind of like "give me a new reference to this input range". 
However, in some cases, it might not be. In some cases, the original is 
unusable.

I don't know if there's one word that encompasses all that. Maybe we 
would need 2 methods, and 2 types of input ranges: ReferenceInputRange 
and SingularInputRange (if that makes sense).

In any case, I thought of "addRef", but that is easily mistaken for 
reference counting. "copy" is not correct either, because you're not 
making a full copy. Maybe "transfer"? It should be short, as you would 
need it in a lot of places.

I'm not good at names. Anyone have any ideas? The migration process 
would be:

1. Add method(s) for input ranges that support being able to correctly 
"destructively copy" the range. This allows an opt-in for simple copying 
when you know that the original is destroyed. You can use `move` otherwise.
2. Deprecate save, and deprecate input ranges that allow simple copying, 
but don't define these methods.
3. Remove save, change classification of ranges that allow simple 
copying to forward ranges.
4. Profit

-Steve


More information about the Digitalmars-d mailing list