Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add lists:find/2,3 #102

Closed
wants to merge 1 commit into from
Closed

Conversation

seancribbs
Copy link
Contributor

lists:find/2,3 returns the first element of the passed list for which the predicate fun returns true, wrapped in a tuple {value, Elem}. If no elements result in the predicate being true, false (/2) or the given default value (/3) is returned.

Why this new feature?

A common task is to select the first element from a list that matches a condition, but there is no existing lists function or language feature that avoids traversing the entire list, while still returning a "safe" value. lists:find/2,3 codifies the pattern of a tail-recursive search for the matching item without resorting to exceptions (used to abort foreach/2 or foldl/3) and always returns either the first matching item, or an otherwise safe value.

Risks / uncertain artifacts

It is unclear the desired order of arguments for the 3-arity version. I have made the default value the final argument which is consistent with application:get_env/3 and proplists:get_value/3, but most functions in lists place the List argument last.

How did you solve it?

Following the patterns of other functions in the lists module, lists:find/3 tests the predicate function against the head of the list, returning the head if the predicate passes, or recursing over the tail if it does not.

@OTP-Maintainer
Copy link

Patch has passed first testings and has been assigned to be reviewed

@jaynel
Copy link
Contributor

jaynel commented Oct 15, 2013

Isn't lists:dropwhile/2 more general?

Default :: term().

find(Pred, [], Default) when is_function(Pred, 1)-> Default;
find(Pred, [H|T], Default) ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The guard for the predicate should be on the clause where you actually call the function :)

EDIT: Actually, you should probably remove the guard altogether. Without it, a Pred that is not a function will give a "bad function" error which is more informative than "function clause".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally I would agree with you but all of the other functions in this module only guard on the empty-list case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you see my edit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but in the case where you pass an empty list, you won't get an error if Pred is an invalid function.

lists:find/2,3 returns the first element of the passed list for which
the predicate fun returns true. If no elements result in the predicate
being true, 'false' (/2) or the given default value (/3) is returned.
@proxyles
Copy link
Contributor

We find that lists:dropwhile/2 does this already

@proxyles proxyles closed this Jan 23, 2014
@seancribbs
Copy link
Contributor Author

I'm surprised this was closed so abruptly, since there hasn't been any discussion or feedback from OTP in the past three months.

lists:dropwhile/2 requires you to invert the logic of the predicate, match on the result testing for the empty list, then taking the head of the list if non-empty. That seems like a lot of boilerplate for something so fundamental and straightforward.

uabboli added a commit to uabboli/otp that referenced this pull request Mar 9, 2018
This is essentially PR 102, erlang#102.

The OTP Technical Board decided to change the name of the function to
search/2.
@seancribbs seancribbs deleted the sdc/lists-find branch March 26, 2018 17:40
uabboli pushed a commit to uabboli/otp that referenced this pull request Dec 1, 2020
…roper-lists

try to fix non-proper lists in state
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants