Coming from an OOP language, I am familiar with the SOLID principles of object oriented design. It seems like some of these would fit into a functional programming model, while other parts make no sense in a world lacking state. Is there a similar set of principles for refactoring functional code?
Are the SOLID principles applicable to Functional Programming? Of course. Functional programmers want to separate their code to avoid crosstalk between responsibilities and users. They want to minimize the number of modules affected by a change.
SOLID is a popular set of design principles that are used in object-oriented software development. SOLID is an acronym that stands for five key design principles: single responsibility principle, open-closed principle, Liskov substitution principle, interface segregation principle, and dependency inversion principle.
According to Orner, while the practice of software development has changed in the past 20 years, SOLID principles are still the basis of good design. The author explains how they also apply to functional programming and microservices architecture, with examples.
As far as I know (I'm no expert), SOLID principles do not tell anything about state. They should be applicable as well in a functional programming languages. They're more advice about how to achieve modularity.
Some of them are rather obvious or at least well-known. Single-responsibility is the UNIX principle "do one thing and do it well", which is even more popular in functional languages where "composition" is widely used, similarly. The Interface Segregation Principle is very natural as well (have your interfaces modular and keep orthogonal concepts separated). Finally, Dependency Inversion is just a name for "abstraction" and is omnipresent in functional programming.
The "OL" principles, Open/Closed and LSP, are more oriented towards languages based upon inheritance as a core software engineering concept. Functional languages values/modules do not have open recursion by default, so "implementation inheritance" is only used in very specific cases. Composition is preferred. I'm not sure how you should interpret the Open/Closed principle in that setting. You may consider it is about encapsulation, which functional programs also use a lot, using abstract types and such.
Finally, the Liskov Substitution Principle may seem to be about inheritance. Functional languages do not always use subtyping, but when they do it is indeed assumed that "derived types" should preserve the specification of "base types". Functional programmers are of course careful to specify and respect the interface and properties of their programs, modules etc., and may use algebraic reasoning (this is equivalent to this so I can substitute...) based on those specifications when programming, refactoring, etc. However, once you get rid of the "inheritance by default" idea, you have much less problems of interface violations, so LSP is not emphasized as a vital safeguard as it is in OOP.
This video presents the SOLID principles, and how to apply them in Clojure.
It shows how these principles hold in the Functional world as much as in OOP, because we still need to solve the same underlying problems. And overall, it made me think Functional Programming is better suited for SOLID design.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With