Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursion with closures in Groovy 2.1.9

I am unable to call recursive closures in Groovy 2.1.9

def facRec = {long n->
    return n>1 ? n * facRec(n - 1) : 1
}

I'm getting a TypeMissmatch

like image 884
Philipp Sander Avatar asked Nov 04 '13 09:11

Philipp Sander


People also ask

What is -> in Groovy?

It is used to separate where you declare bindings for your closure from the actual code, eg: def myClosure = { x, y -> x + y } the part before -> declares that the closure has two arguments named x and y while the second part is the code of the closure.

Can we use continue in recursion?

continue has nothing to do with the recursive call; its effect is to skip the rest of the contents of the while loop and go straight back to in. hasNext() .

What is a closure gradle?

A closure is a function bound to (or executed against) some object instances, which can be one of these three things: this, owner, and delegate. this: the instance of the enclosing class. owner: same as this, or the enclosing closure if exists. delegate: same as owner, but can be changed.


1 Answers

When the closure is being defined, it has no idea of the variable facRec as it has not yet been defined...

You can do:

def facRec
facRec = {long n->
    return n>1 ? n * facRec(n - 1) : 1
}

To get around this, or you can wrap the inner into another closure and call the owner of that inner closure (though I would tend to do the above as it is easier to read):

def facRec = {long n->
    { -> n > 1 ? n * owner.call( n - 1 ) : 1 }()
}

It should be noted that both of these will fail for big values of n as you will overflow the stack

You can use trampoline to get round this:

def facRec
facRec = { n, count = 1G ->
    n > 1 ? facRec.trampoline( n - 1, count * n ) : count
}.trampoline()
like image 90
tim_yates Avatar answered Oct 11 '22 10:10

tim_yates