[erlang-patches] Add lists:find/2,3

Sean Cribbs <>
Wed Nov 13 23:06:29 CET 2013


Ah, that would be nice, does that essentially produce a hand-tuned Core
Erlang version of the function?

On Wed, Nov 13, 2013 at 2:25 PM, Anthony Ramine <> wrote:

> For fun and bonus points, you could inline these two functions with
> +inline_list_funcs.
>
> See sys_core_fold:call_1/5.
>
> --
> Anthony Ramine
>
> Le 13 nov. 2013 à 20:35, Sean Cribbs <> a écrit :
>
> > I've changed and force-pushed my pull-request to adjust the return
> values. Instead of the bare element being returned, it is now wrapped in a
> tuple as {value, Elem}. If nothing passes the predicate, 'false' is the new
> default return value rather than 'undefined'. I believe this makes it more
> consistent with other functions in the lists module, e.g. lists:keyfind/3.
> >
> > Please refetch: https://github.com/erlang/otp/pull/102
> >
> >
> > On Wed, Nov 13, 2013 at 9:51 AM, Serge Aleynikov <>
> wrote:
> > Thanks Steve for clarification. Though for that type of matching there's
> lists:keymember/3 (*) that covers a good portion of suggested use cases, I
> can see that in more complex scenarios find/2 could be useful, but is it
> generic enough to warrant an addition to the lists module? If find/2 is
> accepted, it seems to me that the index_of/2 prototyped in my prior email
> could be another valuable candidate, as that is currently not doable via a
> combination of functions in the lists module (other than by means of
> lists:foldl/3 and throw, which is a bit ugly).
> >
> > (*) 1> lists:keymember(a, 1, [{c, 2}, d, {e, 3}, [a,b,c], {a, 4}]).
> > true
> >
> >
> >
> >
> > On Wed, Nov 13, 2013 at 9:23 AM, Steve Vinoski <> wrote:
> > lists:member/2 matches (using =:=) entire elements to determine whether
> or not they are present in the list, whereas the proposed lists:find/2,3
> allows the caller to pass a fun to test for element presence. The fun
> allows the caller to ignore fields of an element that's a tuple, record
> etc. for purposes of determining whether something is or is not present in
> the list. Therefore lists:member/2 can't do what the proposed
> lists:find/2,3 can do.
> >
> > --steve
> >
> >
> >
> > On Wed, Nov 13, 2013 at 9:08 AM, Serge Aleynikov <>
> wrote:
> > Since finding an element in the list is already doable via
> lists:member/2, it seems to me that there's very little benefit in that
> find/2 function.  Whereas a more valuable addition would be to find an
> index of the element in the given list.  An example of a common use case
> for that would be to locate a field's position in a mnesia table by name
> (e.g. index_of):
> >
> > update_table(Table, FieldName, Value) ->
> >   Attrs = mnesia:table_info(Table, attributes),
> >   {ok, Pos} = index_of(FieldName, Attrs),
> >   R = mnesia:dirty_read(Table, Key),
> >   R1 = setelement(Pos, R, NewValue),
> >   ok = mnesia:dirty_write(Table, R1).
> >
> > index_of(Value, List) ->
> >   index_of(Value, List, 1).
> > index_of(V, [V|T], N) ->
> >   {ok, N};
> > index_of(V, [_|T], N) ->
> >   index_of(V, T, N+1);
> > index_of(_, [], _) ->
> >   false.
> >
> >
> > On Wed, Nov 13, 2013 at 5:48 AM, Thomas Järvstrand <
> > wrote:
> > A more generic version would be to return the first result of applying
> the fun to an element that does not return false. That way you can choose
> whether to return the actual element, the result of the computation you
> just or even something completely different. The user is also free to wrap
> the result in case he/she is worried that the return value might be `false`.
> >
> > Example implementation:
> > find(_MatchF, []) ->
> >   false;
> > find(MatchF, [X|Xs]) ->
> >   case MatchF(X) of
> >     false -> find(MatchF, Xs);
> >     Val   -> Val
> >   end.
> >
> > Thomas
> >
> >
> > 2013/10/22 Anthony Ramine <>
> > Forwarding to list.
> >
> > --
> > Anthony Ramine
> >
> > Le 22 oct. 2013 à 11:56, Anthony Ramine <> a écrit :
> >
> > > Maybe we could just have dropuntil(F, L) -> dropwhile(fun (X) -> not
> F(X) end, L).
> > >
> > > Of course, the function would be written less naively to avoid
> constructing a new fun.
> > >
> > > --
> > > Anthony Ramine
> > >
> > > Le 14 oct. 2013 à 15:52, Sean Cribbs <> a écrit :
> > >
> > >> #1: Would tagging the return value address like Masklinn mentions
> address your concern? {ok, Term} | error (instead of a default value)?
> > >>
> > >> #2: Also, I considered dropwhile but it involves introducing another
> fun, whereas the version I wrote is direct.
> > >>
> > >>
> > >> On Mon, Oct 14, 2013 at 5:28 AM, Anthony Ramine <>
> wrote:
> > >> Hello Sean,
> > >>
> > >> I don't like this patch.
> > >>
> > >> 1/ You can't know whether an element was found or not if the list
> elements are arbitrary terms.
> > >> 2/ I don't see why you would say people hack either foreach/2 or
> foldl/3 to do that when they should just use dropwhile/2.
> > >>
> > >> A naive implementation of find/2 using dropwhile/2:
> > >>
> > >> find(F, L) ->
> > >>        case dropwhile(fun (E) -> not F(E) end, L) of
> > >>                [] -> undefined;
> > >>                [E|_] -> E
> > >>        end.
> > >>
> > >> Regards,
> > >>
> > >> --
> > >> Anthony Ramine
> > >>
> > >> Le 14 oct. 2013 à 02:44, Sean Cribbs <> a écrit :
> > >>
> > >>> `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, `undefined` (/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.
> > >>>
> > >>> https://github.com/erlang/otp/pull/102
> > >>>
> > >>> --
> > >>> Sean Cribbs <>
> > >>> Software Engineer
> > >>> Basho Technologies, Inc.
> > >>> http://basho.com/
> > >>> _______________________________________________
> > >>> erlang-patches mailing list
> > >>> 
> > >>> http://erlang.org/mailman/listinfo/erlang-patches
> > >>
> > >>
> > >>
> > >>
> > >> --
> > >> Sean Cribbs <>
> > >> Software Engineer
> > >> Basho Technologies, Inc.
> > >> http://basho.com/
> > >
> >
> > _______________________________________________
> > erlang-patches mailing list
> > 
> > http://erlang.org/mailman/listinfo/erlang-patches
> >
> >
> > _______________________________________________
> > erlang-patches mailing list
> > 
> > http://erlang.org/mailman/listinfo/erlang-patches
> >
> >
> >
> > _______________________________________________
> > erlang-patches mailing list
> > 
> > http://erlang.org/mailman/listinfo/erlang-patches
> >
> >
> >
> >
> > _______________________________________________
> > erlang-patches mailing list
> > 
> > http://erlang.org/mailman/listinfo/erlang-patches
> >
> >
> >
> >
> > --
> > Sean Cribbs <>
> > Software Engineer
> > Basho Technologies, Inc.
> > http://basho.com/
> > _______________________________________________
> > erlang-patches mailing list
> > 
> > http://erlang.org/mailman/listinfo/erlang-patches
>
>


-- 
Sean Cribbs <>
Software Engineer
Basho Technologies, Inc.
http://basho.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-patches/attachments/20131113/cc73bfab/attachment.html>


More information about the erlang-patches mailing list