3

I am reading Programming Erlang, when I type these into erlang REPL:

perms([]) -> [[]];
perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].
* 1: syntax error before: '->'

I know I cannot define functions this way in shell, so I change it to:

2> Perms = fun([]) -> [[]];(L) -> [[H|T] || H <- L, T <- Perms(L--[H])] end.
* 1: variable 'Perms' is unbound

Does this mean I cannot define a recursive function within shell?

NeoWang
  • 17,361
  • 24
  • 78
  • 126
  • 2
    possible duplicate of [Defining erlang functions in the shell](http://stackoverflow.com/questions/2065990/defining-erlang-functions-in-the-shell) – Steve Vinoski Aug 26 '15 at 03:22
  • So there is no way to define recursive function in erlang shell, right? – NeoWang Aug 26 '15 at 03:37
  • 2
    `F = fun F([X|Xs]) -> [do_something(X) | F(Xs) ] end.` Then call it as `F(YourXList).` See [this question](http://stackoverflow.com/questions/867418/how-do-you-write-a-fun-thats-recursive-in-erlang). – Steve Vinoski Aug 26 '15 at 03:41
  • @SteveVinoski It's not a duplicate, because this is about recursive functions. – Adam Lindberg Aug 26 '15 at 08:08
  • @AdamLindberg did you see the link in my comment just above yours? It's exactly the same question. – Steve Vinoski Aug 26 '15 at 10:49
  • 2
    I should have voted to close because it duplicates [this question](http://stackoverflow.com/q/867418/409228), not the first one I chose, but unfortunately I can't change that now. But the point is that it took me mere seconds to search the site to find the answer, which is something the OP apparently didn't try to do. The answers to that question are more complete than the answer below. – Steve Vinoski Aug 26 '15 at 10:56
  • Ah, just saw the first one you linked, sorry. – Adam Lindberg Aug 26 '15 at 14:40
  • this question is better, it mentions the shell. So google brought me here. Go figure... – Sharas Aug 28 '16 at 18:08

1 Answers1

6

Since OTP 17.0 there are named funs:

  • Funs can now be given names

More details in README:

OTP-11537  Funs can now be a given a name. Thanks to to Richard O'Keefe
           for the idea (EEP37) and to Anthony Ramine for the
           implementation.
1> Perms = fun F([]) -> [[]];
               F(L) -> [[H|T] || H <- L, T <- F(L--[H])]
           end.    
#Fun<erl_eval.30.54118792>
2> Perms([a,b,c]).
[[a,b,c],[a,c,b],[b,a,c],[b,c,a],[c,a,b],[c,b,a]]

In older releases, you have to be a little bit more clever but once you get it:

1> Perms = fun(List) ->
               G = fun(_, []) -> [[]];
                      (F, L) -> [[H|T] || H <- L, T <- F(F, L--[H])]
                   end,
               G(G, List)
           end.    
#Fun<erl_eval.30.54118792>
2> Perms([a,b,c]).
[[a,b,c],[a,c,b],[b,a,c],[b,c,a],[c,a,b],[c,b,a]]
Hynek -Pichi- Vychodil
  • 26,174
  • 5
  • 52
  • 73