How to correctly handle immutable ranges

monarch_dodra monarchdodra at gmail.com
Mon Dec 31 09:52:12 PST 2012


On Monday, 31 December 2012 at 17:11:01 UTC, Peter Alexander 
wrote:
> On Monday, 31 December 2012 at 16:29:27 UTC, monarch_dodra 
> wrote:
>> But back to the original problem, I just think one shouldn't 
>> be able to call a const object a range. A "Range" is mutable 
>> by nature. Any attempt to pass one to an algorithm should fail 
>> (IMO).
>
> This will break a lot of existing code.
>
> This currently works:
>
> immutable int[] a = [1, 2, 3];
> auto b = array(a);
>
> std.array.array is one of the few functions that uses 
> std.traits.isIterable, so it works for immutable slices.

Yes, but technically, the passed object is "immutable(int)[]", 
which *is* a range, so that has nothing to do with isIterable.

But you do bring up a good point. All too often we settle for 
InputRange when we can have Iterable.

That said, it does come with its own problems, such as:
* Figuring out the iteration type?
* Iterate by ref, or by value?
* Difficult to handle "special first step" cases...

Last but not least, I was told by Andrei not too long ago (while 
working on reduce) that "opApply" objects where *not* supported 
by std.algorithm. I was even told to remove existing code that 
supported it.

>> We just have a really special case regarding const slices. 
>> Even then, the only reason you can "iterate them" is because 
>> the compiler is implicitly copying a mutable slice behind the 
>> scenes. The const slice itself, technically, really isn't 
>> iterable (AFAIK)...
>
> It could also iterate the indices:
>
> immutable int[] a = [1, 2, 3];
> foreach (i; 0..a.length)
>     foo(a[i]);
>
> Nothing illegal about that.
>
> The specific issue I'm looking at is the joining of an 
> immutable array of arrays. It should be allowed, because they 
> can be iterated. In fact, if you just remove the template 
> constraints from std.array.join then it works.

Well, the reason it works is not that they can be iterated, but 
that the constness of the subslices is stripped when passed to 
Appender.Put (which, btw, accepts InputRanges, but Iterables). 
Really, this is more luck than an "isIterable" thing.

--------
But you do bring up the issue of giving more love to iterables.

If you want to add support to joiner, you *may* have to start 
with adding support for it for appender though. I'm unsure: 
Appender doesn't accept Iterables, but the free standing put 
does, so it might be able to individually call 
Appender.put(element). Not sure... if it works... or is 
efficient...

In any case, I think it'd be wrong to special case support for 
Range of Immutable Array. At best, the type Immutable Array is 
iterable, but not a range. Trying to change that would (IMO) warp 
the language.


More information about the Digitalmars-d mailing list