Groovy for Domain-specific Languages - Second Edition

(nextflipdebug2) #1

Groovy Closures


[ 110 ]

factorial(6) == 1*2*3*4*5*6
when: "we use value that overflows the stack for recursion"
factorial(10000)
then: "it works"
notThrown StackOverflowError

Closure memoization


The final closure feature we will look at is another useful addition from Groovy 1.8.
Memoization allows the return values for closure invocations to be cached. This is
useful for potentially expensive or long running closure calls, as long as the outcome
of the closure call is predictable and does not have other side effects that impact the
system state:


given: "a simple closure"
def callCount = 0
def memoized = { name ->
callCount++
"Hello, $name $callCount"
}
and: "we memoize the closure"
memoized = memoized.memoize()
when: "we make subsequent calls with the same parameter"
def firstResult = memoized "Dolly"
def secondResult = memoized "Dolly"
def thirdResult = memoized "World"
then:
firstResult == secondResult
firstResult == "Hello, Dolly 1"
secondResult != "Hello, Dolly 2"
thirdResult == "Hello, World 2"

In the preceding code, we see that the first call to memoized is cached and the closure
is not actually invoked again until we pass a different parameter value. Memoization
can be combined usefully with a trampolined closure and will cut down the potential
for repeated expensive processing:


given: "a factorial algorithm using trampoline()"
def trampolined
trampolined = { int n, BigDecimal accumulator = 1 ->
if (n < 2)
accumulator
else

http://www.ebook3000.com
Free download pdf