Should we add drop to Phobos?

Jonathan M Davis jmdavisProg at gmx.com
Mon Aug 15 19:33:57 PDT 2011


On Tuesday, August 16, 2011 04:26:48 Martin Nowak wrote:
> I personally like immutable methods way better than a ref changing  
> function like popFrontN.
> As you pointed out writing str.find(";").drop(2).find(";").drop(2) is  
> cleaner than writing this with popFrontN.
> 
> Drop will have issues for input ranges.

No more than many range-based functions do. Yes, it'll alter the input, that's
to be expected with any range-based function that you pass an input range
to. drop could be made to take only a forward range, but that seems
unnecessarily limiting. You just have to be aware of the fact that range-based
functions always remove elements from input ranges when they process them
- either that or they don't work with input ranges.

> Adding a ref count parameter overload to let you know how many elements  
> were dropped/not dropped seems too messy. No idea for that one.

It's a tradeoff. And if you really want drop, you probably don't care anyway,
since what you'd be doing would be chaining functions. If you really care,
just use popFrontN.

> The documentation should clearly state that this offers similar  
> functionality to popFrontN but it's purpose
> is to enable a different syntax so that people don't get completely  
> confused.

It does. This is the ddoc comment that I have for it:

/++
    Pops $(D n) elements off of the given range and returns it. If the length of
    the given range is less than $(D n), then an empty range is returned. The
    original range is unaltered as long as it's a value type.

    The main reason to use $(D drop) instead of $(LREF popFrontN) is so that you
    can pop elements off of a range and pass the resulting range to another
    range-based function in a single expression, allowing you to chain function
    calls. It allows for a more functional style of programming. However, this
    means that you don't know exactly how many elements were actually popped in
    the case where the range had fewer than $(D n) elements (unless you got its
    length first, which isn't an efficient thing to do for all ranges). Also,
    because it doesn't take the range by reference (unlike $(LREF popFrontN)),
    you can pass the results of other functions to it directly. But that also
    means that it does not affect the original range as long as it's a value
    type, which may or may not be what you want, depending on what you're doing.

    Examples:
--------------------
assert(drop([0, 2, 1, 5, 0, 3], 3) == [5, 0, 3]);
assert(drop("hello world", 6) == "world");
assert(drop("hello world", 50).empty);
assert(equal(drop(take("hello world", 6), 3), "lo "));
--------------------
  +/

- Jonathan M Davis


More information about the Digitalmars-d mailing list