www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Interest in std.algorithm.joiner?

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
We have std.algorithm.splitter which splits a range into components 
without allocating a new array.

Is there an interest in joiner(), the corresponding function for join() 
that joins elements of a range in conjunction with a separator without 
allocating a new array?


Andrei
Jul 27 2010
next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 We have std.algorithm.splitter which splits a range into components
 without allocating a new array.
 Is there an interest in joiner(), the corresponding function for join()
 that joins elements of a range in conjunction with a separator without
 allocating a new array?
 Andrei

Absolutely. I was thinking a while back I was going to suggest a std.range.flattener() or std.algorithm.flattener() that takes a range of ranges and turns them into a single range, one right after the other. joiner() would be a generalization of this in that to flatten a ror, you'd just join it on an empty range.
Jul 27 2010
parent bearophile <bearophileHUGS lycos.com> writes:
dsimcha:
 Absolutely.  I was thinking a while back I was going to suggest a
 std.range.flattener() or std.algorithm.flattener() that takes a range of ranges
 and turns them into a single range, one right after the other.

That's a chain() not a flattener() :-) A flatten operation is usually meant when you have a tree (sometimes even a tree of arbitrary and dis-uniform depth) of iterables and you want to fully linearise it. Bye, bearophile
Jul 27 2010
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 We have std.algorithm.splitter which splits a range into components 
 without allocating a new array.

In Python (and D) a commonly useful function is split() that splits a string according to whitespace, and split(str) that splits it according to a string. There is a similar function in std.string. Then Python misses a lot a function that does the same of split/split(str) but yields its results lazily, this can save a large amount of memory if the string to split is very large. Such split/xsplit (or splitter) are very useful for arrays too, and generic ranges (lazy too).
 Is there an interest in joiner(), the corresponding function for join() 
 that joins elements of a range in conjunction with a separator without 
 allocating a new array?

A join, that does the opposite of split is very useful, especially if strings are an immutable data type (and it's useful for other arrays too, etc). Is your joiner like chain(), that is it gives a lazy iterable as chain(), but also contains the separator? A join when used on strings is often used to build a string that later is stored somewhere or often printed. If your printing functions accept lazy sequences of strings too, for example given by joiner, then I think joiner() can be useful. For generic arrays I can't see immediate usages. Bye, bearophile
Jul 27 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisprog gmail.com> writes:
On Tuesday, July 27, 2010 08:21:08 Andrei Alexandrescu wrote:
 We have std.algorithm.splitter which splits a range into components
 without allocating a new array.
 
 Is there an interest in joiner(), the corresponding function for join()
 that joins elements of a range in conjunction with a separator without
 allocating a new array?
 
 
 Andrei

Well, I don't think that I can currently say that I've written an app that would have liked to have joiner(), but I've definitely used join() often enough. However, I'd argue that it would be good to add it for completeness' sake, if nothing else. And it wouldn't surprise me at all to end up writing an app one of these days that found joiner() to be quite useful. I certainly can't think of any reason for _not_ having it. - Jonathan M Davis
Jul 27 2010
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 27 Jul 2010 11:21:08 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 We have std.algorithm.splitter which splits a range into components  
 without allocating a new array.

 Is there an interest in joiner(), the corresponding function for join()  
 that joins elements of a range in conjunction with a separator without  
 allocating a new array?

How do you do that? -Steve
Jul 27 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 On Tue, 27 Jul 2010 11:21:08 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 
 We have std.algorithm.splitter which splits a range into components 
 without allocating a new array.

 Is there an interest in joiner(), the corresponding function for 
 join() that joins elements of a range in conjunction with a separator 
 without allocating a new array?

How do you do that?

Well joiner would offer an input or in best case a forward range with the range primitives. Andrei
Jul 27 2010
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 On Tue, 27 Jul 2010 14:12:34 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Steven Schveighoffer wrote:
 On Tue, 27 Jul 2010 11:21:08 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:

 We have std.algorithm.splitter which splits a range into components 
 without allocating a new array.

 Is there an interest in joiner(), the corresponding function for 
 join() that joins elements of a range in conjunction with a 
 separator without allocating a new array?


Well joiner would offer an input or in best case a forward range with the range primitives.

How do you store all the ranges you joined for future reference without creating an array of those ranges? With splitter, it's straightforward, there's one range to store. Or am I missing something?

It's just one range and one separator. auto joined = joiner(["Mary", "has"], "\t"); assert(joined.front == 'M'); Andrei
Jul 27 2010
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 On Tue, 27 Jul 2010 14:27:20 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Steven Schveighoffer wrote:
 On Tue, 27 Jul 2010 14:12:34 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:

 Steven Schveighoffer wrote:
 On Tue, 27 Jul 2010 11:21:08 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:

 We have std.algorithm.splitter which splits a range into 
 components without allocating a new array.

 Is there an interest in joiner(), the corresponding function for 
 join() that joins elements of a range in conjunction with a 
 separator without allocating a new array?


Well joiner would offer an input or in best case a forward range with the range primitives.

without creating an array of those ranges? With splitter, it's straightforward, there's one range to store. Or am I missing something?

It's just one range and one separator. auto joined = joiner(["Mary", "has"], "\t"); assert(joined.front == 'M');

Ah, Ok. I was under the impression that the input was a bunch of individual ranges to join. So basically, you are pushing the "range of ranges" allocation onto the user. That works. That is quite an interesting problem, esp if you intend to keep it lazy and forward things like random access to the joined range. Or output the result to writeln. Hey, could it potentially be used as a formatter to writefln?

As of the upcoming release, I changed write() and writeln() to fully support input ranges. Andrei
Jul 27 2010
prev sibling next sibling parent sybrandy <sybrandy gmail.com> writes:
 It's just one range and one separator.

 auto joined = joiner(["Mary", "has"], "\t");
 assert(joined.front == 'M');


 Andrei

Looks good to me. I vote for having it. Casey
Jul 27 2010
prev sibling parent Rory Mcguire <rjmcguire gm_no_ail.com> writes:
Andrei Alexandrescu wrote:

 Steven Schveighoffer wrote:
 On Tue, 27 Jul 2010 14:12:34 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Steven Schveighoffer wrote:
 On Tue, 27 Jul 2010 11:21:08 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 We have std.algorithm.splitter which splits a range into components
 without allocating a new array.

 Is there an interest in joiner(), the corresponding function for
 join() that joins elements of a range in conjunction with a
 separator without allocating a new array?


Well joiner would offer an input or in best case a forward range with the range primitives.

How do you store all the ranges you joined for future reference without creating an array of those ranges? With splitter, it's straightforward, there's one range to store. Or am I missing something?

It's just one range and one separator. auto joined = joiner(["Mary", "has"], "\t"); assert(joined.front == 'M'); Andrei

Not sure, but wouldn't it be better to call that unite?
Jul 29 2010
prev sibling parent dsimcha <dsimcha yahoo.com> writes:
== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s article
 On Tue, 27 Jul 2010 14:12:34 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Steven Schveighoffer wrote:
 On Tue, 27 Jul 2010 11:21:08 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 We have std.algorithm.splitter which splits a range into components
 without allocating a new array.

 Is there an interest in joiner(), the corresponding function for
 join() that joins elements of a range in conjunction with a separator
 without allocating a new array?


Well joiner would offer an input or in best case a forward range with the range primitives.

creating an array of those ranges? With splitter, it's straightforward, there's one range to store. Or am I missing something? -Steve

I was under the impression that the idea is that you'd have a range of ranges, for example an array of strings.
Jul 27 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 27 Jul 2010 14:12:34 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Steven Schveighoffer wrote:
 On Tue, 27 Jul 2010 11:21:08 -0400, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:

 We have std.algorithm.splitter which splits a range into components  
 without allocating a new array.

 Is there an interest in joiner(), the corresponding function for  
 join() that joins elements of a range in conjunction with a separator  
 without allocating a new array?


Well joiner would offer an input or in best case a forward range with the range primitives.

How do you store all the ranges you joined for future reference without creating an array of those ranges? With splitter, it's straightforward, there's one range to store. Or am I missing something? -Steve
Jul 27 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 27 Jul 2010 14:27:20 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Steven Schveighoffer wrote:
 On Tue, 27 Jul 2010 14:12:34 -0400, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:

 Steven Schveighoffer wrote:
 On Tue, 27 Jul 2010 11:21:08 -0400, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:

 We have std.algorithm.splitter which splits a range into components  
 without allocating a new array.

 Is there an interest in joiner(), the corresponding function for  
 join() that joins elements of a range in conjunction with a  
 separator without allocating a new array?


Well joiner would offer an input or in best case a forward range with the range primitives.

without creating an array of those ranges? With splitter, it's straightforward, there's one range to store. Or am I missing something?

It's just one range and one separator. auto joined = joiner(["Mary", "has"], "\t"); assert(joined.front == 'M');

Ah, Ok. I was under the impression that the input was a bunch of individual ranges to join. So basically, you are pushing the "range of ranges" allocation onto the user. That works. That is quite an interesting problem, esp if you intend to keep it lazy and forward things like random access to the joined range. Or output the result to writeln. Hey, could it potentially be used as a formatter to writefln? -Steve
Jul 27 2010
prev sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--0016e6dd8a2950c02c048c8587d4
Content-Type: text/plain; charset=ISO-8859-1

 Andrei Alexandrescu wrote:
 Is there an interest in joiner(), the corresponding function for
 join() that joins elements of a range in conjunction with a
 separator without allocating a new array?






Seeing your code in svn, wouldn't also a flatten() (or, concat() ) function be interesting? It transforms a range of ranges (of whatever depth) into a linear range. Also, interpose(range, element) that returns range[0], element, range[1], element, etc. and interleave(range1, range2) that produces range1[0], range2[0], range1[1], range2[1], range1[2], ... Isn't joiner just chain(interpose(["Mary", "has", "a", "little", "lamb"], "...")? std.range.transversal is a bit... short on this one: it just iterates through a 'vertical' slice. Philippe --0016e6dd8a2950c02c048c8587d4 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margi= n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class=3D"im= ">Andrei Alexandrescu wrote:<br>&gt;&gt;&gt;&gt;&gt; Is there an interest i= n joiner(), the corresponding function for<br> &gt;&gt;&gt;&gt;&gt; join() that joins elements of a range in conjunction w= ith a<br> &gt;&gt;&gt;&gt;&gt; separator without allocating a new array?<br></div></b= lockquote><div><br></div><div>Seeing your code in svn, wouldn&#39;t also a = flatten() (or, concat() ) function be interesting? It transforms a range of= ranges (of whatever depth) into a linear range.</div> <div><br></div><div>Also, interpose(range, element) that returns range[0], = element, range[1], element, etc.</div><div>and interleave(range1, range2) t= hat produces range1[0], range2[0], range1[1], range2[1], range1[2], ...</di= v> <div><br></div><div>Isn&#39;t joiner just chain(interpose([&quot;Mary&quot;= , &quot;has&quot;, &quot;a&quot;, &quot;little&quot;, &quot;lamb&quot;], &q= uot;...&quot;)?</div><div><br></div><div>std.range.transversal is a bit... = short on this one: it just iterates through a &#39;vertical&#39; slice.</di= v> <div><br></div><div><br></div><div><br></div><div>Philippe</div><div>=A0</d= iv></div> --0016e6dd8a2950c02c048c8587d4--
Jul 29 2010