[erlang-questions] lists:keyfind as an alternative to lists:keysearch

Robert Virding rvirding@REDACTED
Wed Jan 21 17:20:42 CET 2009


2009/1/21 Bjorn Gustavsson <bgustavsson@REDACTED>

> On Wed, Jan 21, 2009 at 4:40 PM, mats cronqvist <masse@REDACTED> wrote:
> > Bjorn Gustavsson <bgustavsson@REDACTED> writes:
> >
> >>>  seems i've written this function at least a thousand times;
> >>>
> >>> keyfind(Key,N,List) ->
> >>>  {value,{Key,Val} = lists:keysearch(Key,N,List),
> >>>  Val.
> >>
> >> This version only works for tuples of size 2.
> >
> >  it was meant as an example, not an implementation proposal. i didn't
> >  balance the braces either :<
>
> Yes, but if the tuple has more than two elements, how do you know
> which field the caller is interested in? Do you assume that it always
> the element after the key? What is the caller is interested in several
> fields of the tuple?


I am sorry, but I think that returning something "half-tagged" like
ValueTuple | false (/not_found/error/...) is horrendous and should be
avoided like the plague. I think the Right Way is to tag both return values
as is done with keyserach, but I agree that using {value,Val} | false is
bad. If we are going to "fix" it then I would suggest two functions like in
dict, find/2 to find a value if it exists and one which assumes it exists
and errors otherwise. I also agree that returning 'error' is not the best as
it may very well not be an error, with 20/20 hindsight I would prefer a
maybe(value) so:

keyfind(Key, N, List) -> {yes,Value} | no.
keyfetch(Key, N, List) -> Value (or exception)

If you want to be more consistent with existing modules like dict then use
{ok,Value} | error instead.

Just because lisp has a convention of returning value or nil, this is not
something we should really copy as they also have the convention that (car
()) => () and (cdr ()) => () which are used together with functions
returning nil for not found. In erlang terms that would mean hd([]) => [],
tl([]) => [] and [] matches [[]].

Now this would help make LFE more lisp-like but I don't advocate it.

If you are going to tag return values then you must tag them all, otherwise
you will be bitten. And the extra cost *is* neglible.

Robert
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20090121/44bfba74/attachment.htm>


More information about the erlang-questions mailing list