Closure Design Patterns

Go To StackoverFlow.com

5

These days I'm learning design patterns. There are a lot of documentation about programming design patterns, but I'm interesting in closure design patterns.

I found a presentation of Venkat Subramaniam about Design Patterns in Java and Groovy, and extract some patterns of this presentation that involves closures and others patterns based on my own experience.

Execute Around Method

A pair of operation that needs to be performed before and after operations.

def operations(closure) {
    println "Open"
    closure()
    println "Close"
}

operations { println "Operation" }

===> Open
===> Operation
===> Close

Pluggable Behavior

Specify the behavior of an object at runtime.

def selectValues(number, closure) {
    def list = []
    1.upto(number) {
        if (closure(it)) list << it
    }
    return list
}

assert [2, 4, 6, 8, 10] == selectValues(10) { it % 2 == 0 }  // even
assert [1, 3, 5, 7, 9]  == selectValues(10) { it % 2 != 0 }  // odd

Iterator Pattern

Allows sequential access to the elements.

def listNumbers(closure) {
    (0..5).each { closure it }
}

listNumbers {
    if (it < 3) println "$it is a little number"
    else println "$it is a big number"
}

===> 0 is a little number
===> 1 is a little number
===> 2 is a little number
===> 3 is a big number
===> 4 is a big number
===> 5 is a big number

Dynamical Conditional Execution

Create and execute a conditional operation.

def greet(user, successClosure, failClosure) {
    if (isAdmin(user)) successClosure()
    else failClosure()
}

greet(user, { println "Hi Admin!" }, { println "Hello User" })

I want to know more closure design patterns. Is there any reference about this topic? Feel free to write a new pattern in you favorite programming language.


Update

I wrote a post about this topic (Groovy and Ruby but same content):
Closure Design Patterns
Closure Design Patterns. Ruby Edition

2012-04-03 23:48
by Arturo Herrero
If something has to be named, I usually find that there is too much thought going into it. A closure just represents an invocable context (e.g. function) with a [non-empty] set of bound variables. Nothing special. Also note that a closure is a special type of lambda or anonymous function (one that binds one or more variables): there is arguable no closure in selectValues (well, any of the above examples), for instance. Anyway ... I don't really "get" this question - NoName 2012-04-03 23:52
(Actually, closures need not be anonymous either: they just fit such a pattern well. - NoName 2012-04-03 23:57
Nice question Arturo :). I guess that some of the answers won't be so language agnostic as you'd hope, because what might be OK to do in a language like Groovy, JavaScript or Ruby, will not make too much sense in Java for example. "But Java doesn't have closures!" you may say... well, it has lexically scoped (anonymous) classes, with which you can do everything that can be done with closures. But doing so is so cumbersome that it's easier to just repeat the logic of a "filter" or "map", writing the same "for each" loop time and time again - epidemian 2012-04-04 00:31
@pst You are right about what closures are. The problem with Arturo's question might be that Groovy, the language, uses the term "closure" to refer to any anonymous function. They are an instance of the class Closure. Similar to Ruby's Procs I think. BTW, I also agree that naming some of the common uses of functions as first-class objects is not of much value; I'd stick with saying that a function that expects another function as a parameter, or that returns a function, is a "high order function" and that's all hehe. But I also think it's cool to try and find these patterns : - epidemian 2012-04-04 00:39
You're right. Groovy makes no such distinction between closures or anonymous functions. Should I change the title to Anonymous Function Design Patters or Higher-Order Function Design Patterns - Arturo Herrero 2012-04-04 11:09
@Arturo Before you do anything, I would read a little about the history of the term Design Pattern. It's an interesting one and many old-timers (who relative to the invention of most of these concepts, aren't really that old) will just be reminded of the Gang of Four patterns, and others might think of JavaEE patterns. I think there are newer terms for what your examples do, such as sugar or maybe expressive power (look it up on wikipedia, it briefly discusses higher-order functions and closure). And maybe you should just ask a question about Groovy = - Tony R 2012-04-05 00:09
After thinking about it, I guess I call this type of thing just a pattern. When you put Design in front of it, it sounds like a higher-level issue, like you're drawing UML diagrams on a whiteboard in front of 6 senior engineers.. - Tony R 2012-04-05 00:22


7

I think you're confusing closure with lambda/anonymous functions?

Closure is a lexical context that has bound variables. In short, if you define a function from within a function, the inner function has access to variables defined in the outer function. The "lexical context" in this case is the outer function.

Lambdas are functions that don't have a variable assignment. In Ruby, for example, you can pass blocks to functions, and the function can call it inside using only the yield keyword. In JavaScript you can define a function and pass it as an argument at the same time. Your examples are all this.

First-class functions are yet another thing, which are functions that can be passed around like regular objects. You can pass them as arguments to function calls and hold references to them. This would be like Ruby's Proc. In JS, all functions are first-class and all functions are objects.

In JavaScript we can illustrate all 3 with a silly example:

function foo(func) {
  func();
}
var bar = function() {    // bar is a first-class function
  var i = 5;
  foo(function() {        // this is the anonymous function (lambda)
    console.log(i);       // i is the closure-bound variable
  });
}
foo(bar);   // Prints 5

So, this makes your question confusing. Closure is a language feature, not a design pattern. There are plenty of design patterns whose implementation could use closure or lambda or modulo or constructors or whatever, as you've shown yourself with those examples. Although none of those are classical design patterns, so I'm not sure I would even call them that. Maybe I'd call them sugar.

Java can implement all kinds of design patterns, but has none of these features. A lot of this kind of stuff is done with interfaces, a completely different language feature.

2012-04-04 00:23
by Tony R


1

As people have said, these aren't really "patterns", and are reasonably specific to Groovy, but another two uses of Closures are:

1. Composability

def sum    = { Collection a -> a.sum() }
def first2 = { Collection a -> a.take( 2 ) }

def take2andAdd = sum << first2

println take2andAdd( [ 1, 2, 3, 4 ] ) // Prints 3

2. Currying

def add = { a, b -> a + b }
def add2 = add.curry( 2 )

println add2( 3 ) // Prints 5

And of course, these can be combined:

def square = { a -> a * a }
def add = { a, b -> a + b }
def add2 = add.curry( 2 )

def add2andSquare = square << add2

println add2andSquare( 3 ) // prints 25
2012-04-04 07:42
by tim_yates


1

I agree with the other responses in that it doesn't really make sense to talk about closure design patterns (especially when it seems you are really talking about first-class functions ;) ). I think the point you are really trying to get at is how you can use tools such as first-class functions, lambdas and closures when implementing design patterns. Although it is specific to Groovy, you might find it useful to look at this page: http://groovy.codehaus.org/Design+Patterns+with+Groovy

For example, the "Loan my Resource Pattern" shows how to use Closures in a way very similar to your "Execute Around Method" pattern, and the "Visitor Pattern" is one that also makes good use of Closures and isn't included in your list.

2012-04-10 12:08
by Geli
Ads