Dalla mia esposizione (dichiaratamente limitata) ai linguaggi di programmazione funzionale, come Clojure, sembra che l'incapsulamento dei dati abbia un ruolo meno importante. Di solito vari tipi nativi come mappe o set sono la valuta preferita per rappresentare i dati, sopra gli oggetti. Inoltre, tali dati sono generalmente immutabili.
Ad esempio, ecco una delle citazioni più famose di Rich Hickey of Clojure, in un'intervista sull'argomento :
Fogus: Following that idea—some people are surprised by the fact that Clojure does not engage in data-hiding encapsulation on its types. Why did you decide to forgo data-hiding?
Hickey: Let’s be clear that Clojure strongly emphasizes programming to abstractions. At some point though, someone is going to need to have access to the data. And if you have a notion of “private”, you need corresponding notions of privilege and trust. And that adds a whole ton of complexity and little value, creates rigidity in a system, and often forces things to live in places they shouldn’t. This is in addition to the other losing that occurs when simple information is put into classes. To the extent the data is immutable, there is little harm that can come of providing access, other than that someone could come to depend upon something that might change. Well, okay, people do that all the time in real life, and when things change, they adapt. And if they are rational, they know when they make a decision based upon something that can change that they might in the future need to adapt. So, it’s a risk management decision, one I think programmers should be free to make. If people don’t have the sensibilities to desire to program to abstractions and to be wary of marrying implementation details, then they are never going to be good programmers.
Venendo dal mondo OO, questo sembra complicare alcuni dei principi sanciti che ho imparato nel corso degli anni. Questi includono l'occultamento dell'informazione, la legge di Demetra e il principio di accesso uniforme, per citarne alcuni. Il filo conduttore è che l'incapsulamento ci consente di definire un'API affinché gli altri sappiano cosa dovrebbero e non devono toccare. In sostanza, la creazione di un contratto che consente al manutentore di alcuni codici di apportare liberamente modifiche e refactoring senza preoccuparsi di come potrebbe introdurre bug nel codice del consumatore (principio Open / Closed). Fornisce anche un'interfaccia pulita e curata per gli altri programmatori per sapere quali strumenti possono utilizzare per ottenere o costruire su tali dati.
Quando è possibile accedere direttamente ai dati, il contratto API viene interrotto e tutti i vantaggi di incapsulamento sembrano scomparire. Inoltre, i dati strettamente immutabili sembrano passare attorno a strutture specifiche del dominio (oggetti, strutture, record) molto meno utili nel senso di rappresentare uno stato e l'insieme di azioni che possono essere eseguite su quello stato.
In che modo le codebase funzionali affrontano questi problemi che sembrano emergere quando le dimensioni di un codebase diventano enormi, così che le API devono essere definite e molti sviluppatori sono coinvolti nel lavorare con parti specifiche del sistema? Sono disponibili esempi di questa situazione che dimostrano come questo viene gestito in questo tipo di codebase?