I think it depends a lot on the language's syntax and what sugar it offers. I believe there are choices you can make that make closures superior to objects in every possible way.
Consider this simple syntactic rule: `obj.x` <=> `obj("x")`. With this rule, the usual syntax for a method call, `obj.method(x)`, literally becomes the curried application of a closure, `obj("method")(x)`. You could also add a rule like `obj(x) = y` <=> `obj(set(x, y))`. Then you could define objects a bit like this:
point = (x, y) -> method ->
match method:
"x" -> x
"y" -> y
set("x", newx) -> x = newx
set("y", newy) -> y = newy
"add" -> (pt) -> point(x + pt.x, y + pt.y)
p = point(1, 2)
p.x = 5
print p.add(point(3, 4))
All closures. And the nice thing with that scheme is that meta-programming and reflection become completely trivial. Control over the interface is total. What use is there for "real" objects in this situation?
Consider this simple syntactic rule: `obj.x` <=> `obj("x")`. With this rule, the usual syntax for a method call, `obj.method(x)`, literally becomes the curried application of a closure, `obj("method")(x)`. You could also add a rule like `obj(x) = y` <=> `obj(set(x, y))`. Then you could define objects a bit like this:
All closures. And the nice thing with that scheme is that meta-programming and reflection become completely trivial. Control over the interface is total. What use is there for "real" objects in this situation?