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.

Reply via email to