Bug 15972 – range of chars doesn't work with joiner with literal delimiters

Status
NEW
Severity
normal
Priority
P3
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2016-04-29T19:02:52Z
Last change time
2024-12-01T16:26:40Z
Assigned to
No Owner
Creator
hsteoh
Moved to GitHub: phobos#10174 →

Comments

Comment #0 by hsteoh — 2016-04-29T19:02:52Z
Code: ------- auto triangle(int i) { import std.algorithm.iteration : map, joiner; import std.range : iota, repeat; return iota(i).map!(i => '#'.repeat(i)) .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 '#'.repeat(i) returning a range of char (as opposed to a range of dchar, which 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 return iota(i).map!(i => '#'.repeat(i)) .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.
Comment #1 by dfj1esp02 — 2016-05-05T14:16:41Z
What I have in mind: 1. Move autodecoding algorithms to undead. 2. Remove autodecoding from algorithms. 3. Have dfix rewrite std.algorithm to undead.algorithm
Comment #2 by greensunny12 — 2018-03-31T19:11:56Z
> What I have in mind: > 1. Move autodecoding algorithms to undead. > 2. Remove autodecoding from algorithms. > 3. Have dfix rewrite std.algorithm to undead.algorithm How would that work in practice? std.algorithm is highly templated and the big issue are the auto-decoding primitives in std.range. We can't remove them easily nor even version them out (see e.g. https://github.com/dlang/phobos/pull/5513) and no one seems to have found a good transition path so far. For now .byCodeUnit is the only available workaround and maybe eventually RCString gets a thing.
Comment #3 by dfj1esp02 — 2018-08-03T11:43:41Z
(In reply to Seb from comment #2) > and no one seems to have found a good transition path so far. I mean replace std.algorithm with undead.algorithm in sources.
Comment #4 by robert.schadek — 2024-12-01T16:26:40Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/phobos/issues/10174 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB