How are "Closures" such a powerful abstraction that object systems and fundamental control structures are implemented using it?
Here is a quote from programming scala chapter 1:
Closures are such a powerful abstraction that object systems and fundamental control structures are often implemented using them
Apparently the statement is not specifically about Scala but Closures in general but I can not make much sense from it. Perhaps it is some pearl of wisdom only meant for those mighty compiler writers!
So who uses Closures to implement fundamental control structures and why?
Edit: I remember reading something about custom control structures in groovy "using the closure as the last parameter of method call" syntax and making the structure available to your code using meta-classes or use
keyword with Categories. Could it be something related?
Edit: I found the following reference of the groovy custom control structures syntax here (slide 38):
Custom control structures
Thanks to closures
- When closures are last, t开发者_如何学Chey can be put “out” of the parentheses surrounding parameters
unless(account.balance > 100.euros, { account.debit 100.euros })
unless(account.balance > 100.euros) { account.debit 100.euros }
- Signature
def unless(boolean b, Closure c)
Apparently what groovy is offering is a syntactic sugar for making the Closure based custom control structures appear like first-class control structures offered by the language itself.
I commented on the case of control structures. Let me comment on closures as objects. Consider what happens when you call a method on an object; it has access not only to the argument list, but also the fields of the object. That is, the method/function closes over the fields. This isn't that different from a "bare" function (i.e., not an object method) that closes over variables in scope. However, the object syntax provides a nice abstraction and modularity mechanism.
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 could remove the "case" keyword from Welcome, so that message doesn't 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 over the value of the input parameter, not a 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 the 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?
There are three fundamental control structures:
Sequence
a = 1
b = 2
c = a + b
Conditions
if (a != b) {
c = a + b
} else {
c = a - b
}
Iterations/loops
for (a <- array) {
println(a)
}
So, I guess they mean that internally many languages use closures for control structures (you can look the last two structures).
As an example:
if (a < b) {
for (i = a; a < b; a++) {
println(i)
c = i * i
}
} else {
c = a - b
}
So for
is a closure inside the if
closure, and else
is a closure too. That's how I understand it. They create a closure for the first if
if the condition is true, create the closure inside the braces, call it. Then create a closure for the for
loop and call it while the condition is true.
And I guess there is no list of languages which use closures internally.
Update:
Just as an example, this is how you can implement your own for
loop in Scala (o is cyrillic, so it will compile):
def fоr(start: Unit, condition: => Boolean, increment: => Unit)(body: => Unit): Unit = {
if (condition) {
body
increment
fоr(0, condition, increment)(body)
}
}
var i = 0
fоr (i = 0, i < 1000, i += 1) {
print(i + " ")
}
So actually this is how it can be implemented in other languages on the inner level.
I would say that "closures are such a powerful abstraction..." because unlike standard methods, you have a reference to the calling object, regardless of the scope in which the closure has been called.
In Groovy, for example, you can add a new method, "capitalize" to String type:
String.metaClass.capitalize = {
delegate[0].upper() + delegate[1..-1].lower()
}
"hello".capitalize() // "Hello"
Or, you can do something more complex, like create a domain specific language (DSL) using closures.
class ClosureProps {
Map props = [:]
ClosureProps(Closure c) {
c.delegate = this // pass closure scope to "this"
c.each{"$it"()} // iterate through closure, triggering missingMethod()
}
def methodMissing(String name, args) {
props[name] = args.collect{it} // collect extracted closure properties
}
def propertyMissing(String name) {
name
}
}
Example
class Team {
// the closure
static schema = {
table team
id teamID
roster column:playerID, cascade:[update,delete]
}
}
def c = new ClosureProps(Team.schema)
println c.props.id // prints "teamID"
a) Please try at least googling topics before asking questions.
b) Once you have done that, please ask specific questions.
c) Lexical closures are functions that have access to a lexical environment not available where they are invoked. As such, their parameters can be used to select messages, and pass parameters with those messages. For general control structures, they are not sufficient, unless they can affect the call stack, in the manner of continuations.
精彩评论