<div dir="ltr"><br><br><div class="gmail_quote">On Tue, Oct 7, 2008 at 4:43 AM, Richard O'Keefe <span dir="ltr"><<a href="mailto:ok@cs.otago.ac.nz">ok@cs.otago.ac.nz</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="Ih2E3d"><br>
On 6 Oct 2008, at 3:11 am, Ciprian Dorin Craciun wrote:<br>
> About this subject, I would ask if isn't it better / easier /<br>
> clearer to add a special function name / keyword that would refer to<br>
> the function itself. This would also have a few advantages:<br>
<br>
</div>Please write an EEP about this.<br>
<div class="Ih2E3d"><br>
><br>
> * first it will solve the recursivity problem described above;<br>
<br>
</div>The particular example here seems to be one that would have been<br>
better addressed using existing debugging tools.<br>
<br>
Recursiveness is not a problem; it's *anonymous* recursive<br>
functions.<br>
<div class="Ih2E3d">><br>
> * (maybe) it could also improve efficiency (because you know<br>
> exactly what function you're calling, without any lookup); (this is<br>
> just an assumption, maybe inside the beam file the lookup does not<br>
> exist); (certainly it is more efficient than the proposed solution ---<br>
> sending the function as an argument;)<br>
<br>
</div>The best recommendation that has been given is to use a plain<br>
ordinary top level function. This is _already_ more efficient<br>
than anything based on funs could be (because it is _certain_<br>
not to need to unpack or repack outer variables), and it is<br>
certainly easier to get your head around (*some* variables<br>
in a function refer to outer variables, *some* do not,<br>
despite having the same name as outer variables).<br>
<div class="Ih2E3d"><br>
><br>
> * it will assist in refactoring --- changing a recursive function<br>
> name will have no impact on it's code;<br>
<br>
</div>Yes it will. Suppose we add something like<br>
<br>
Factorial = fun:Self (N) when N > 1 -> N*Self(N-1)<br>
; (N) when N >= 0 -> 1<br>
end,<br>
[Factorial(X) || X <- [3,1,4,1,5,9,2,6,5,3,5]]<br>
<br>
Changing "Self" in one place means it had better be changed<br>
in other places. For that matter, changing "Factorial" in<br>
one place means it has to be changed in other places.<br>
<div class="Ih2E3d"><br>
><br>
> * it could clearly mark the fact that the function calls itself.<br>
<br>
</div>It's hard to see how. The mere existence of a mark (such as :Self)<br>
is no guarantee that the body of the function *uses* it. And if<br>
you are thinking in terms of something like this_fun(), please,<br>
we've suffered enough from C already, and don't need any more like<br>
that. Consider<br>
<br>
F = fun:Outer (...) -><br>
... G = fun:Inner (...) -><br>
... Inner(X) ...<br>
... Outer(Y) ...<br>
end<br>
... Outer ... G ...<br>
end<br>
</blockquote><div><br>Is there any problem write this think this way?<br><br>F = begin<br> Outher = fun(OSelf, ...) -><br> ...<br> Inner = fun(ISelf, ....) -><br> ... ISelf(ISelf, X) ...<br>
... OSelf(OSelf, Y) ...<br> end,<br> ... OSelf(OSelf, ...) ... Inner(Inner, ...) ...<br> fun(Args) -> Outher(Outher, Args) end<br> end.<br><br>For Example factorial:<br><br>Fact = begin F = fun(_, 0) -> 1; (Self, N) -> Self(Self, N-1)*N end, fun(N) -> F(F, N) end end.<br>
<br>Some nontrivial example:<br><br>4> UpToGen = begin<br> Outher = fun(_OSelf, M, M) -> [];<br> (OSelf, Step, M) -><br> Inner = fun(_ISelf, N) when N>M -> [];<br>
(ISelf, N) -> [N | ISelf(ISelf, N+Step) ]<br> end,<br> [Inner(Inner, 0) | OSelf(OSelf, Step+1, M)]<br>
end,<br> fun(Max) -> Outher(Outher, 1, Max) end<br> end.<br>#Fun<erl_eval.6.13229925><br>5> UpToGen(10).<br>[[0,1,2,3,4,5,6,7,8,9,10],<br> [0,2,4,6,8,10],<br> [0,3,6,9],<br> [0,4,8],<br>
[0,5,10],<br> [0,6],<br> [0,7],<br> [0,8],<br> [0,9]]<br><br> <br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><br>
With a hook like this, the inner function can not only refer to<br>
itself, but also to the function that contains it. With a<br>
'this_fun()' approach, it can't.<br>
<div class="Ih2E3d"><br>
> As for disadvantages I really do not see any.<br>
<br>
</div>Try looking just a _little_ harder.<br>
<div class="Ih2E3d">><br>
<br>
> P.S.: I think this solution could be equally applied to all<br>
> languages (mainly Lisp like).<br>
<br>
</div>Most functional languages don't *need* it because they<br>
have 'letrec'. (In Lisp it's called 'labels'.)<br>
Even BCPL had letrec,<br>
let F(...) = E1<br>
and G(...) = E2<br>
and H(...) = E3<br>
was a letrec in which F G and H could refer to each other.<br>
<div><div></div><div class="Wj3C7c"><br>
<br>
><br>
> _______________________________________________<br>
> erlang-questions mailing list<br>
> <a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
> <a href="http://www.erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://www.erlang.org/mailman/listinfo/erlang-questions</a><br>
><br>
<br>
_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://www.erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://www.erlang.org/mailman/listinfo/erlang-questions</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>--Hynek (Pichi) Vychodil<br>
</div>