OutputRange should be infinite?

monarch_dodra monarchdodra at gmail.com
Fri Oct 5 08:15:44 PDT 2012


A good while ago, I ran into some issues regarding output ranges. 
(reference 
http://forum.dlang.org/thread/xyvnifnetythvrhtcexm@forum.dlang.org)

The gist of the problem is that with "put" an OutputRange that 
accepts a T will accept a Range!T, and a Range(Range!T) and a 
Range!(Range(Range!T)) add infinitum.

This all works nice and well, provided the output range does not 
ever become empty => is infinite. However, this is currently not 
the case, and this code will blow in your face:

//--------
auto a = new int[](1);
auto b = new int[](2);
assert(isOutputRange!(typeof(a), typeof(b)));
if(!a.empty)
    put(a, b); //Nope
//--------
auto a = new int[](10);
auto b = new int[][](3, 5);
assert(isOutputRange!(typeof(a), typeof(b)));
if(a.length > b.length)
     put(a, b); //Nope
//--------

I had made a "formal request" to deprecate this feature: 
http://forum.dlang.org/thread/xgncorvzlbtcmaxjuvkz@forum.dlang.org 
. I had not come back to this since, but I *have* been thinking 
about it since. I think my request was wrong.

However, I that the "isOutputRange" definition should require 
infinite-ness, as mentioned by others.

The "fun" part of OutputRange is that delegates, or as a general 
rule, any object that implements "put", or in some way shape or 
form, accepts put(range, stuff) is considered OutputRange.

To enforce infiniteness, I'd like to add this to the requirement 
of output range:
*Must meet one of these two criteria:
**isInifite!Range
or
**Does not define "range.empty"
   //notion of infiniteness by default: delegates etc...

This actually has some very very low impact in phobos: The only 
OutputRanges ever used by phobos are appenders/delegates/printers 
anyways.

Also, it does not actually prevent writing put(dynamicArray, [1, 
2]): The dynamic array will seize to match the "isOutputRange", 
but that don't mean the function "put" won't work on it anymore. 
Nuance ho!

The *only* function that is really impacted is "copy". However, 
arguably, it was wrong to use it with OutputRanges to begin with. 
copy(r1, r2) and put(r1, r2) are NOT the same semantic, and 
should not be used as such.

I'd like to try to push for this change. Would this be a lost 
cause, or does the community feel this is indeed the way to go?


More information about the Digitalmars-d mailing list