[erlang-questions] Calling a Function with Same argument twice
Ulf Wiger
ulf.wiger@REDACTED
Wed Oct 14 15:31:25 CEST 2009
sapan shah wrote:
> Hi,
>
> see the code below.
> ...
>
> We call temp:start(1), the output is 4. The output should have been 1.
No, 4 is right.
> Here, when start(1) is called, it intern calls
> {element(1, test(1,1), element(2, test(1,1)}
test(2,2) results in two calls to test(1,1),
which each result in two calls to test(0,0), each
incrementing the 'test' object by 1.
>
> The first call of test(1,1) should recursively evaluate test(1,1) while the
> second call should already use the value returned by the first call.. Is
> this a right thinking???
I assume you're thinking that it would work like:
test(0,0) ->
put(test, get(test) +1),
{0,0};
test(X,Y) ->
Z = test(X-1, Y-1),
{element(1, Z), element(2, Z)}.
but here you make only one call and reuse the result.
If the test/2 function werer purely functional (i.e. no side-
effects), the two would be equivalent, but here you use get and
put, so it really makes a difference how many times you explicitly
call the function.
Btw, since test/2 returns a two-tuple, the above is of course
equivalent to
test(0,0) ->
put(test, get(test) +1),
{0,0};
test(X,Y) ->
test(X-1, Y-1).
...which is almost equivalent to
test(X,X) when is_integer(X) -> put(test, get(test) +1), {0,0}.
(It differs only slightly in how it fails on erroneous input).
Think twice before using get/put. Also, why wrap the return values
inside a 1-tuple? Remove the tuple, and you can remove some of the
calls to element/2.
But of course it was a contrived example, so I assume the real
problem you're trying to solve is somewhat different?
BR,
Ulf W
--
Ulf Wiger
CTO, Erlang Training & Consulting Ltd
http://www.erlang-consulting.com
More information about the erlang-questions
mailing list