improving the join function

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Mon Oct 11 17:33:27 PDT 2010


I'm looking at http://d.puremagic.com/issues/show_bug.cgi?id=3313 and 
that got me looking at std.string.join, which currently has the sig:

string join(in string[] words, string sep);

A narrow fix:

Char[] join(Char)(in Char[][] words, in Char[] sep)
if (isSomeChar!Char);

I think it's reasonable to assume that people would want to join things 
that aren't necessarily arrays of characters, so T could be pretty much 
any type. An obvious step towards generalization is:

T[] join(T)(in T[][] items, T[] sep);

But join doesn't really need random access for words - really, an input 
range should suffice. So a generally useful join, almost worth putting 
in std.algorithm, would be:

ElementType!R1[] join(R1, R2)(R1 items, R2 sep)
if (isInputRange!R1 && isForwardRange!R2
     && is(ElementType!R2 : ElementType!R1);

Notice how the separator must be a forward range because it gets spanned 
multiple times, whereas the items need only be an input range as they 
are spanned once. This is at the same time a very general and very 
precise interface.

One thing is still bothering me: the array output type. Why would the 
"default" output range be an array? What can be done to make join() at 
the same time a general function and also one that works for strings the 
way the old join did? For example, if I want to join things into an 
already-existing buffer, or if I want to write them straight to a file, 
there's no way to do so without having an array allocation in the loop. 
I have a couple of ideas but I wouldn't want to bias yours.

I also have a question from people who dislike Phobos. Was there a point 
in the changes of signature above where you threw your hands thinking, 
"do the darn string version already and cut all that crap!"?


Thanks,

Andrei


More information about the Digitalmars-d mailing list