Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groovy : Closures or Methods

I've got into the habit of using Closures everywhere I can in place of regular methods, even when I don't need access to free variables. So, I will use this:

def addNumbers = { left, right -> left + right }

.. instead of this:

def addNumbers (left,right) { left + right }

Is this bad practice? I far prefer the extra power I get when using closures over methods, and I far prefer the syntax.

Thanks!

like image 995
djcredo Avatar asked Dec 01 '09 10:12

djcredo


People also ask

What are closures in Groovy?

A closure in Groovy is an open, anonymous, block of code that can take arguments, return a value and be assigned to a variable. A closure may reference variables declared in its surrounding scope.

Is method in Groovy?

A method is in Groovy is defined with a return type or with the def keyword. Methods can receive any number of arguments. It's not necessary that the types are explicitly defined when defining the arguments. Modifiers such as public, private and protected can be added.

How do you call a method in Groovy?

In Groovy, we can add a method named call to a class and then invoke the method without using the name call . We would simply just type the parentheses and optional arguments on an object instance. Groovy calls this the call operator: () . This can be especially useful in for example a DSL written with Groovy.

How do I return a Groovy closure?

We can even return closures from methods or other closures. We can use the returned closure to execute the logic from the closure with the explicit call() method or the implicit syntax with just the closure object followed by opening and closing parentheses ( () ).


2 Answers

I only use closures where I need them, i.e. I use methods by default. I do this because

  • Methods are simpler than closures. Closures have a delegate, an owner, retain access to variables that were in their local scope when created (what you call "free variables"). By default method calls within a closure are resolved by:

    1. Closure itself
    2. Closure owner
    3. Closure delegate

But this order can be changed at runtime, and a closure's delegate can also be changed to any object.

All of these factors combined can make some code that uses closures very tricky to grok, so if you don't need any of this complexity I prefer to eliminate it by using a method instead

  • A .class file is generated for each closure defined in Groovy. I have exactly zero evidence to support a claim that a regular method is more performant than a closure, but I have suspicions. At the very least, a lot of classes may cause you to run out of PermGen memory space - this used to happen to me frequently until I raised my PermGen space to about 200MB

I have no idea whether the practice I'm advocating (use methods by default and closures only when you need them) is widely considered a "best practice", so I'm curious to hear what others think.

like image 76
Dónal Avatar answered Sep 19 '22 05:09

Dónal


While all the things @Don says are true, I don't know that any of them are all that significant. You can override the delegate of a closure which can change execution, but unless you're passing the closure around (which you can't do with a method anyways) you don't really have to worry about any of those things happening. Playing with the delegate is a feature, not a liability.

As for a possible performance hit from extra class files, why are you using Groovy if you're that worried about performance?

My opinion is that it doesn't really matter. If you have a lot of people on your team that are old Java developers, they're probably going to dislike it when you use closures where a method will do. On the other hand, someone fluent in Groovy will get annoyed if you clutter everything up with methods when a closure makes more sense.

tl;dr - There is no hard and fast rule, instead you should exercise good judgement with an eye towards code readability.

like image 45
noah Avatar answered Sep 22 '22 05:09

noah