Should we add drop to Phobos?

Jonathan M Davis jmdavisProg at gmx.com
Sat Aug 13 23:02:18 PDT 2011


Okay. Right now, if you want to remove n elements from the front of a range, 
you use popFrontN.

popFrontN(range, n);

This is obviously a highly useful function. However, it does not work very 
well when chaining range-based functions. For instance, what if you need to 
call find on a range, but you know that what you're looking for is not in the 
first n elements of that range? You'd do

popFrontN(range, n);
auto found = find(range, needle);

And what if you don't want to alter the range when you did that? You'd do 
something like

auto toFind = range.save;
toFind.popFrontN(range, n);
auto found = find(toFind, needle);

That's not very functional at all and requires multiple lines of code. Also, 
if you want to chain more than one function and need to call popFrontN 
multiple times in there, you can't chain them very well. popFrontN returns the 
actual number of elements popped, not the range, so you can't just pass its 
result into another range-based function.

However, if you had a drop function, you could do this

auto found = find(drop(range, n), needle);

You now only have one line of code instead of three. And if you have more 
complicated chaining, it's that much more useful. However, it does have one 
downside.

Both popFrontN and drop pop _up to_ n elements, so if there are fewer than n 
elements in the range, then as many elements as are in the range are popped. 
However, in the case of popFrontN, it returns the actual number of elements 
popped, so you know how many elements were popped. drop, on the other hand, 
returns the range with the elements popped, so you don't know how many 
elements were popped unless you do something like

auto newRange = drop(range, n);
auto elementsDropped = newRange.empty ? walkLength(range) : n;

Also, drop doesn't alter the original range, so if you call it multiple times 
on the same range instead of using popFrontN, then it's inefficient. However, 
it's not like we're getting rid of popFrontN, so if that's an issue, you can 
just call popFrontN instead. It's just up to the progammer to decide which is 
best for what they're doing. In cases where you want to chain range-based 
functions and don't want to alter the original range, drop is best. In cases 
where you want to alter the original range and don't necessarily care about 
chaining functions, popFrontN is best.

Now, as Andrei has pointed out, you can get a similar effect by doing 
(popFrontN(range, n), range). So, instead of

auto found = find(drop(range, n), needle);

you can do something like

auto found = find((popFrontN(range, n), range), needle);

However, that involves the comma operator, which most people avoid. It also 
alters the original range instead of returning a new one with n elements 
popped off, though whether that's good or bad depends on what you're doing.

So, the question is: Is drop worth having in Phobos? It's common in functional 
languages, and if you want to program in a more functional style, it's of 
enormous benefit. We'll still have popFrontN regardless, so the question is 
whether drop adds enough value to be worth having or whether it's just too 
similar to popFrontN to be worth adding to the standard library.

Personally, I think that drop would be a _very_ useful function to have. What 
do you think?

- Jonathan M Davis


More information about the Digitalmars-d mailing list