Functional programming has been the talk of the town in recent times – and for a good reason. Born from mathematics, this programming approach can lead to a cleaner and more elegant code, easier to manage and review. The dream of every software engineer, and a clearer pathway for startup growth at scale.
Yuri Danilchenko and Jared Schaber talked about functional programming applied to the startup world in our first Tech Talk. Yuri's a co-founder and the CTO here at Latitud, while Jared is our principal engineer. These two teamed up not only to build Latitud, the operating system that supports Latin America's new generation of tech entrepreneurs. They also go way back, as co-founders in a previous company and as long-time tech experts.
You can watch the full rundown of functional programming on the video above. Below, we've jotted down the best insights for a quick but comprehensive 101 on functional programming. You'll discover why use functional programming, what is functional programming, a roadmap to implement functional programming in your startup, and how to hire talent specialized in functional programming.
Before talking about what exactly is functional programming, it's easier to first understand the why behind it.
Something you need to know about software engineers: their work is never done. Code is always evolving. And that's why 1) it needs to be flexible, and also 2) have good readability. Nobody wants to revisit your hieroglyphs, John.
"We're looking for the program that hits the sweet spot: doing what we need to do now with good performance and also being easy to evolve", Jared says.
On your quest for the most flexible and readable code, you will certainly stumble into programming paradigms. Understanding these will be essential to get into functional programming later on, so stick with us.
Programming paradigms classify each programming language based on their unique characteristics. When you know these characteristics, you can then find what language suits your startup's needs the most.
The most known programming paradigms are imperative versus declarative.
In the imperative paradigm, the programmers instructs the machine step by step. In the declarative paradigm, the programmer doesn't explain how to get to the end result but describes really well what is wanted. Instead of stating the order of operations, the programmer supplies what operations are available in the system and the conditions each one has to follow when executed.
A good metaphor from the comic XKCD shared by Jared: you want to teach someone how to get to your house. If you use the imperative paradigm, you'd say something like "from the exit of X subway station, walk two blocks east, make a turn to your right, go down five blocks, and go three blocks west." But if you choose the declarative paradigm, you'd just give them a GPS and your address.
We don't mean to say that the imperative paradigm is bad. For some simpler commands, it has the best cost-benefit. And a lot of languages have a mix of imperative and declarative paradigms. But if declarative is mostly your thing, let's discover what exactly is functional programming.
Functional programming is an approach to software development that results in a cleaner, more elegant code. Here's how functional programming works, in basic terms.
Functional programming uses the declarative programming paradigm, which means it focuses more on the results to be achieved rather than the execution steps.
Functional programming works by applying and composing functions – a sequence of expressions that map values to other values. That's where the functional in functional programming comes from, btw.
These functions can be combined, making the code through functional programming work in modules. For programmers, it's way easier to manage and review code that way rather than having one single extensive code (also called a monolith).
Well, let's get into more detail so you can opt in or out of functional programming. What exactly do you give up when choosing functional programming?
Every programming language you've ever used are immersed in types. Each type describes a term (which could be a word, a number, or any other symbol) and a set of operations that can be performed on this term. For example, "Integer" is a type to describe numbers that don't acknowledge fractions (0, 1, 2, etc.).
Some languages are strongly typed, while others are weakly typed. If you have a lot of them, guess what? With functional programming, you'll need to keep track of all the information you didn't need to before.
The good news is that more modern functional languages have type inference, figuring out what all the types are for you. Your code gets a lot cleaner.
A foundation of functional programming is pure functions. In a pure function, the results only depend on the input – and that makes it much easier to test.
Pure functions also don't generate any side effects besides its return value. A side effect is when a function relies on or modifies something that's outside its parameters (one clear example is when a function recalls data from a database).
The thing is that side effects are actually desirable sometimes – a code hardly exists by itself, without any interaction with the outside world. To battle that, use pure functions in the middle of your program and move these side effects to other parts of your code, such as its edges, making effects easier to identify and test.
Another characteristic of functional programming is being rooted in an immutable state. That means that data structures can't be modified, only copied.
That's useful when we want to avoid unintended effects (let's say, x is always equal to 5, no matter what happens). If you used a shared state rather than an immutable state, you run the risk of updating an object that's being used elsewhere in the system.
From the last sentence, you can imagine just how side effects and shared state make debugging a more difficult task. You need to consider not only what one function, but other functions that might have altered the program beforehand.
When you opt for functional programming and its pure functions, you eliminate side effects and have much easier testing and debugging.
Overhead is a way to measure extra cost. In the world of coding, that extra cost is translated into more computing time, more memory, or more bandwidth to perform a task. When we talk about performance overhead, we're comparing these extra costs between two alternatives.
Functional programming can sometimes take longer to compile when comparing it to approaches that favor the imperative paradigm. Function overhead can be a real thing depending on if your language of choice doesn't have optimizations in place yet or the compiler you're using, for example.
Now that you know what functional programming is and how it compares to other approaches in certain characteristics, here's a special roadmap to implement it in your startup.
You might be wondering where your startup lands in that roadmap. The best advice we can give you is to understand what works (or doesn't work) for your startup.
It's still hard to find great talent with experience in functional programming. According to Jared, if your startup expects to have a team bigger than five software engineers, going for a pure functional languages will be a huge challenge.
Some tips and tricks for hiring tech talent in functional programming, from your friendly neighborhoods Jared and Yuri:
Still, Jared says the future looks bright for functional programming. "I think it's like the chicken or the egg dilemma. There are a lot of developers that are hungry to develop these ideas, that have read too many blogs posts about functional programming and just want to start doing it. At some point you'll have a bigger problem hiring developers that don't wanna do functional programming, to be honest."