Re: Add lists:find/2,3
Sean Cribbs <[email protected]>
| Newsgroups | gmane.comp.lang.erlang.patches |
|---|---|
| Message-ID | <CAHsw=e3W4GoF3GZ+1tZ499qfYNLDsfydtBM9rUf52oqfcVjFFw@mail.gmail.com> |
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 <[email protected]> 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 <[email protected]> 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 <[email protected]> > 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 <[email protected]> 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 <[email protected]> > 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 < > [email protected]> 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 <[email protected]> > > Forwarding to list. > > > > -- > > Anthony Ramine > > > > Le 22 oct. 2013 à 11:56, Anthony Ramine <[email protected]> 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 <[email protected]> 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 <[email protected]> > 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 <[email protected]> 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 <[email protected]> > > >>> Software Engineer > > >>> Basho Technologies, Inc. > > >>> http://basho.com/ > > >>> _______________________________________________ > > >>> erlang-patches mailing list > > >>> [email protected] > > >>> http://erlang.org/mailman/listinfo/erlang-patches > > >> > > >> > > >> > > >> > > >> -- > > >> Sean Cribbs <[email protected]> > > >> Software Engineer > > >> Basho Technologies, Inc. > > >> http://basho.com/ > > > > > > > _______________________________________________ > > erlang-patches mailing list > > [email protected] > > http://erlang.org/mailman/listinfo/erlang-patches > > > > > > _______________________________________________ > > erlang-patches mailing list > > [email protected] > > http://erlang.org/mailman/listinfo/erlang-patches > > > > > > > > _______________________________________________ > > erlang-patches mailing list > > [email protected] > > http://erlang.org/mailman/listinfo/erlang-patches > > > > > > > > > > _______________________________________________ > > erlang-patches mailing list > > [email protected] > > http://erlang.org/mailman/listinfo/erlang-patches > > > > > > > > > > -- > > Sean Cribbs <[email protected]> > > Software Engineer > > Basho Technologies, Inc. > > http://basho.com/ > > _______________________________________________ > > erlang-patches mailing list > > [email protected] > > http://erlang.org/mailman/listinfo/erlang-patches > > -- Sean Cribbs <[email protected]> Software Engineer Basho Technologies, Inc. http://basho.com/ _______________________________________________ erlang-patches mailing list [email protected] http://erlang.org/mailman/listinfo/erlang-patches