[erlang-questions] Weird lists:dropwhile/2 behavior?

Richard A. O'Keefe <>
Mon Feb 22 02:08:26 CET 2016

```
On 22/02/16 2:40 am, fxmy wang wrote:
> Thanks guys, somehow the doc gives me a feeling that lists:dropwhile
> will scan through all the list no matter Pred(Elem) returns 'true' or
> 'false'. =)

The documentation is unfortunately sparse.

dropwhile(Pred, List1) -> List2

Types:

Pred = fun((Elem :: T) -> boolean())
List1 = List2 = [T]
T = term()

Drops elements Elem from List1 while Pred(Elem) returns true and returns
the remaining list.

You have to read closely to see the word WHILE there.
For takewhile/2 it's clearer:

takewhile(Pred, List1) -> List2

Types:

Pred = fun((Elem :: T) -> boolean())
List1 = List2 = [T]
T = term()
Takes elements Elem from List1 while Pred(Elem) returns true, that is,
the function returns the longest prefix of the list for which all
elements satisfy the predicate.

For all L and for all F such that [F(X) || X <- L] contains only true
and false,
takewhile(F, L) ++ dropwhile(F, L) == L.

The takewhile and dropwhile functions (why on earth are they not
take_while and drop_while? since when has Erlang runwordstogetherlikeC?)
are not unique to Erlang.   For example, in Haskell
> dropWhile (> 3) [1..5]
[1,2,3,4,5]

I propose the following revision to the documentation.

%% dropwhile

Let List == Prefix ++ Suffix where Pred(X) is true for every X in Prefix
and Prefix is as long as possible.  dropwhile(Pred, List) returns Prefix.
See takewhile/2.

%% takewhile

Let List == Prefix ++ Suffix where Pred(X) is true for every X in Prefix
and Prefix is as long as possible.  takewhile(Pred, List) returns Suffix.
See dropwhile/2.

```