Bug 4317 – Calling std.string.split with static array for separator fails to compile

Status
RESOLVED
Resolution
INVALID
Severity
minor
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
Windows
Creation time
2010-06-14T23:52:00Z
Last change time
2011-05-25T03:18:04Z
Assigned to
nobody
Creator
jpowers

Comments

Comment #0 by jpowers — 2010-06-14T23:52:59Z
Using D 2.047, get a template error at compilation from std.algorithm when calling split with a static array as the separator. The following code: module main; import std.string; void main() { char[3] foo = "t n"; string[] sa = split("split me now", foo); } fails with: ...phobos\std\algorithm.d(796): Error: template std.range.retro(R) if (isBidirectionalRange!(R)) does not match any function template declaration ...phobos\std\algorithm.d(796): Error: template std.range.retro(R) if (isBidirectionalRange!(R)) cannot deduce template function from argument types !()(char[3u]) This means the character sets provided in std.string cannot be used, i.e. split("some string", whitespace) will fail. Using an immutable array (as the char sets are) surfaces an additional compiler error: ...phobos\std\algorithm.d(804): Error: slice this._separator[] is not mutable Think there are actually two issues here, though fixing one likely fixes the other: 1. It doesn't work (see above). 2. Errors reported are rather difficult to track back to cause - there is no indication of what originally triggered the algorithm/range code.
Comment #1 by andrej.mitrovich — 2011-05-24T20:59:35Z
You have to pass a slice, e.g.: string[] sa = split("split me now", foo[]); and: split("some string", whitespace[])
Comment #2 by bearophile_hugs — 2011-05-25T02:47:42Z
(In reply to comment #1) > split("some string", whitespace[]) In std.string whitespace is defined as: immutable char[6] whitespace = " \t\v\r\n\f"; /// ASCII whitespace Isn't it better and nicer to define it as a normal string? immutable string whitespace = " \t\v\r\n\f"; /// ASCII whitespace
Comment #3 by issues.dlang — 2011-05-25T03:18:04Z
The template error is not the best, but it's definitely an error to try and use a static array as a range. You need to take a slice of it. > Isn't it better and nicer to define it as a normal string? > immutable string whitespace = " \t\v\r\n\f"; /// ASCII whitespace I'm currently in the process of rearranging some of std.string, std.ctype, and std.uni to make it more consistent in terms of naming and where each type of functionality goes (such as putting the functions which operate on single characters instead of strings in std.ctype if they deal with ASCII or std.uni if they deal with unicode rather than having them be in std.string which is supposed to operate on strings). One of the changes that I made does change whitespace to a string (albeit in std.ctype rather than std.string). So, assuming that my pull request passes peer review on github once I'm done, this particular case will work. However, what the compiler is doing is completely correct. Range functions _shouldn't_ work with static arrays, because static arrays are not ranges. They can't be, since they're not mutable. If the error is still this bad (which is questionable given that a number of functions in std.string, std.array, std.range, and std.algorithm have been moved around and/or updated since 2.047), then the template constraints on split should be improved. But the compiler is perfectly correct in not allowing this code to work.