←back to thread

296 points gyre007 | 2 comments | | HN request time: 0s | source
Show context
cryptica ◴[] No.21281989[source]
OOP was designed to prioritize encapsulation at the expense of referential transparency. Functional programming was designed to prioritize referential transparency at the expense of encapsulation.

You cannot have referential transparency and encapsulation at the same time.

In order to prevent mutations (which is a requirement of FP), a module cannot hold any state internally; this necessarily means that the state must be passed to each module action from the outside. If state has to be passed to each module action from the outside, then this necessarily means that the outside logic needs to be aware of which state is associated with which action of which child module. If higher level modules need to be aware of all the relationships between the logic and state of all lower level (child) modules, that is called 'leaky abstraction' and is a clear violation of encapsulation.

Encapsulation (AKA 'blackboxing') is a very important concept in software development. Large complex programs need to have replaceable parts and this requires encapsulation. The goal is to minimize the complexity of the contact areas between different components; the simpler the contact areas, the more interchangeable the components will be. It's like Lego blocks; all the different shapes connect to each other using the same simple interface; this gives you maximum composability.

Real world software applications need to manage and process complex state and the best way to achieve this is by dividing the state into simple fragments and allowing each fragment to be collocated with the logic that is responsible for mutating it.

If you design your programs such that your modules have clear separation of concerns, then figuring out which module is responsible for which state should be a trivial matter.

replies(5): >>21282691 #>>21283116 #>>21284562 #>>21287900 #>>21295632 #
1. overgard ◴[] No.21282691[source]
Encapsulation is desirable because it limits the possibility space of what can operate on a set of data. Referential transparency is desirable because pure programs are much easier to reason about. If I understand what youre saying, it seems youre saying referential transparency and encapsulation are at odds and encapsulation is more valuable, but I disagree. Hiding state maybe keeps things tidy and enforces that you need to use the API, but its not really the point IMO. The point of encapsulation is managing state mutations. Hiding state is only a small part. You dont need to hide state as much when its immutable because then you don’t need to care what other code is doing with your emitted data structures because it doesn’t effect you.
replies(1): >>21291516 #
2. cryptica ◴[] No.21291516[source]
Encapsulation doesn't necessarily mean hiding state. It means hiding the implementation details of how actions mutate the state. The same action called on a different kind of module instance can end up mutating the instance's internal state in a completely different way. The higher level logic should not be concerned with how a module performs an action.