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?
Many Java developers will already be familiar with 'closures-lite' - design patterns that imitate closures with classes:
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.
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.
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With