Reputation: 59
Here is the code I have found while reading Joe's Erlang book. But I am unable to understand.
odds_and_evens_acc(L) ->
odds_and_evens_acc(L, [], []).
odds_and_evens_acc([H|T], Odds, Evens) ->
case (H rem 2) of
1 -> odds_and_evens_acc(T, [H|Odds], Evens);
0 -> odds_and_evens_acc(T, Odds, [H|Evens])
end;
odds_and_evens_acc([], Odds, Evens) ->
{Odds, Evens}.
Please help me on this.
Upvotes: 2
Views: 1473
Reputation: 14042
When you try to understand some piece of code you can use the debugger - especially with code like this which is very small.
Write a file named test1.erl:
-module (test1).
-compile(export_all).
odds_and_evens_acc(L) ->
odds_and_evens_acc(L, [], []).
odds_and_evens_acc([H|T], Odds, Evens) ->
case (H rem 2) of
1 -> odds_and_evens_acc(T, [H|Odds], Evens);
0 -> odds_and_evens_acc(T, Odds, [H|Evens])
end;
odds_and_evens_acc([], Odds, Evens) ->
{Odds, Evens}.
in the same directory start the erlang shell : erl or werl.
1> %% compile the code for debug
1> c(test1,[debug_info]).
{ok,test1}
2> %% create a list of integer for test
2> L=lists:seq(1,8).
[1,2,3,4,5,6,7,8]
3> %% start the debugger
3> debugger:start().
{ok,<0.38.0>}
4> %% in the menu Module, select interpret... and then the file test1.erl
4> %% then check the box Auto attach on break
4> %% double click on module name test1
4> %% put a break point on the first line of code
4> %% start the function
4> test1:odds_and_evens_acc(L).
you should arrive in this window:
then you can play with the step button and look into the value panel to see the evolution of the program. It is possible to see the execution trace by opening the trace panel: Options/Trace Window/Trace Area
Upvotes: 2
Reputation: 2040
%% There are two functions - odds_and_evens_acc/1 and odds_and_evens_acc/3
%% First function. It takes a list of integers and splits it on two lists -
%% odds and evens.
%% The function calls odds_and_evens_acc/3 with three arguments -
%% given List of integers and two empty lists which are
%% accumulators for odds and evens. Actually they are just initial values
%% for lists, where we store odds and evens.
odds_and_evens_acc(L) ->
odds_and_evens_acc(L, [], []).
%% Second function. It takes 3 arguments - list of integers and initial lists for
%% storing odds and evens. The functions works recursively. On each step it
%% takes first element of list, test if it is odd or even, add that elemnt
%% to appropriate list. Then function calls itself
%% with tail (first element deleted) of the list and lists of o/e
%% (one with one new element, another is the same as it was passed).
%% When the list is empty function finishes.
%%
%% Function has two clauses.
%% First clause - the list is not empty - so we should proceed.
%% Function splits it on first element (head)
%% and reminder (tail) with pattern matching ([H|T]).
odds_and_evens_acc([H|T], Odds, Evens) ->
%% Test head if it is odd or even.
%% In both cases the function call itself again with the tail of the list and
%% accumulators (note: head is added in appropriate accumulator).
case (H rem 2) of
1 -> odds_and_evens_acc(T, [H|Odds], Evens);
0 -> odds_and_evens_acc(T, Odds, [H|Evens])
end;
%% Second clause. The list is empty.
%% Function finishes returning tuple with two accumulators
%% which are two lists, the first
%% contains all odd elemnts of the initial list and the second - all evens.
odds_and_evens_acc([], Odds, Evens) ->
{Odds, Evens}.
Upvotes: 4