Functional Programming

There are many programming languages. Most of them are based on C. However, there are a few different schools of thought. There are imperative, object-oriented, and functional schools and a couple of branches and variations, but that's the mainstream of languages you will see in production in big companies. Programming languages is how we express our intents and turn that intent into value for people. Usually, people are concerned about how other engineers would read the code, make sense of it, and be able to effectively maintain it. System programming languages like C and Zig tend to focus more on performance over abstractions (which always have a cost). Object-oriented programming languages like Java focus more on structure and how to abstract things. Abstractions are not necessarily bad if done right. They have a cost and impact on the people who maintain them. Having more abstractions on the SDK or standard library is a good thing for mantainance and increases people's knowledge about them and how to use them properly. But no matter where the abstraction comes from, whether from the standard lib or a 3rdy party library, there is always the learning curve. There are many tradeoffs between performance, maintainability, abstractions vs. benefits, and non-obvious dimensions like operation ability (how do you observe, troubleshoot, tuneup, profile, how mature is your tooling for production support, etc...). Recently, there has been some attrition on Linux Kernel on the debate C vs. Rust. For sure, Rust is modern and has nice functional abstractions. However, what people often forget to account for is that you have solid infrastructure and tools that can compensate for a lot of language gaps. Not everything needs to be fixed at the language level, and 100% for sure, not on the library level.

School of Tought

Object Oriented Programming (OOP) is a school of tought. Done right is not a bad one. Functional programming is another school of tought. Also, if done right, it can be good. Any engine engineer can code in any language. However, to take advantage of it, you must go deeper to fully understand the school of thought and how to properly operationalize it in production. Which sometimes, in fact, is one of the barriers to new languages.

Functional programming has two main branches: Lisp and Haskell. Clojure comes from the Lisp school, and Scala comes from the Haskell school. Both are functional programming languages, but they have very different approaches. For instance, Clojure is very into dynamic programming, like you would with OOP languages like Ruby. Scala, which takes the Haskell approach, is the opposite; it is all about leveraging type systems, complex type manipulations via higher-order functions, higher kinded types, monads, and other generics patterns, but all boiling into the compiler.

IMHO, There is no better school than Tought. I like both; it's all about the teams and people you have and your passion for learning new things. Good engineers will continuously learn new languages and ways of tought, even if they don't use production that POC in V or Idris will pay off in the long run.

State Misinterpretation

The state is something people often get wrong in functional programming. Functional programming favors immutability, yes. Even if you are doing OOP you should favor immutability. Having a state is not bad; now, having an indiscipline state that's where it can be pretty bad. Shared state is a problem even outside of functional programming; let me give you a list of bad examples of shared state:

  • Shared Database: The most obvious and yet form of indisciplined state, which leads to distributed monoliths. Pretty bad and the source of many problems at scale. Resource contention, Scalability issues, Availability issues, Ownership issues, and many other problems.
  • Aspect-Oriented Programming: IF you create a central aspect to enforce rules and behavior across all your classes, you have code that is not obvious and can be hard to test and maintain. 
  • Global Chained State by Reference: Create a global variable and pass it by reference to 3-5 methods, and you already have very difficult code to understand and refactor.
Having state discipline is a great thing. You don't necessarily need Free Monads to have a clean and decent code base. State, Reader, and Writer monads are just abstractions. One way or another, you will need to have a way to enforce common ways of expressing code. It could be via standard abstractions, but it could also be done with centralized function responsibility, usually done through and shared via design sessions and code reviews. 

Functional Patterns

OOP, we have design patterns, but FP is not different. There is a combination of some types of classes plus functions you need to implement. But we can summarize the functions you need to implement. So, functional programming patterns are all about functions. Here is a simple summary:

For the sake of comparison, if we trace a parallel with OOP. Let's say you have to have a value that doesn't change, and when consumers read that value, it should always be the same; we would create a Singleton, which in FP could be ReaderMonad. IF you are using Scala, you have both schools of tought at your disposal and can even combine the patterns. 

Complexity and Performance

The more abstractions you get, the more impact on performance you will have. Do not think abstractions are for free. Build time and execution time in production can be a problem. Always check the generated assembly and perform performance tests and benchmarks to ensure your abstractions are not killing the performance. 

Complexity is another very interesting tradeoff. If everybody knows Haskell, having monads might be fine; otherwise, you can have a simple and grounded abstraction that people can understand and wrap their heads around. Either way, there will be a cost for people to understand and get used to it.

Influence on Modern Engineering

No matter if you are into functional programming or not, no matter if the language is a functional programming language or not, we see and tend to continue to see lots of influence from functional programming in new languages like Kotlin, Typescript, Rust, and many others.  

Cheers,

Diego Pacheco



Popular posts from this blog

C Unit Testing with Check

Having fun with Zig Language

HMAC in Java