[erlang-questions] re cursive fun()

Hynek Vychodil <>
Tue Oct 7 13:32:37 CEST 2008


On Tue, Oct 7, 2008 at 4:43 AM, Richard O'Keefe <> wrote:

>
> 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
>

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]]



>
> 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
> > 
> > http://www.erlang.org/mailman/listinfo/erlang-questions
> >
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://www.erlang.org/mailman/listinfo/erlang-questions
>



-- 
--Hynek (Pichi) Vychodil
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20081007/a9fabcbf/attachment.html>


More information about the erlang-questions mailing list