Proposal: takeFront and takeBack

Jonathan M Davis jmdavisProg at gmx.com
Tue Jul 3 11:00:42 PDT 2012


On Tuesday, July 03, 2012 10:40:07 Jonathan M Davis wrote:
> On Tuesday, July 03, 2012 17:31:21 Christophe Travert wrote:
> > takeFront implementation is dangerous for ranges which invalidates their
> > front value when popFront is called, for instance, File.byLine. Thus
> > takeFront will have to be used with care: any range implement takeFront
> > (because of the template and USFC), but it may not be valid. That makes
> > the range interface more complicated: There is a takeFront property, but
> > you have to check it is safe to use... how do you check that by the way?
> 
> Hmm. I hadn't thought of that. That could be a good reason not to do this.
> I'm not quite sure how to get around that. Hmmm... It would arguably be a
> bit ugly, but a range which couldn't safely be used with takeFront could
> have an enum on it which indicated that, and takeFront would fail to
> compile if used with such a range. Of course, that would mean that you'd
> have to special case such ranges in any range-based function which used
> takeFront so that there was a branch which didn't use takeFront for ranges
> which couldn't use it.
> 
> I don't know. It's certainly something to think about. We may need a
> different solution.

An alternative would be to make it so that takeFront (or consumeFront, as 
someone suggested, since that's a better name) would be defined only for ranges 
which it helps. So, similar to hasSlicing, you get something like hasConsume, 
and then a range-based function which wants to use consumeFront or consumeBack 
checks hasConsume!R and uses it on that particular static if branch if it does 
and uses another branch with front and popFront if it doesn't. 
std.range.consumeFront then works only with strings (and maybe arrays).

However, it seemed to me that a major upside of consumeFront as I proposed it 
was that you could always just use it, and it would do the most efficient thing, 
so you _didn't_ have to special case for it, whereas with hasConsume, you 
would. But if you can't use consumeFront safely on all ranges, then that 
doesn't really work. It's still worth something but not as much.

You can already special case strings (and in many cases need to). What 
consumeFront does is make it so that functions operating on wrappers around 
strings (i.e. the results of functions like filter or map) can operate on them 
more efficiently as well. It also makes it so that user-defined ranges can get 
that benefit from algorithms that know nothing about those ranges and therefore 
don't special case them (e.g. std.algorithm functions can then be more efficient 
for user-defined ranges which can define a more efficient consumeFront). So, even 
if we had hasConsume and functions had to special case in order to use 
consumeFront or consumeBack, it would still be beneficial. However, it would be 
nice to have a solution which _didn't_ require special casing.

- Jonathan M Davis


More information about the Digitalmars-d mailing list