I'm not going to lie. There was a time when I used to believe that. I was convinced I only wanted to work with functional programmers because functional programmers are better programmers.
And I know others still think that way. Likewise, some believe that C programmers are better than Rust programmers, devs that use AI tools are better than others, and vice versa.
Reaching that kind of conclusion takes only a few logical (mis)steps. In my case, it was like this:
fp and good code
I care a lot about writing good, reliable software
I consider coding a craft. I want to be productive and write maintainable code that delivers value. I don’t want to do a sloppy job, introduce preventable bugs or tech debt, and get woken up in the middle of the night.
I know that functional programming is a great tool for that
I have years of experience with functional and non-functional languages and suck at the latter. The other day, it took me 3 pull requests (3 deployments to production) to ship a trivial change to a Ruby codebase. Maybe that’s a special case. However, I’m sure I write and read Scala code better and faster than Ruby, PureScript than TypeScript/JavaScript, and so on.
This misdirected me to a naive conclusion: A programmer who cares about writing good, reliable software should use functional programming.
In other words, if someone doesn’t use FP, they don’t care. Right? Cause, why someone interested in writing good code chooses not to? Why are they choosing to use inferior tools and do a sloppy job?
not-fp and good code
Turns out “I” am not the “programmers”. And there are other programmers (and other people).
Just because a tool helps me — doesn’t mean it helps others. People are different, environments are different, abilities are different, and so on.
For instance, some people are good at holding many things in their working memory and switching between tasks, but I’m not. When working on something, I easily get distracted by slack messages, switch contexts, and — poof — completely forget what I was doing. I need functional programming — I need small independent blocks that I can quickly joggle and work with.
Also, people have different values and preferences. Take, for example, abstraction and expressiveness (those are different concepts but related enough). There is plenty of room for choice here. I believe that a typical functional dev is leaning to a greater extent on both. Extracting abstractions, reusing functionality, and refactoring data types, among other things, are completely different experiences in Rust and Haskell. Similarly, handling optionality, errors, lists, and async programming in Scala and Java…
If you aren’t familiar with those or don’t care for them, the ordinary opinionated programming thing is generics. There are Go, Java generics, and Zig comptime, and there are plenty of programmers who prefer and are productive with each one.
fp and bad code
So, there are functional programmers who write good, reliable software, and there are other programmers who write good, reliable software. Which is one thing.
The other thing is that if we deceive ourselves with generic statements (like I did), it’s easy to forget that there are functional programmers who don’t write good, reliable software.
The reason I’m chewing on this topic is this other extreme. I haven’t noticed this in my earlier days, but it turns out that quite a number of FP devs just offload their thinking (or not thinking) onto functional programming, tangential theory, and other standards.
It’s easy to fall into this kind of attitude: FP is so formal and mathematical and whatever, so let’s just over-rely on it and don’t reason ourselves. You know? The people who seriously believe that “if it compiles, it works” or “if it’s according to the specification, it’s perfect”.
Totally shattered my devotion to functional programmers.
In other words, if someone is doing X, it doesn’t mean they have values associated with X, or X can imply any values in the first place.