Bug 8851 – std.string.join should allow 'char' as joiner

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-10-18T15:26:00Z
Last change time
2015-01-03T17:04:04Z
Assigned to
rburners
Creator
andrej.mitrovich

Comments

Comment #0 by andrej.mitrovich — 2012-10-18T15:26:25Z
import std.string; void main() { char sep = '|'; string z = ["foo", "bar"].join(sep); } test.d(7): Error: template std.array.join does not match any function template declaration D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\array.d(1273): Error: template std.array.join cannot deduce template function from argument types !()(string[],char) Well apparently it's std.array.join, but nevertheless it should work.
Comment #1 by issues.dlang — 2012-10-18T16:17:08Z
I expect that this stems from the stupidity of character literals defaulting to char rather than dchar, and when you couple that with the fact that templates always use the _exact_ type of what you give them, it's going to try and instantiate join with a separator of char, which doesn't work with ranges of dchar. I'm not sure how you'd go about fixing that.
Comment #2 by monarchdodra — 2012-10-19T02:36:28Z
(In reply to comment #1) > I expect that this stems from the stupidity of character literals defaulting to > char rather than dchar, and when you couple that with the fact that templates > always use the _exact_ type of what you give them, it's going to try and > instantiate join with a separator of char, which doesn't work with ranges of > dchar. I'm not sure how you'd go about fixing that. I investigated, and that's not it. It's *just* that std.array.join, like std.algorithm.joiner, expects the separator to be a range. The enhancement request here would be for both "std.array.join" std.algorithm.joiner" to accept a single element as a separator. In the meantime, of course, a simple workaround is to just "join([sep])". I think this needlessly allocates a 1 element array though, no? -------- On a side note, the current restrictions in join are overly restrictive, requiring an exact match, making this illegal: int[] sep = [1]; double[] z = [[0.1], [0.2]].join(sep); When it is perfectly supported: joiner supports it.
Comment #3 by monarchdodra — 2012-10-19T02:39:28Z
(In reply to comment #1) > I expect that this stems from the stupidity of character literals defaulting to > char rather than dchar, and when you couple that with the fact that templates > always use the _exact_ type of what you give them, it's going to try and > instantiate join with a separator of char, which doesn't work with ranges of > dchar. I'm not sure how you'd go about fixing that. I investigated, and that's not it. It's *just* that std.array.join, like std.algorithm.joiner, expects the separator to be a range. The enhancement request here would be for both "std.array.join" std.algorithm.joiner" to accept a single element as a separator. In the meantime, of course, a simple workaround is to just "join([sep])". I think this needlessly allocates a 1 element array though, no? -------- On a side note, the current restrictions in join are overly restrictive, requiring an *exact* ElementType match, making this illegal: int[] sep = [1]; double[] z = [[0.1], [0.2]].join(sep); The implementation actually perfectly supports it. As a matter of fact, joiner supports it. I'll see into relaxing the restraints for now, and taking the opportunity to investigate using an element as a separator.
Comment #4 by monarchdodra — 2012-10-19T02:45:07Z
(In reply to comment #3) > (In reply to comment #1) > > I expect that this stems from the stupidity of character literals defaulting to > > char rather than dchar, and when you couple that with the fact that templates > > always use the _exact_ type of what you give them, it's going to try and > > instantiate join with a separator of char, which doesn't work with ranges of > > dchar. I'm not sure how you'd go about fixing that. > > I investigated, and that's not it. > > It's *just* that std.array.join, like std.algorithm.joiner, expects the > separator to be a range. > > The enhancement request here would be for both "std.array.join" > std.algorithm.joiner" to accept a single element as a separator. > > In the meantime, of course, a simple workaround is to just "join([sep])". > > I think this needlessly allocates a 1 element array though, no? > > -------- > On a side note, the current restrictions in join are overly restrictive, > requiring an *exact* ElementType match, making this illegal: > > int[] sep = [1]; > double[] z = [[0.1], [0.2]].join(sep); > > The implementation actually perfectly supports it. As a matter of fact, joiner > supports it. I'll see into relaxing the restraints for now, and taking the > opportunity to investigate using an element as a separator. That was fast actually. Both the fix and the enhancement are trivially trivial. I believe in the change, so I'm assigning to self.
Comment #5 by andrej.mitrovich — 2013-09-17T15:26:11Z
(In reply to comment #4) > I believe in the change, so I'm assigning to self. Is this part of any open pulls you've made?
Comment #6 by monarchdodra — 2013-09-17T23:34:29Z
(In reply to comment #5) > (In reply to comment #4) > > I believe in the change, so I'm assigning to self. > > Is this part of any open pulls you've made? Turns out I *completely* forgot about this. If you want to do anything regarding this pull, please go right on ahead. Seems code gets into Phobos faster when I review rather than write ^^
Comment #7 by andrei — 2013-09-18T01:15:22Z
better yet, accept dchar
Comment #8 by monarchdodra — 2013-09-18T03:00:56Z
(In reply to comment #7) > better yet, accept dchar Well, it's just a public import of std.array.join, so it should really just accept "(R, E)" and "(R, R)".
Comment #9 by bearophile_hugs — 2013-09-21T05:27:57Z
See also Issue 5542 that is different but related.
Comment #10 by rburners — 2014-09-11T11:17:38Z
anyone working on this currently?
Comment #11 by monarchdodra — 2014-09-11T21:38:39Z
(In reply to Robert Schadek from comment #10) > anyone working on this currently? No one that I know of. Although 'only' was recently introduced that helped work around the issue, it is still in need of fixing.
Comment #12 by andrej.mitrovich — 2014-09-12T08:43:24Z
I've tried using only but it didn't really work.
Comment #13 by rburners — 2014-09-12T09:50:26Z
(In reply to Andrej Mitrovic from comment #12) > I've tried using only but it didn't really work. example?
Comment #14 by andrej.mitrovich — 2014-09-12T10:05:56Z
import std.string; void main() { char sep = '|'; string z = ["foo", "bar"].join(sep.only); }
Comment #15 by monarchdodra — 2014-09-12T11:09:47Z
(In reply to Andrej Mitrovic from comment #14) > import std.string; > > void main() > { > char sep = '|'; > string z = ["foo", "bar"].join(sep.only); > } I'll assume you also imported std.range, and got this error? Error: template std.array.join cannot deduce function from argument types ... It seems the issue here is that the template restrictions are overzealous in that it checks for exact element type matching, rather than checking if they have a common type (Or at the very least, if ElementType!Sep is implicitly convertible to ElementType!(ElementType!RoR)). As a workaround, using an (explicit) dchar only works. //---- import std.range; import std.stdio; void main() { ["foo", "bar"].join(dchar('|').only).writeln(); } //---- So Jonathan's original assesment(https://issues.dlang.org/show_bug.cgi?id=8851#c1) was also correct (it's a dual issue I guess)
Comment #16 by andrej.mitrovich — 2014-09-12T11:32:52Z
Yeah, looks like we may have to make multiple fixes here? Anyway, it would be nice to get this taken care of. :)
Comment #17 by rburners — 2014-09-12T11:36:04Z
I'm on it
Comment #18 by rburners — 2014-09-16T21:44:43Z
issue 5542 refers to the same bug
Comment #19 by bearophile_hugs — 2014-09-16T22:03:17Z
(In reply to Robert Schadek from comment #18) > issue 5542 refers to the same bug Issue 5542: join("123", "x") ==> "1x2x3" This issue: join(["foo", "bar"], '|') ==> "foo|bar"
Comment #20 by rburners — 2014-09-16T22:11:39Z
woops sry, lets stay both issues are from the same class
Comment #21 by rburners — 2014-09-18T22:39:51Z
Comment #22 by github-bugzilla — 2014-09-19T16:41:12Z