Regarding encapsulation, here’s how Wikipedia defines encapsulation:
In object-oriented programming (OOP), encapsulation refers to the bundling of data with the methods that operate on that data, or the restricting of direct access to some of an object’s components. Encapsulation is used to hide the values or state of a structured data object inside a class, preventing direct access to them by clients in a way that could expose hidden implementation details or violate state invariance maintained by the methods.
Julia provides neither bundling of data with methods, nor restricting of direct access to object components (i.e. struct fields). However, Julia does encourage using interfaces to interact with objects, rather than directly accessing object fields (although direct access of fields can be incorporated into an interface). Examples of interfaces that are defined in Base Julia can be found here. Using interfaces achieves what I consider to be the most important goal of encapsulation, which is to hide implementation details and ensure that invariance properties of data objects are maintained.
There’s another interesting quote from the Wikipedia page on encapsulation:
The authors of Design Patterns discuss the tension between inheritance and encapsulation at length and state that in their experience, designers overuse inheritance. They claim that inheritance often breaks encapsulation, given that inheritance exposes a subclass to the details of its parent’s implementation.
This is one of the reasons why it is often better to prefer composition over inheritance, which is a principle that is recommended in Design Patterns. Julia does not allow inheritance of concrete data types, so in fact composition is essential when writing Julia code.
So, to sum up, I would say that using interfaces and composition is generally the best way to write code, and neither interfaces nor composition require class-based OOP. ![]()
(By the way, don’t forget that there are many functional programming languages like Haskell, Elm, and Elixir that get by just fine without classes and inheritance.)