I commented on the case of management structures. Let me comment on the closure of objects. Consider what happens when you call an object method; it has access not only to the list of arguments, but also to the fields of the object. That is, the method / function is closed above the fields. This is no different from a bare function (i.e., not an object method) that closes variables in scope. However, object syntax provides a good mechanism for abstraction and modularity.
For example, I could write
case class Welcome(message: String) { def greet(name: String) = println(message + ", " + name) } val w = Welcome("Hello") w.greet("Dean")
vs.
val message = "Hello" val greet = (name: String) => println(message + ", " + name) greet("Dean")
Actually, in this example, I can remove the keyword "case" from the greeting so that the message does not become a field, but the value is still in scope:
class Welcome2(message: String) { // removed "case" def greet(name: String) = println(message + ", " + name) } val w = new Welcome2("Hello") // added "new" w.greet("Dean")
It still works! Now greet closes the value of the input parameter, not the field.
var welcome = "Hello" val w2 = new Welcome2(welcome) w2.greet("Dean") // => "Hello, Dean" welcome = "Guten tag" w2.greet("Dean") // => "Hello, Dean" (even though "welcome" changed)
But if a class refers to a variable in the outer scope directly,
class Welcome3 { // removed "message" def greet(name: String) = println(welcome + ", " + name) // reference "welcome" } val w3 = new Welcome3 w3.greet("Dean") // => "Guten tag, Dean" welcome = "Buon giorno" w3.greet("Dean") // => "Buon giorno, Dean"
Make sense?