Encapsulation can also be handled well at the module/package system level, though. (The package system in OCaml has some particularly interesting features.)
The latter is a mixed blessing. It's often very convenient, but sometimes there isn't a clear answer which object should be the primary one in a binary operation. (This is particularly troublesome with non-commutative operations.)
Lua's syntactic sugar for this ( obj:method(args) vs method(obj, args) ) seems like a good balance; it's explicit that it's just sugar for convenience, but you aren't required to use it.
Encapsulation can also be handled well at the module/package system level, though
Yes, it's more or less the same, but you can define public and private parts for individual objects. The good part of encapsulation is separating interface from implementation: you can publish a data type without giving access to its innards.
sometimes there isn't a clear answer which object should be the primary one in a binary operation
I really haven't found it to be a problem in practice.
Also, look at the functors - modules are first class, so you can write functions that take a module and return a (usually more specific or generated) module.
The latter is a mixed blessing. It's often very convenient, but sometimes there isn't a clear answer which object should be the primary one in a binary operation. (This is particularly troublesome with non-commutative operations.)
Lua's syntactic sugar for this ( obj:method(args) vs method(obj, args) ) seems like a good balance; it's explicit that it's just sugar for convenience, but you aren't required to use it.