|
hello
I have this going on FunVar = fun() -> ... FunVar() end. so the compiler is complaining that FunVar is unbound at the place where its being used inside fun(); this makes sense, however Im wondering how to make this into a recursive function since there's no name to reference the function with. thanks |
|
I'm assuming that you want to do this in the shell, otherwise it would be easier just to write the function in the usual way, e.g.
myfun() -> blah, blah, myfun(). To create a fun that calls itself, you must realize that you are creating an unnamed function. When you write fun(X) -> X * 2 end. this is compiled to a Fun data type, e.g. #Fun<erl_eval.6.13229925>. Since the function does not have a name, it cannot refer to itself. When you write FunVar = fun(X) -> X * 2 end, the function is bound to the variable FunVar. Because the binding takes place *after* the fun is created, the fun cannot refer to the variable FunVar within its definition. So how is it done? You have to pass the variable to the function so that it "knows" what to call: FunVar = fun(MySelf) -> ... MySelf(). Then when you call it, you call FunVar(FunVar). Looks strange but it works. Example: Writing a simple generate and fold function using only a fun() variable. 9> GenFold = fun(0, Acc, _) -> Acc; (X, Acc, Fun) -> Fun(X - 1, [X|Acc], Fun) end. #Fun<erl_eval.18.105910772> 10> GenFold(10, [], GenFold). [1,2,3,4,5,6,7,8,9,10] 11> Or a for loop: 22> For = fun(Max, Max, ExecFun, _) -> ok; (N, Max, ExecFun, Next) -> ExecFun(N), Next(N + 1, Max, ExecFun, Next) end. #Fun<erl_eval.4.105156089> 23> For(0,10,fun(I) -> io:format("~B ", [I]) end, For). 0 1 2 3 4 5 6 7 8 9 ok 24> Stuff like this is described in Joe Armstrong's Erlang book. Hope this helps. On Sat, Oct 4, 2008 at 11:19 PM, deepblue_other <[hidden email]> wrote:
_______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
|
In reply to this post by deepblue_other
deepblue_other wrote:
> hello > I have this going on > > FunVar = > fun() -> > ... > FunVar() > end. > > so the compiler is complaining that FunVar is unbound at the place where its > being used inside fun(); this makes sense, however Im wondering how to make > this into a recursive function since there's no name to reference the > function with. You have to make it keep "itself" around as an additional parameter, so that you can first create it and then hand it the self-reference: FunVar = fun(Myself) -> ... Myself(Myself) end then call it like this: FunVar(FunVar). If you want the result to be a function of arity 0, as in your example, then replace the last line with FinalFunVar = fun () -> FunVar(FunVar) end /Richard -- "Having users is like optimization: the wise course is to delay it." -- Paul Graham _______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
|
In reply to this post by deepblue_other
> FunVar = > fun() -> > ... > FunVar() > end. > > so the compiler is complaining that FunVar is unbound at the place where its > being used inside fun(); this makes sense, however Im wondering how to make > this into a recursive function since there's no name to reference the > function with. Maybe have the fun call a real (recursive) function. eg. F(A) -> ... F(B). Caller(Data) -> ... FunVar = fun(A) -> F(A) end, ... foo:use_fun(FunVar, Data). -- Rich Make the switch to the world's best email. Get Yahoo!7 Mail! http://au.yahoo.com/y7mail _______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
|
In reply to this post by Richard Carlsson-2
On Sun, Oct 5, 2008 at 12:30 PM, Richard Carlsson <[hidden email]> wrote:
> deepblue_other wrote: >> hello >> I have this going on >> >> FunVar = >> fun() -> >> ... >> FunVar() >> end. >> >> so the compiler is complaining that FunVar is unbound at the place where its >> being used inside fun(); this makes sense, however Im wondering how to make >> this into a recursive function since there's no name to reference the >> function with. > > You have to make it keep "itself" around as an additional parameter, > so that you can first create it and then hand it the self-reference: > > FunVar = > fun(Myself) -> > ... > Myself(Myself) > end > > then call it like this: > > FunVar(FunVar). > > If you want the result to be a function of arity 0, > as in your example, then replace the last line with > > FinalFunVar = fun () -> FunVar(FunVar) end > > /Richard > > -- > "Having users is like optimization: the wise course is to delay it." > -- Paul Graham About this subject, I would ask if isn't it better / easier / clearer to add a special function name / keyword that would refer to the function itself. This would also have a few advantages: * first it will solve the recursivity problem described above; * (maybe) it could also improve efficiency (because you know exactly what function you're calling, without any lookup); (this is just an assumption, maybe inside the beam file the lookup does not exist); (certainly it is more efficient than the proposed solution --- sending the function as an argument;) * it will assist in refactoring --- changing a recursive function name will have no impact on it's code; * it could clearly mark the fact that the function calls itself. As for disadvantages I really do not see any. (Except of having a new keyword / special function.) So any comments? Ciprian. P.S.: I think this solution could be equally applied to all languages (mainly Lisp like). _______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
|
In reply to this post by Edwin Fine
Just noticed a mistake.
FunVar = fun(MySelf) -> ... MySelf(). should have been FunVar = fun(MySelf) -> ... MySelf(MySelf). On Sun, Oct 5, 2008 at 5:13 AM, Edwin Fine <[hidden email]> wrote:
_______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
|
In reply to this post by Edwin Fine
no shell is not the reason, I need a function that will only be called from within another function and I dont want to "pollute" the "module wide" space with another function, so Im putting in a nested one... I would prefer to declare a regular function, but as far as I know there are no nested functions in Erlang (regular named functions). what you have described makes perfect sense thanks |
|
In reply to this post by deepblue_other
Otherwise, than passing the Fun as argument to itself, one can implement recursive functions, using code, like this:
fact(0) -> 1; fact(N) when N>0 -> {M,F,_A} = element(2,process_info(self(),current_function)), N * {M,F}(N-1). But this doesn't work for funs, if there are was something like: Fact = fun(0) -> 1; (N) when N>0 -> Fun = element(2,process_info(self(),current_fun)), N * Fun(N-1). Zvi
|
|
so definitely no named nested functions?
|
|
You may do a trick like this:
1> Fact = fun(0) -> 1; (N) -> Fun=get(fact), N*Fun(N-1) end. #Fun<erl_eval.6.13229925> 2> put(fact,Fact). undefined 3> Fact(5). 120 Regards, Alpar On Sun, 2008-10-05 at 09:07 -0700, deepblue_other wrote: > so definitely no named nested functions? > > Zvi wrote: > > > > Otherwise, than passing the Fun as argument to itself, one can implement > > recursive functions, using code, like this: > > > > fact(0) -> 1; > > fact(N) when N>0 -> > > {M,F,_A} = element(2,process_info(self(),current_function)), > > N * {M,F}(N-1). > > > > But this doesn't work for funs, if there are was something like: > > > > Fact = fun(0) -> 1; > > (N) when N>0 -> > > Fun = element(2,process_info(self(),current_fun)), > > N * Fun(N-1). > > > > Zvi > > > > > > deepblue_other wrote: > >> > >> hello > >> I have this going on > >> > >> FunVar = > >> fun() -> > >> ... > >> FunVar() > >> end. > >> > >> so the compiler is complaining that FunVar is unbound at the place where > >> its being used inside fun(); this makes sense, however Im wondering how > >> to make this into a recursive function since there's no name to reference > >> the function with. > >> > >> thanks > >> > > > > > _______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
|
In reply to this post by deepblue_other
On 5 Oct 2008, at 4:19 pm, deepblue_other wrote:
> I have this going on > > FunVar = > fun() -> > ... > FunVar() > end. > Shouldn't this go in a FAQ somewhere? Maybe it belongs in the reference manual. The quick answer is that if you need a recursive function, why not write a recursive function in the usual way? There's something particularly nasty about this example. One normally proves (or at any rate argues with vigourously waving hands for) the termination of a recursive function by showing that some non-negative measure of its arguments strictly decreases on each recursive call, but this function has no arguments. I think we need to see more of it. The long answer is that you can always do Rec = fun (Self, Args) -> .... Self(Self, Args') end, Foo = fun (Args) -> Rec(Rec, Args) end, It's possible, but you are working against the grain of the language, and there is most likely a better way to achieve your goals. _______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
|
the example I gave was not suppose to be a practical one, I just wanted to ask how to recursively call a anonymous function...
|
|
In reply to this post by Edwin Fine
BTW, this question has apparently come up before (multiple times). The key google phrase is "Y combinator":
Steven On Oct 5, 2008, at 2:13 AM, Edwin Fine wrote:
_______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
|
In reply to this post by deepblue_other
On 6 Oct 2008, at 4:12 am, deepblue_other wrote: > no shell is not the reason, I need a function that will only be > called from > within another function and I dont want to "pollute" the "module > wide" space > with another function, so Im putting in a nested one... This seems an extraordinarily weak reason. Putting local functions into a namespace that is designed for local functions is hardly polluting it! Note that if the 'inner' function is needed in two clauses of the same function, it cannot be inside both, so it would have to be at top level anyway. Somehow, I find myself writing nested functions all the time in Haskell, but never wanting to in Erlang. Of course, many functional language compilers implement nested functions by moving them out to top level anyway... It's a fundamental property of Erlang scope rules that there is no letrec. _______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
|
In reply to this post by Ciprian Dorin Craciun
On 6 Oct 2008, at 3:11 am, Ciprian Dorin Craciun wrote: > About this subject, I would ask if isn't it better / easier / > clearer to add a special function name / keyword that would refer to > the function itself. This would also have a few advantages: Please write an EEP about this. > > * first it will solve the recursivity problem described above; The particular example here seems to be one that would have been better addressed using existing debugging tools. Recursiveness is not a problem; it's *anonymous* recursive functions. > > * (maybe) it could also improve efficiency (because you know > exactly what function you're calling, without any lookup); (this is > just an assumption, maybe inside the beam file the lookup does not > exist); (certainly it is more efficient than the proposed solution --- > sending the function as an argument;) The best recommendation that has been given is to use a plain ordinary top level function. This is _already_ more efficient than anything based on funs could be (because it is _certain_ not to need to unpack or repack outer variables), and it is certainly easier to get your head around (*some* variables in a function refer to outer variables, *some* do not, despite having the same name as outer variables). > > * it will assist in refactoring --- changing a recursive function > name will have no impact on it's code; Yes it will. Suppose we add something like Factorial = fun:Self (N) when N > 1 -> N*Self(N-1) ; (N) when N >= 0 -> 1 end, [Factorial(X) || X <- [3,1,4,1,5,9,2,6,5,3,5]] Changing "Self" in one place means it had better be changed in other places. For that matter, changing "Factorial" in one place means it has to be changed in other places. > > * it could clearly mark the fact that the function calls itself. It's hard to see how. The mere existence of a mark (such as :Self) is no guarantee that the body of the function *uses* it. And if you are thinking in terms of something like this_fun(), please, we've suffered enough from C already, and don't need any more like that. Consider F = fun:Outer (...) -> ... G = fun:Inner (...) -> ... Inner(X) ... ... Outer(Y) ... end ... Outer ... G ... end With a hook like this, the inner function can not only refer to itself, but also to the function that contains it. With a 'this_fun()' approach, it can't. > As for disadvantages I really do not see any. Try looking just a _little_ harder. > > P.S.: I think this solution could be equally applied to all > languages (mainly Lisp like). Most functional languages don't *need* it because they have 'letrec'. (In Lisp it's called 'labels'.) Even BCPL had letrec, let F(...) = E1 and G(...) = E2 and H(...) = E3 was a letrec in which F G and H could refer to each other. > > _______________________________________________ > erlang-questions mailing list > [hidden email] > http://www.erlang.org/mailman/listinfo/erlang-questions > _______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
|
On Tue, Oct 7, 2008 at 4:43 AM, Richard O'Keefe <[hidden email]> wrote:
Is there any problem write this think this way? F = begin Outher = fun(OSelf, ...) -> ... Inner = fun(ISelf, ....) -> ... ISelf(ISelf, X) ... ... OSelf(OSelf, Y) ... end, ... OSelf(OSelf, ...) ... Inner(Inner, ...) ... fun(Args) -> Outher(Outher, Args) end end. For Example factorial: Fact = begin F = fun(_, 0) -> 1; (Self, N) -> Self(Self, N-1)*N end, fun(N) -> F(F, N) end end. Some nontrivial example: 4> UpToGen = begin Outher = fun(_OSelf, M, M) -> []; (OSelf, Step, M) -> Inner = fun(_ISelf, N) when N>M -> []; (ISelf, N) -> [N | ISelf(ISelf, N+Step) ] end, [Inner(Inner, 0) | OSelf(OSelf, Step+1, M)] end, fun(Max) -> Outher(Outher, 1, Max) end end. #Fun<erl_eval.6.13229925> 5> UpToGen(10). [[0,1,2,3,4,5,6,7,8,9,10], [0,2,4,6,8,10], [0,3,6,9], [0,4,8], [0,5,10], [0,6], [0,7], [0,8], [0,9]]
-- --Hynek (Pichi) Vychodil _______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
|
On Tuesday, October 07, 2008, Hynek Vychodil wrote:
> Is there any problem write this think this way? . . . > For Example factorial: > > Fact = begin F = fun(_, 0) -> 1; (Self, N) -> Self(Self, N-1)*N end, fun(N) -> F(F, N) end end.
My only objection is that it pollutes the shell variable space with the extra function F. How about:
Fact = fun(N) -> F = fun(_, 0) -> 1; (Self, N) -> Self(Self, N-1)*N end, F(F, N) end.
Cheers,
David _______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
|
Yes of course, it can be done. There is little difference when closure is made.
this second example can be rewritten (and simplified) in same manner: UpToGen = fun(Max) -> Outer = fun(_OSelf, Max) -> []; (OSelf, Step) -> Inner = fun(_ISelf, N) when N>Max -> []; (ISelf, N) -> [N | ISelf(ISelf, N+Step) ] end, [Inner(Inner, 0) | OSelf(OSelf, Step+1)] end, Outer(Outer, 1) end. On Tue, Oct 7, 2008 at 4:29 PM, David Mercer <[hidden email]> wrote:
-- --Hynek (Pichi) Vychodil _______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
|
It seems like there are two separate threads here: one is about defining recursive functions in the shell; and the other is about defining local (recursive) functions in a module.
The first case has been reasonably covered in how you create a fun with a reference to itself so it can call itself recursively. In the second case I must agree with Richard, there is no *need* to have local (to a function) functions, you can just use normal top-level functions. They *are * more efficient than funs. I have found, however, that I sometimes use funs as local functions when I want to stress that these are local functions. Especially after a bout of LFE hacking which has them. However, if it was really desired it would be possible to add them, of course you would need both the recursive and non-recursive options. It would be a bit of a contrived expression as it would not, *could not*, return anything sensible. I would not like to add a scoping let type construction as we don't have having scoping anywhere else. Well except in funs and comprehensions where the scoping is a bit off actually. The visibility rules for the defined functions would be a bit hairy, very hairy really, but the best would be to make them the same as for variables, which are very hairy. I have no intention of adding an EEP! I don't like the idea of Self. A rather humourous note is local functions in Core erlang. In Core yo have local functions, but only the mutually recursive type. These were originally added to implement comprehensions so only the recursive kind were needed. A solution would be do what I used to threaten Bjarne with: do an E2 and get it right. What ever right is. Robert _______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
|
On Tue, Oct 7, 2008 at 10:09 PM, Robert Virding <[hidden email]> wrote:
You can use same tricks in module as in shell (if you are pervert a little ;-).
I agree, there is always way how to do refactoring to local recursive functions and make up funs from those. (There should not be difference in performance, it is Erlang fault if is. But there is long way to this goal, for example hot spot compiler and such thinks.) I strongly agree with following, especially with EPP and Self thinks.
-- --Hynek (Pichi) Vychodil _______________________________________________ erlang-questions mailing list [hidden email] http://www.erlang.org/mailman/listinfo/erlang-questions |
| Powered by Nabble | Edit this page |
