www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 15972] New: joiner doesn't recognize range of chars

https://issues.dlang.org/show_bug.cgi?id=15972

          Issue ID: 15972
           Summary: joiner doesn't recognize range of chars
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: phobos
          Assignee: nobody puremagic.com
          Reporter: hsteoh quickfur.ath.cx

Code:
-------
auto triangle(int i) {
        import std.algorithm.iteration : map, joiner;
        import std.range : iota, repeat;

                      .joiner("\n");
}
void main() {
        import std.stdio : writeln;
        writeln(triangle(10));
}
-------

Compile error:
-------
test.d(5): Error: template std.algorithm.iteration.joiner cannot deduce
function from argument types !()(MapResult!(__lambda2, Result), string),
candidates are:
/usr/src/d/phobos/std/algorithm/iteration.d(1949):       
std.algorithm.iteration.joiner(RoR, Separator)(RoR r, Separator sep) if
(isInputRange!RoR && isInputRange!(ElementType!RoR) && isForwardRange!Separator
&& is(ElementType!Separator : ElementType!(ElementType!RoR)))
/usr/src/d/phobos/std/algorithm/iteration.d(2232):       
std.algorithm.iteration.joiner(RoR)(RoR r) if (isInputRange!RoR &&
isInputRange!(ElementType!RoR))
-------

A little sleuthing with pragma(msg) reveals that the problem is caused by

is what usually happens when strings are used with joiner), but strings (as
well as char literals such as writing '\n' instead of "\n") are always ranges
of dchar (no thanks to autodecoding), so joiner's signature constraints will
fail because it tries to check implicit conversion of the delimiter element
type (in this case always dchar) to the target range type (char), and is(dchar
: char) is false.

Workaround:
--------
auto triangle(int i) {
        import std.algorithm.iteration : map, joiner;
        import std.range : iota, repeat;
        import std.utf : byCodeUnit; // this is a hack

                      .joiner("\n".byCodeUnit);
}
void main() {
        import std.stdio : writeln;
        writeln(triangle(10));
}
--------

This is very silly, since nobody not already familiar with the intricacies of
autodecoding will even have the slightest idea what the problem is and how to
work around it.  My personal recommendation: kill autodecoding with fire.

--
Apr 29 2016