I'm obviously not who you're asking, but I'm going to cheekily show up with my own thoughts on the subject, anyway:
I'm coming to the opinion that, if you need private member functions to retain encapsulation, that's a strong sign that your design was never properly encapsulated in the first place.
The motivation for making something private is to prevent people from breaking your object by messing with things they shouldn't. Generally speaking, only real way for it to be possible break an object is if its internal state is complicated enough to allow that to happen in the first place. Which is itself a failure of encapsulation.
Somewhat more concretely: If you've got to private fields A and B, where any change to A must be accompanied by some corresponding change to B, and the logic for enforcing that rule needs to be enforced at several places within your class, then, at the level of abstraction your object is operating at, A and B represent a single logical entity, and should never have been represented as individual fields in the first place. They should have been encapsulated into their own object.
Even more concretely:
Don't do this:
class Thing {
val counter = 0;
fun foo() {
val x = counter;
counter++;
...
}
fun bar() {
val x = counter;
counter++;
...
}
}
And don't do this:
class Thing {
val counter = 0;
fun foo() {
val x = counter_next();
...
}
fun bar() {
val x = counter_next();
...
}
private fun counter_next() {
val x = counter;
counter++;
return counter;
}
Do this:
class Counter {
int state = 0;
fun next() {
val x = state;
state++;
return x;
}
}
class Thing {
val counter = Counter();
fun foo() {
val x = counter.next();
}
}
Very abstractly: Composing objects is the core idea behind OOP. In general, the more object-oriented design is the one that favors object composition over other language constructs whenever possible.
Also, this is all arguably a separate issue from using privates simply to avoid cluttering your public interface when factoring code. If you're working in a language that doesn't really have good nested functions, private methods are your next best choice.