Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 371
ThaDon Avatar asked Jun 21 '11 15:06

ThaDon


3 Answers

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.

like image 167
Dan Vinton Avatar answered Nov 17 '22 15:11

Dan Vinton


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.

like image 27
Edwin Buck Avatar answered Nov 17 '22 16:11

Edwin Buck


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.

like image 1
Chris Nauroth Avatar answered Nov 17 '22 16:11

Chris Nauroth