There’s been a lot of hype around lambdas getting introduced in Java 8, and I have a good theory on why: hype is often born out of anticipation, and we’ve been anticipating lambdas in Java for a LONG time.
The funny thing is that lambdas don’t, by themselves, do anything new. They’re just a succinct form for turning a block of code into an object that can be passed around – syntactic sugar. Some of us have been doing this for a while without the succinctness and we call it… object-oriented programming! Yes, passing blocks of code (aka functions) around as objects (aka values) is also core to functional programming, but certainly not unique to it.
Somewhere that this idea of “passing code around” is heavily utilised is in the Gang of Four’s Design Patterns, which got me thinking: Will having lambdas in Java make a bunch of the classic design patterns easier to implement and discuss?
So here’s my whirlwind summary of design patterns that can be re-written using lambdas…
A lambda that conforms to some interface and returns a new object.
A lambda that calls a function with a different signature on some other object.
(Assuming the adapter interface has one public function.)
Chain of responsibility
A lambda that may or may not delegate to another lambda, which may or may not delegate to another lambda, ad infinitum.
(How to get the ‘next’ reference into the lambda is left as an exercise for the reader.)
Otherwise known as: a lambda!
(Assuming you’re not planning on implementing undo. But then you just want a tuple of lambdas, don’t you?)
A lambda that calls another lambda with the same signature but changes the arguments on the way in, or the result on the way out, or performs some extra action.
(Assuming the decorated object has one public function.)
Close (though not identical) to forEach(lambda). More specific functions like map(lambda), filter(lambda), flatMap(lambda), foldLeft/Right(lambda), reduceLeft/Right(lambda), etc. cater for the majority of Iterator’s use in modern Java.
Give some other object a lambda to call when something happens in the future.
(Assuming the Observer interface has a single function.)
Choose from a family of lambdas with identical signatures at runtime.
Replace the abstract method polymorphism with composition, passing lambdas into the constructor.
I guess I should write something here. These patterns aren’t going to die or go away. The way we make use of them may become different/simpler/terser due to the introduction of the syntactic sugar of lambdas.
The main point of design patterns, however, was never to provide cookie-cutter class diagrams; it was to create a pattern language that software developers can use to discuss common solutions to common problems. Those problems are still around, and the pattern names still serve extremely well in discussing possible solutions, regardless of whether you throw a few lambdas into the mix when implementing them.