[erlang-questions] Code critique please

Zoltan Lajos Kis <>
Wed Dec 2 18:25:13 CET 2009


Sam Bobroff wrote:
> Zoltan Lajos Kis wrote:
>> Sam Bobroff wrote:
>>> Jarrod Roberson wrote:
>>>> is there anything that I can do to improve this code? Are the 
>>>> nested case of
>>>> the best way to do that? It was the only thing I could get to work.
>>>>   
>>> Hi Jarrod,
>>>
>>> I have another suggestion you might find interesting. I would like 
>>> to factor out the recursion in the "is_subscribed" function because 
>>> I think it's generally good to use comprehensions or folds if you 
>>> can, instead of creating your own recursion. Unfortunately I can't 
>>> see a way to do this trivially, so:
>>>
>>> Given this code:
>>>> % test to see if a dns_rr.domain is subscribed to
>>>> is_subscribed(_,[]) -> false;
>>>> is_subscribed(Dom,[S|Rest]) ->
>>>>     case lists:suffix(S,Dom) of
>>>>         true ->
>>>>             {ok,S};
>>>>         false ->
>>>>             is_subscribed(Dom,Rest)
>>>>     end.
>>> I would first write a function like this:
>>>
>>> %% first(Pred, List): Return either false or {true, Elem} where Elem 
>>> is the first element of List for which Pred(Elem) returns true.
>>> %% Pred must take one argument and return true or false.
>>> first(Pred, []) ->
>>>    false;
>>> first(Pred, [X | Xs]) ->
>>>    case Pred(X) of
>>>        true ->
>>>            {true, X};
>>>        false ->
>>>            first(Pred, Xs)
>>>    end.
>>>
>>> Then I could write is_subscribed like this:
>>>
>>> is_subscribed(Dom, SS) ->
>>>    first(fun(S) -> lists:suffix(S, Dom) end, SS).
>>>
>>> This makes the "is_subscribed" function really easy to understand 
>>> and provides "first" as a useful tool.
>>>
>>> To be honest I was quite surprised that it wasn't in the "lists" 
>>> module... maybe there is one somewhere I couldn't find.
>>>
>>> Sam.
>>>
>>>
>>>
>>> ________________________________________________________________
>>> erlang-questions mailing list. See http://www.erlang.org/faq.html
>>> erlang-questions (at) erlang.org
>>>
>> It is there inversed: lists:dropwhile/2
>>
>> is_subscribed(Dom, SS) ->
>>  case lists:dropwhile(fun(S) -> not lists:suffix(S, Dom) end, SS) of
>>    [X|_] -> {true, X};
>>    [] -> false
>>  end
>>
>> Regards,
>> Zoltan.
> I actually looked at dropwhile/2, but I didn't think it was a good 
> solution because:
>
> * It might create a copy of the tail of the list, which you don't need 
> (I don't know enough about Erlang to know if this happens or not).
> * The whole point of factoring is_subscribed/2 was to make it clearer 
> and I don't think it achieves that.
>
> So thanks for pointing that out but I still like the idea of a first/2 
> function :-)
>
> Cheers,
> Sam.
The list won't be copied, the function will only return a "pointer" into 
the middle of the list as far as I know.
I think your refactoring is merely putting stuff behind the scenes. Your 
is_subscribed only looks "clearer" because you purposefully made your 
first function return values in a way that no additional handling is 
required in is_subscribed. In other functions you will have to do that. 
Same with dropwhile.

Regards,
Zoltan.


More information about the erlang-questions mailing list