ThaDon
ThaDon

Reputation: 8068

When to use Closures

Note: jump down to "Question" below if you just want to skip the context

When giving talks on Scala I'm almost always certain I'll be asked "but when would you use a Closure?" Typically I say "wait until I show you a for comprehension" and then I show how the for comprehension can be boiled down to using flatMap/map + closures.

This example does help, however it's tough for me to explain a general "this is when you'd recognize when to use a closure". It's one of those things you "just get used to" in functional programming, you almost do it without thinking.

Typically I'm talking to Java devs when I speak about Scala, and one analogy that comes to mind is "you know when you create an anonymous inner class that needs to access a variable somewhere above where the class was defined? That's like a closure". So I use event call-back processing as one particular example (as inevitably you use anonymous inner classes in that scenario).

Considering the audience (no experience, or limited experience with FP) I don't go on to discuss terms like Monads, these people are typically looking for concrete/pragmatic examples they can relate to.

Question: Anyone have their own way of successfully explaining closures that really hits home for Java (or other OO language) developers?

Upvotes: 13

Views: 2315

Answers (5)

BitMask777
BitMask777

Reputation: 2733

You asked for a simple explanation of closures for devs coming from languages where they are non-existent or rarely used.

Here's a succinct explanation likening them to stackframes that are not deallocated when a function returns: "JavaScript Closures 101- they're not magic". I find this to be a helpful conceptualization for a traditional dev struggling with the idea.

Also, Goslings upvote of them in the early days of the Java closure debate would be of interest to Java devs. Note that he also references Neal Gafter's original proposal for their inclusion in Java.

Upvotes: 1

eivindw
eivindw

Reputation: 1959

If you mean anonymous functions in general, and not just closures, I typically use the following example. Give a simple collection (in this case a list of names), and show how much simpler it is to query and modify with anonymous functions.

Java - get a new list of names beginning with "A":

List<String> names = Arrays.asList("Ed", "Bob", "Anna");
List<String> namesOnA = new ArrayList<String>();

for(String name : names) {
  if(name.startsWith("A")) {
    namesOnA.add(name);
  }
}

Scala - get list of names beginning with "A":

val names = List("Ed", "Bob", "Anna")
val namesOnA = names.filter(_.startsWith("A"))

Similar examples using map, reduceLeft and other methods on the collections. Most Java developers find this interesting.

Upvotes: 1

Edwin Buck
Edwin Buck

Reputation: 70909

Why don't you reverse the order of presentation? When you would normally present Closures, present a well known pattern (like Listener or Visitor). Then show how Closures solve the problem without the creation of extra "helper" objects or unnecessary code frame-working.

You say that your audience is looking for concrete examples of how Closures work. After presenting a few of them, then you can back pedal and properly define a Closure. The technique of presenting the problem, solving it, solving it again, solving it again, and then presenting the greater theory is not foreign to programmers. That's how they discovered patterns in the first place.

Upvotes: 6

Dan Vinton
Dan Vinton

Reputation: 26769

Many Java developers will already be familiar with 'closures-lite' - design patterns that imitate closures with classes:

  • visitor
  • command
  • strategy
  • functor (see Google Guice's collections handling for many examples)
  • callback/listener (large swathes of Swing)

Whenever a Java developer reaches for one of these patterns to solve a problem in Scala, they should be considering closures as a lightweight alternative.

As you mention, first-class closures are in some ways just a logical extension of these patterns - if my anonymous class only has one method, why not do away with the class altogether, and just have the method itself?

It may also be worth discussing what all of these patterns have in common - they are all some form of abstraction of control flow. They separate control flow itself from an action to perform at certain points in this flow. Any similar separation of concerns can benefit from closures.

Upvotes: 10

Chris Nauroth
Chris Nauroth

Reputation: 9844

I think you're right on track in relating closures to anonymous inner classes for the sake of introducing the concept to Java developers. I recommend taking some problem that involves heavy use of callbacks, and showing a slide with a side-by-side comparison of the code required in Java using anonymous inner classes and the code required in Scala using closures.

Here are a couple of ideas for problems involving callbacks:

  1. Swing button click handlers
  2. Anything involving a Runnable or Callable (i.e. submitting a task to a ThreadPoolExecutor)
  3. SAX event-based XML parsing
  4. JDBC-based database access code passed through a common transaction executor to cut down on boilerplate connection acquisition/release

For each of these examples, I expect that the Scala/closure solution will turn out shorter and simpler than the Java/anonymous inner class solution.

Upvotes: 1

Related Questions