#888 recursive anonimous function?

jsendra Mon 28 Dec 2009

Syntax does not support named local functions

class X {
   Void main() {}
   Void f() {
      Void g() {}
   }
}

compiler complains

x.fan(4,13): Expected end of statement: semicolon, newline, or end of block; not '('

We can solve it with anonymous local functions (clousures)

class X {
   Void main() {}
   Void f() {
      g := |,| {}
   }
}

The question is: can g be recursive?

class X {
   Void main() {}
   Void f() {
      g := |,| {g()}
   }
}

compiler complains again

x.fan(4,13): Unknown method 'x_0::X.g'

how to invoke an anonymous function from inside? is there a special syntax for it?

brian Mon 28 Dec 2009

You can't do that today. Do any other languages allow that with closures?

Although I would definitely recommend making a recursive function a first class method b/c it will be far more efficient in the VM.

helium Mon 28 Dec 2009

Do any other languages allow that with closures?

JavaScript, D, Scala, Haskell, OCaml, ...

There are lots of languages with named local functions which are closures and allow recursion.

In some languages like C# it's not as strait forward.

void f()
{
    Action g = null;
    g = () => { g(); };
}

You have to do it in two steps, because otherwise the compiler complains about using a non initialized variable g. That might work in Fantom, too.

Without naming the anonymous function you'd have to use the Y combinator.

KevinKelley Mon 28 Dec 2009

I ran into similar before... changing above example to pre-declare the closure var:

class X {
  Void main() { f() }

  Void f() {
    |,|? g          
    g = |,| {g()}    
    g()
  }
}

works.

Of course this example gives infinite recursion, stack overflow... :-)

tactics Mon 28 Dec 2009

Clojure has a special form similar to this called recur

I'm not really sure this construct is necessary in Fantom. It's fascinating from a theoretical standpoint that factorial = fix (\f \n -> case n of 0 -> 1; otherwise -> n * (f (n-1) f)), but I can't imagine any practical use. Recursion is confusing enough for most people even with named functions.

KevinKelley Tue 29 Dec 2009

It's cool, but those Lisp-y recursive definitions really don't work out unless you've got some tail-call optimization thing going on; all the cute examples blow up the stack so fast. I've been playing with Stutter - a really tiny Lisp-like interpreter; I re-wrote it in Fantom to use it as a simple example of a DSL.

It's fun and it works, but you find out pretty quick how deep the stack is!

tactics Tue 29 Dec 2009

It's fun and it works, but you find out pretty quick how deep the stack is!

The size of a stack frame * (the number of iterations - 1) :)

Login or Signup to reply.