I’ve felt resistance to functional programming and to functional programmers ever since functional programming became “a thing”. While I’m disappointed by the arguments made against functional
programming, I am equally (if not more) frustrated that the functional programming point of view has not evolved, leading it to be easily derided as developer religion. It’s time to move the discussion forward. Because no matter our views on functional programming vs.
object-oriented programming vs. whatever else, we all need to be functional engineers. Functional engineering is more than writing code. It’s about solving problems in the context of the world we work and live in. There are imperfections in the real world. We run into complexities that can’t be modeled nicely yet still need to integrate with other (sometimes poorly-designed) systems. There are constraints in resources and schedules in order to hit business goals and keep the ship afloat. We have to make the
compromises necessary to deliver solutions that meet all these requirements, negotiating where possible while standing firm on critical aspects (e.g., safety must be designed in; it cannot be tested in or retrofitted).
Our compromises and firm stances need to be data-driven because engineers do not work on reactionary, baseless theories. We hypothesise and rely on quantitative evidence from our own experimentation and the experiences of our teammates. Then we must be able to communicate our findings and resulting reasoning to any audience — even a non-technical audience.
Functional engineering is more than writing code. It’s about solving problems in the context of the world we work and live in.
Build with urgency and quality
I also want to address the argument against time pressure — e.g., “your can’t rush innovation”. While time pressure probably is indeed a lousy way to foster innovation, we do live in a world of fast delivery of customer-facing value. Deadlines aren’t just some arbitrary date from managers. They are driven by observing the market we operate in. Every company has competitors moving faster. Being a functional engineer means treating fast delivery and high quality as hard requirements. As if your team’s survival depended on it (spoiler alert: it does). Let’s not dismiss this reality. Instead, let’s look at it as an opportunity to prove our strength. Those of us who’ve been lucky enough to choose the technology stacks for their projects also need to remember the responsibility that comes with that freedom. If we don’t show improvements in delivery, it becomes harder for even the most supportive team leads
to justify letting us make those choices the next time around (and I’m talking about the elephant in the room, here: mandated tech stacks). So let’s work together to support our team leads and prove we deserve the trust they’ve placed in us.
Deliver solutions, not components
Functional programmers (and software engineers in general) like to tinker with code. But functional engineers balance perfecting the code with ensuring the overall system is delivered and maintainable. Considering the system as a whole is not simply a matter of considering all its smaller parts. There are operational considerations, documentation, integration of all the services, migration, then finally the roll-out to customers. That’s a lot to do beyond just the coding itself. And it all needs to fit into the time between now and the delivery date. We can do ourselves a favor by applying functional programming principles not just to the code, but to the architecture of our systems. For example, some of the work in perfecting a small microservice ends up going to waste because microservices are meant to be thrown out and rewritten if they no longer meet your needs. By contrast, applying functional concepts such as append-only stores and event-based architectures helps our efforts live much longer. This, in turn, let us spend more energy perfecting the system as a whole, instead of rabbit-holing on individual
Apply the principles of functional programming(versus “Functional Programming”)
The term “Functional Programming” means different things to different people. Some fear it, some love it, some believe they are doing it but don’t really understand it. I feel the term is getting in
the way of everyone understanding that we’re all talking about the same principles.
We can do ourselves a favor by applying functional programming principles not just to the code, but to the architecture of our systems.
Immutability wherever possible. This isn’t just a Functional Programming thing. It’s a tenant of building high-performing, highly-concurrent systems.
Less code means fewer bugs. Use available libraries over writing things ourselves not only means less code, it means more time for documentation, migration, and all the other things I mentioned above.
Don’t repeat yourself. Find the right abstractions to reduce code duplication.
Think of software as data transformation. Almost all software we write is mainly just reading data from somewhere, allowing code or user transformations, and then saving it somewhere else.