We achieve this in clojure through clojure's lovely typing mechanism which allows you to declare types that have publicly known functions without any data declarations; and private implementations of those functions that know the data they are manipulating.
One last note. C was much more encapsulated than C++, Java, or C# because in C you would declare your functions in a .h file, and your variables in a .c file. No other .c file could see your variables, so they _had_ to use your functions. The public/private keywords were added to C++, and then to Java and C# because the act of putting variable and function declarations in the same source file broke encapsulation, and we needed a way to re-assert it. That reassertion was only partially effective.
The bottom line is that all the C based OO languages are _less_ encapsulated than C.
As the size of a class grows, mutable member variables approach globals. If you wisely break the class into smaller ones, classes will still contain instances of other classes, so to reason about the behaviour of your class you often have to understand the possible state of its sub-instances. This is especially true if multiple classes reference the same instance.
Does Clojure guarantee all these things? Not entirely; because Clojure allows you to invoke the java stack, which is decidedly not immutable; and because clojure provides mechanisms for changing state; albeit with significant discipline imposed.
The end result is that clojure is _much_ safer to use in complex and multi-threaded systems, and is likely much, _much_ safer in extreme multi-core applications.
Closure actually has truly local mutability, in its "transients" feature