Skip to content
Gregory Morrison edited this page Feb 5, 2023 · 3 revisions

Groovy, introduced in 2003, is a dynamic language for the JVM. It's a superset of Java with Ruby-like dynamic elements added. This gives a programmer the comfort of plain old Java while allowing them to adopt dynamic elements as they grow more comfortable. This version illustrates the traditional imperative Euler1 algorithm, with some dynamic declarations, and with the OOP omitted:

// Euler1 in Groovy

BigInteger euler1 (Integer n) {
    retval = 0
    for (i=0; i<n; i++)
        if (i%3==0 || i%5==0)
            retval += i
    return retval
}

println "${ euler1(1000) }"

The traditional and dynamic subsets of Groovy functionality can be quite disjoint sets - a Java programmer would not even recognize anything in this next example:

// Euler1 in Groovy

def euler1(n) { (0..n).findAll{x -> x%3==0 || x%5==0}.sum() }

print euler1(999) + '\n'

This dual nature of Groovy - that it can't decide if it is Java or Ruby - confounds me. The language has the feel of, well, Windows 8, with its dual interfaces written to support both servers and tablets. It has a design smell. Still, Groovy is actually quite fun, and this code took me no time at all to write. And it is very elegantly concise code.

Now let's try a tail-recursive version:

// DOES NOT WORK - JVM doesn't support tail recursion

def euler1
euler1 = { Integer n, BigInteger acc=1 ->
    if (n == 1) return acc

    if (n%3==0 || n%5==0)
        return euler1(n-1, acc+n)
    else
        return euler1(n-1, acc)
}

print euler1(999) + '\n'

D'Oh! Groovy, Y U No Work?

$ groovy euler1.grv
Caught: java.lang.StackOverflowError
 at euler1$_run_closure1.doCall(euler1.grv:11)
 at euler1$_run_closure1.doCall(euler1.grv:9) . . . 

Actually, it's not Groovy's fault - blame the JVM. Stack Overflow has this explanation... I tried both proposed solutions on this page but neither work with my version, 1.5, sigh...

Groovy comes with a console, so you can paste your code into the console and run it from there. Or, you can execute Groovy, passing your script in as an argument. Oh, and even with this trivial example, Groovy is as slow as an asthmatic snail:

$ groovy euler1.grv
233168
Clone this wiki locally