The way I like to put it is that instances and closures are duals: a closure can do exactly one thing, while an instance can, in general, do several things. That's why, when invoking an instance, you have to supply a method name that says which of the several things you want it to do, while when invoking a closure no method name is necessary.
Of course it's not a hard-and-fast distinction: you can have a closure that dispatches on one of its parameters to do one of several different things, and you can have an instance with only one method. But it's usually valid.
If you think of a closure as only returning a reference to a function, but a closure can return anything. What if my closure returns an ssh connection to a new machine? A database? A program that generates programs? A hash of functions specialized to my calling arguments? How is a the function that returns a closure different from a constructor?
You can also do it over just one function that takes in a variable that modifies behavior.
Imagine you have a closure with a function that takes in a string and a list and returns a list. Depending on implementation of the function, you could have the string be the operation you wish to perform. The method name, and the list be the parameters. The returned list is the output.
Getters could pass an empty list and return a list with one entry
Setters could pass a list with a value and return an empty list
And so on :)
Like this:
func NewClosure() func(string, ...float64) []float64 {
x := float64(0)
return func(method string, args ...float64) []float64 {
if method == "setX" && len(args) > 0 {
x = args[0]
return nil
} else if (method == "getX") {
return []float64 { x }
} else {
panic("invalid method")
}
}
}
a := NewClosure()
b := NewClosure()
a("setX", 50)
b("setX", 12)
fmt.Printf("a.X = %v, b.X = %v", a("getX")[0], b("getX")[0])
For this reason, I think of objects as not equivalent to closures, but rather ML-style functors. I think implementing objects as records with closures as fields is really just a poor man's parameterized module.
Of course it's not a hard-and-fast distinction: you can have a closure that dispatches on one of its parameters to do one of several different things, and you can have an instance with only one method. But it's usually valid.