|
|
| Author |
Message |
< Erlang ~ can anyone explain how this code work? |
| porkai |
Posted: Sat Jul 18, 2009 9:47 pm |
|
|
|
Joined: 18 Jul 2009
Posts: 1
|
I am reading Joe Armstrong thesis and found the following code. I am very new to Erlang and have huge difficulty in adusting to it (used to C#/Java those type of lang but not funcitonal) .. so any help will be very helpful:
This is his version of factorial:
Fact=fun(X)-> G=fun(0,F) ->1;
(N,F)->N*F(N-1,F)
end,
G(X,G)
end.
then a Fact(4) shall evaluate to 24 .
But i ahve trouble tracing it. and diassemble the technique piece by piece |
|
|
| Back to top |
|
| Mazen |
Posted: Sun Jul 19, 2009 10:33 am |
|
|
|
User
Joined: 20 Jul 2006
Posts: 164
Location: London
|
Code:
Fact =
fun(X) ->
G = fun(0, F) ->
1;
(N, F) ->
N * F(N-1, F)
end,
G(X, G)
end.
Fact is a fun which takes 1 integer argument, this fun then defines another fun G which takes two arguments, one integer and a fun. Then this fun (the G fun) is called with the value passed to Fact (the integer X) and itself (the G fun). if the integer is 0, then 1 is returned to who ever called the G fun. If the integer is other then zero then the value of X is multiplied with the result of F(). Now F is what ever fun was passed on to G which in this case is itself G thus it is recursive. G is defined once, and used inside itself.
Another example of this code would look something like:
Code:
fact(X) ->
g(X).
g(0) ->
1;
g(N) ->
N * g(N-1).
Joe's way of writing it with funs is probably to illustrate that it can be done and give a "wow" or "coolness" factor to it. not exactly production code imho, but nevertheless has a nice twist to it  |
|
|
| Back to top |
|
| baryluk |
Posted: Tue Aug 18, 2009 10:02 am |
|
|
|
User
Joined: 05 Aug 2009
Posts: 48
|
There is even something called y-combinator, it is an fixed-point operator for recursive function:
Code:
y(M) ->
G = fun (F) -> M(fun(A) -> (F(F))(A) end) end,
G(G).
Then you can just use it like this:
Code:
Fact = y(fun (Me) ->
fun(0) -> 1;
(N) -> N * Me(N-1)
end
end).
And use it:
It takes few days to understand it completly.  |
|
|
| Back to top |
|
| jmontelius |
Posted: Sat Oct 03, 2009 8:39 am |
|
|
|
User
Joined: 07 Mar 2009
Posts: 29
|
To understand what we are trying to do it could be good to understand what we want to do but can not. This is how it could have been:
Code:
Fac = fun(0) ->
1;
(N) ->
N * Fac(N-1)
end.
The scoping rules in Erlang does not allow us to use the Fac variable inside the expression. Many other functional and logical programming langues have no problem with this but it is not allowed in Erlang.
So the trick that is applied is to make the function take an extra argument and pass the function as an argument when we call it. Joe's code is thus a clever work-around to be able to do something that is not there at first glance.
You might wonder why the scoping ruleas are not changed. We'll that would also allow us to do things like
This does of course looks fun and any Prolog programmer could tell you that it's quite useful. If you ask the people that implement the garbage collector and message passing rutines they would probably throw bricks on you if you proposed something like this. |
|
|
| Back to top |
|
|
|
All times are GMT
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|
|