tags:

views:

1113

answers:

2

Found the following snippet on the Closure page on wikipedia

//# Return a list of all books with at least 'threshold' copies sold.
def bestSellingBooks(threshold: Int) = bookList.filter(book => book.sales >= threshold)
//# or
def bestSellingBooks(threshold: Int) = bookList.filter(_.sales >= threshold)

Correct me if I'm wrong, but this isn't a closure? It is a function literal, an anynomous function, a lambda function, but not a closure?

A: 

I'm not entirely sure, but I think you're right. Doesn't a closure require state (I guess free variables...)?

Or maybe the bookList is the free variable?

Jeremy Powell
"Scala's type inference system automatically recognizes the argument to filter to be a function that takes a book and returns a Boolean value and turns it into a closure".
Schildmeijer
+8  A: 

Well... if you want to be technical, this is a function literal which is translated at runtime into a closure, closing the open terms (binding them to a val/var in the scope of the function literal). Also, in the context of this function literal (_.sales >= threshold), threshold is a free variable, as the function literal itself doesn't give it any meaning. By itself, _.sales >= threshold is an open term At runtime, it is bound to the local variable of the function, each time the function is called.

Take this function for example, generating closures:

def makeIncrementer(inc: Int): (Int => Int) = (x: Int) => x + inc

At runtime, the following code produces 3 closures. It's also interesting to note that b and c are not the same closure (b == c gives false).

val a = makeIncrementer(10)
val b = makeIncrementer(20)
val c = makeIncrementer(20)

I still think the example given on wikipedia is a good one, albeit not quite covering the whole story. It's quite hard giving an example of actual closures by the strictest definition without actually a memory dump of a program running. It's the same with the class-object relation. You usually give an example of an object by defining a class Foo { ... and then instantiating it with val f = new Foo, saying that f is the object.

-- Flaviu Cipcigan

Notes:

  • Reference: Programming in Scala, Martin Odersky, Lex Spoon, Bill Venners
  • Code compiled with Scala version 2.7.5.final running on Java 1.6.0_14.
Flaviu Cipcigan
great answer +1
Jeremy Powell