[erlang-questions] Give me some advice

Ulf Wiger ulf@REDACTED
Sun Feb 11 10:46:34 CET 2007


Den 2007-02-11 06:49:52 skrev LUKE <luke@REDACTED>:

>
> I am tring to do the excise about return a new tuple
> which is a copy of the tuple T where the Nth element
> of the tuple has been replaced by C.

... trying to write an erlang-based version of
the built-in function setelement(N, T, C)?

> Give me some advice on the following poor code. ie.
> tail recursion issue.....
>
> -module(element).
> -export([set2/3]).
>
> set2(N,T,C)->
>    list_to_tuple(set2(N,tuple_to_list(T),C,1)).
>
> set2(_,[],_,_)->[];
> set2(N,[H|T],C,Count)->
>    if     N==Count ->
>         [C|set2(N,T,C,Count+1)];
>      true->
>         [H|set2(N,T,C,Count+1)]
>    end.

(1) This is mainly a matter of taste, but
     I would order the arguments of set2
     differently
(2) When you get to the right position, you
     don't have to recurse any further, since
     you're guaranteed not to find another match.

set2([_|T], N, N, C) ->
    [C|T];
set2([H|T], Pos, N, C) when Pos < N ->
    [H|set2(T, Pos+1, N, C)].

(3) You don't need a clause for [], if you add
     a guard in set2/3:

set2(N,T,C)
   when is_tuple(T),
        is_integer(N),
        N > 0, N =< size(T) ->
   list_to_tuple(set2(tuple_to_list(T),1,N,C)).

(4) It's good form to use guards in the exported
     function to clearly indicate what the arguments
     are expected to be. Don't worry about this
     slowing down your code. It most likely won't,
     and in some cases, it can even speed things up,
     since the compiler is able to make some
     assumptions about the code that follows.

(5) In this case, I wouldn't worry about the
     function not being tail-recursive. Doing
     it this way makes it a lot easier to break
     out of the loop once you've reached N.
     Also, your tuple is not likely to have a
     huge number of elements to begin with.

BR,
Ulf W


-- 
Ulf Wiger




More information about the erlang-questions mailing list