
Ask HN: Why are private/hidden methods so popular in OOP APIs? - swidi
As a Python programmer, I heartily subscribe to the philosophy of &quot;we&#x27;re all consenting adults here&quot; [0]. Nothing should really be private or hidden, because nothing is really stopping a canny user from cracking open your code and accessing that stuff anyway.<p>However, it seems like the opposite philosophy is the prevalent one, so I must ask why? Why do people inside on concealing and privatizing so much of their code, especially in open source projects where I can clearly see what they&#x27;re doing?<p>Thanks.<p>[0]: https:&#x2F;&#x2F;mail.python.org&#x2F;pipermail&#x2F;tutor&#x2F;2003-October&#x2F;025932.html
======
i_cant_speel
I think you need to clarify what you mean by "private". Are you referring to
making methods private?

When you make a method public, you are making a promise to users that you
won't make any breaking changes to that API without a major version upgrade.
Once something is out there, you can't take it back. So if you have some
functionality that isn't meant to be used by the outside world but is used to
serve your API, then you wouldn't want to expose that and tie your hands in
the future.

~~~
argimenes
Another way of phrasing it is that a public interface is a kind of tight
coupling. Also, private methods are typically contain highly factored code
which may have little utility outside of the interface but which is factored
for reasons of modularity.

------
quickthrower2
I know the answer, thanks to watching a recent video by Richard Feldman on why
functional programming isn’t popular yet. I recommend watching it for some
interesting talk about programming languages in general, it’s on YouTube at
[https://m.youtube.com/watch?v=QyJZzq0v7Z4](https://m.youtube.com/watch?v=QyJZzq0v7Z4)

Anyway what privates give you is what everyone wants from a programming
language: modularity.

We want to be able to expose an api to some code and for it to have some inner
workings that we don’t see because:

1\. If we know they can’t be touched we have some implicit guarantees about
our program. E.g. the mouse pointer cannot go off screen even if we try to
make a call to do that.

2\. It is simpler for a programmer to understand the api which might be 1% of
the size of the module itself with all private’s.

3\. I can change my private’s without breaking your calls. Essentially a minor
version change in Semvar parlance instead of a major breaking change.

4\. Make impossible state impossible! By guarding the state.

All these things require modularity, and OO uses classes and private members
to provide that modularity.

Elm uses modules and the exposing keyword (or lack of!) as a contrast.

JS modules are similar with a lack of an export allowing you to hide
something. That something you did export can use for state or functionality.
There is an old IIFE trick that works this way also.

Making everything public is a bad idea, as you miss out on modularity
advantages. Not sure how Ruby hides things as I haven’t used it for a while
but I’m sure there is a way.

And finally reflection in OO to access private’s is almost always a sin,
unless you are make a debugging tool or similar. Canny? No way!

~~~
eyegor
To address your first point, plenty of functional langs have access control -
as an example F# has complete public/protected/private for all levels of
function/class.

------
eyegor
The primary reason is of course encapsulation. Many things you don't want to
leave publically accessible. For instance if you're creating a thread safe
api, you need to be mindful of references/mutexes/locks which can easily be
enforced with wrappers. If you expose the underlying objects directly you
could easily dead lock, corrupt memory, create race conditions, etc. It also
greatly simplifies testing and guarantees/provability since you can guard
against access patterns or certain inputs or states.

Personally, I have run into enough horror caused by mutating a global state
that I write code which is quite strict about what it exposes. If you're a
python dev, I'd suggest reading this (posted on hn recently but I can't find
the hn link currently): [https://instagram-engineering.com/python-at-scale-
strict-mod...](https://instagram-engineering.com/python-at-scale-strict-
modules-c0bb9245c834)

------
valand
I get your sentiment of the overused "hidden"/"private" stuff that seems like
people following some sort of decades-old ritual and then adding
getter/setter, where it should have been all transparent, knowingly that the
module/package will eventually be running in a single process.

"private"/"hidden" attrs/methods help limiting the knowledge needed by new
developers jumping into and building on top of existing code base.

Concealing complexity is necessary, but can be done with other methods such as
HOF, selective exports, etc.

This is called interface-first design paradigm where your module is "serving"
other module by doing its job without exposing its complexity.

Disclaimer: I'm mostly use TypeScript in a functional/data oriented design
manner. Not a big fan of OOP.

------
Aperocky
This is all about the Unix philosophy of ‘do one thing, and do it well’. I
used to be a python programmer before I moved to java and a significantly
larger stack. The public interfaces of different classes made writing new code
so so much easier. In fact, I think python should use this paradigm if only
for the purpose of productivity.

------
ben509
The issue is not consent or privacy, it's promises.

An API is an "application programmatic interface" and the idea of an interface
is that it's making a promise or some kind of contract.

Every precocious teenager thinks they're a consenting adult, but they don't
_really_ understand how fucking works until they've actually made a baby.

So you publish some code that does a thing, and however many consumers are
exploring every sweaty nook and cranny of your interfaces, and not only do you
not remember because cocaine is a hell of a drug, but now you've got a small
legion of dependents you aren't even aware of.

Even if you're using a language like Java that lets you impose the bureaucracy
of encapsulation, there are always various unintended consequences to the use
of your API.

(Besides making assumptions about state, while the API might have all sorts of
encapsulation, it still throws exceptions. And those exceptions might wrap
internal exceptions, so a consumer trying to respond to an error condition
might slide the condom off and investigate those internal exceptions to
identify their specific error.)

There are two major reasons to claim a thing is private:

1\. If your code breaks when I make a change, you can yell at me, but I can
point at the fine print and tell my boss, "nah, it's swidi's fault".

2\. It might even get you to nag me, "I need feature X to do a thing" and then
I'm aware you're using feature X.

I'm working on a language to make APIs work better[1] and you should tell me
if I'm fucking crazy or not.

Don't take any of this seriously, I'm quite inebriated at the moment.

[1]: [https://tenet-lang.org/](https://tenet-lang.org/)

------
muzani
To quote something from Pragmatic Programmer (1999):

"Functions should act like a contract. Functions should do no more and no less
than what they're expected to. If they fail to meet the contract, they should
report it."

------
SamReidHughes
You can reason about your code more effectively when you can see more
precisely what function calls are made on an object or class of objects, and
from where. Making a method private limits that surface area.

------
m463
The more public interfaces you have, the harder it is to improve things.

------
frou_dh
"Implementation Detail" is a fundamental concept in software engineering.

If we don't formalise something as fundamental as that in tooling, we're
pretty much giving up on tooling.

