www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - RFP - name for input range method

reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Apr 02
next sibling parent Dennis <dkorpel gmail.com> writes:
On Thursday, 2 April 2020 at 14:09:14 UTC, Steven Schveighoffer 
wrote:
 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"?
shallowCopy?
Apr 02
prev sibling next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 4/2/20 10:09 AM, Steven Schveighoffer wrote:
 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
better: 1. same as above. 2. Deprecate copying input ranges, directing the user to use the new methods. It might be useful to have compiler help for this. If a range defines `save`, it is a forward range still. If a range allows copying but does not define `save`, then a deprecation message is displayed via `isInputRange`. 3. Interpret ranges that are copyable as forward ranges. Deprecate save 4. Remove save. 5. Profit -Steve
Apr 02
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Thursday, 2 April 2020 at 14:09:14 UTC, Steven Schveighoffer 
wrote:
[...]
 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.
Walter has a draft DIP in the works [1] to implicitly move objects instead of copying them when you "make a copy and just don't use the original". It seems to me like this would make non-copyable ranges much more ergonomic to use, without requiring any changes to the existing range interface. [1] https://github.com/WalterBright/DIPs/blob/13NNN-WGB.md/DIPs/13NNN-WGB.md
Apr 02
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 4/2/20 11:32 AM, Paul Backus wrote:

 
 Walter has a draft DIP in the works [1] to implicitly move objects 
 instead of copying them when you "make a copy and just don't use the 
 original". It seems to me like this would make non-copyable ranges much 
 more ergonomic to use, without requiring any changes to the existing 
 range interface.
 
 [1] 
 https://github.com/WalterBright/DIPs/blob/13NNN-WGB.md/DIPs/13NNN-WGB.md
With that, indeed you could remove the need for special functions in many cases. I'm not sure it would be all cases. But of course, that DIP isn't done yet. It does look like a no-brainer though. -Steve
Apr 02