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