On Sunday, February 14, 2016 15:24:39 Bastiaan Veelo via Digitalmars-d-learn wrote: > Hi, > > I am having trouble getting the iteration methods in > std.algorithm.iteration to work on immutable data: > > > import std.algorithm.iteration; > > import std.stdio; > > > > void main() > > { > > string[][] cycles; > > cycles ~= ["one", "two"]; > > cycles ~= ["three", "four"]; > > foreach (number; cycles.joiner) // This works. > > writeln(number); > > > > immutable(string[])[] icycles; > > icycles ~= ["one", "two"]; > > icycles ~= ["three", "four"]; > > foreach (number; icycles.joiner) // Should this work? > > writeln(number); > > } > > The error message is: > > /d149/f840.d(15): Error: template std.algorithm.iteration.joiner > cannot deduce function from argument types > !()(immutable(string[])[]), candidates are: > /opt/compilers/dmd2/include/std/algorithm/iteration.d(1911): > std.algorithm.iteration.joiner(RoR, Separator)(RoR r, Separator > sep) if (isInputRange!RoR && isInputRange!(ElementType!RoR) && > isForwardRange!Separator && is(ElementType!Separator : > ElementType!(ElementType!RoR))) > /opt/compilers/dmd2/include/std/algorithm/iteration.d(2194): > std.algorithm.iteration.joiner(RoR)(RoR r) if (isInputRange!RoR > && isInputRange!(ElementType!RoR)) > > I had expected this to work. What did I miss?
An immutable range fundamentally does not work. The same goes with const. In fact, a type that's immutable is going to fail isInputRange precisely because it can't possibly function as one. While empty and front may be callable on an immutable range, depending on their exact signatures, popFront cannot be, because it has to mutate the range in order to work. Arrays do typically get sliced when they're passed to functions, and array slices are tail-const (e.g. const(int[]) is sliced as const(int)[]), so something like immutable string foo = "hello world"; auto result = foo.startsWith("goodbye"); will compile. But that doesn't work with ranges in general. What you're doing is probably failing, because icycle[] is immutable(string)[], which is immutable(char[])[], and it can't iterate over the immutable(char[]). But regardless, if you try and use immutable with ranges, even if it works in some cases thanks to how arrays are treated, it's just going to end up shooting you in the foot in the end. So, I'd advise that you not bother trying to do much with const or immutable with ranges. - Jonathan M Davis