This is also what rubs me the wrong way about the simplistic level with which FP languages (like Haskell or Scala+monads) are either cargo culted or hated. The truth is, the two perspectives really go hand-in-hand, and we're all the worse for not realizing this.
All notations have trade-offs at the level of semantics making certain operations more difficult to express (what programmers refer to as 'the expression problem')
That's the entire shpiel of reification/first-class citizenships/semantics of programming languages.
Instead of getting into fanboi-ism of 'my language is better than your language' perhaps approach the problem from first principles (design): what is "IT" that you want to talk about, reason, express and manipulate in your program?
That dictates the sort of language you need to solve the problem that you are trying to solve.
https://en.wikipedia.org/wiki/First-class_citizen https://en.wikipedia.org/wiki/Reification_(computer_science)
You wind up with two camps that cannot communicate. It's often made worse by the functional programmers - who are mostly also imperative programmers - doing a poor job of enabling translation.
Unfortunately the people that get excited building things is outnumbered by the people that is just in this for the money.
I don't think there's a reason to be sad about it. There are plenty of e.g. maintenance jobs in the industry, and people who are passionate about programming may not be the best fit for this niche - it's boring, and sometimes you feel the urge to re-invent a few wheels even in detriment to actual business needs. For not-so-passionate however it's a good place - minimize efforts while having good salary.
I wouldn't be surprised if people who just program for a paycheck are the majority of employees in many offices. I know they're a tiny minority in a lot of the places I've worked at. That's not a boast or a coincidence - humans cluster in tribes based on shared values. I don't consider myself part of the same community as people who show up to work to close jira tickets and collect a paycheck.
This is why I keep my mouth shut IRL about just wanting the paycheck. I'd imagine a lot more than a tiny minority of people are just there for the job where you've worked. We just keep our mouths shut because the passionate folks judge us paycheckers.
But while you are at your job anyway, might as well make it slightly less of a drudgery while you are at it.
(Eg I quite like functional programming. Both because I like the style of thinking, but also because I don't trust myself nor anyone else with code; and eg a heavy emphasis on immutability means that I'm less likely to get woken up in the middle of the night with some production problem.)
Taking a mercenary attitude towards work works just fine for me, and keeps me overall happier.
Per your example, I like FP and immutability for the same reasons (won't get paged as much), and I'm always reading to stay up on my game, but it's still just work. If you worked with me, you'd probably think I live and breath this stuff as a passion because I put so much time in to stay so much on top of the tools available. But I hate programming. Hell, you might even say my hate of it drives mastery in the same way your passion drives your mastery. To me, it's just a tool by which to automate things I do care about (and retire younger than I could in other roles).
About FP and immutability specifically:
You don't have to go full on and re-write everything in Haskell. Small scale decisions can already make your life easier without much disruption. Eg if you are using Python, by default stick your information in frozen dataclasses, and only deviate from that with good reason.
Another thing I have a minor passion for is to as much as possible handle corner cases in the main line of the code.
Eg instead of having a big 'if' at the start of your function to handle an empty list and return early, try to make sure that the main logic can deal with empty lists just fine.
After all, the simpler your control flow, the easier it is to get code coverage in tests and production.
(I mention `and production', because in practice, lots of code is battle-hardened instead of sufficiently tested.)
you were passionate, found a job that claimed to match your passion and later found out otherwise. rinse and repeat multiple times, and there you go.
soon you started to be paycheck only at your day job and passionate off hours in your free time.
Their real passion is a having a band, or hiking, traveling, etc. And programming is just a way to fund those activities.
Others feel that programming is something that unimportant people do because they feel entitled to become managers. But why would a person like to work for a person they can't learn anything from? a person that looks down on their job? Noone wants a manager like that.
The thing about being "enthusiastic" is that certain cultures and organizations wouldn't at all recognise it and an otherwise enthusiastic programmer can easily become a drudge when the business requirements are just some company-specific internal rules changing all the time.
It's not even that: you can take company internal rule changes and make it 'fun'. Or at least as fun as anything else.
It's perhaps more the attitude of the organization. Both the wider organization and their software making department(s).
Mathematicians want to express equational reasoning/identities.
Computer scientists want to express computations.
Translation/bridging the gap will be a whole lot easier when both camps answered the trivial 'Why?' question which contextualises the reason for doing whatever it is that you are doing.
People without shared goals have the tendency to speak right past each other.
I thoroughly enjoyed your post at the time!
One thing that I disliked, though, was the inaccurate caricaturing of people on camp 2. For example:
> Low level languages are often better than high level languages because you can be more explicit about what the computer will do when it executes your code. (Thus you have more room to optimize).
My concern is the last parenthesis. I am squarely on camp 2, but I'm almost never concerned for optimization. I want my code to be very explicit because I want to understand clearly what it does (thus I hate C++ and other untoward abstractions). Thus clarity is the main motivation, not efficiency as you put it.
On the other hand, I tend to think in terms of abstractions. And thus find things much clearer when they are based on high level abstractions (things like map and filter, RAII, pattern matching, etc). And I like languages like Rust and TypeScript where I can express those. If I read a for-loop, I have to translate it into a more abstract higher-level function in my head to understand what it's doing anyway.
y = f(x);
I'm extremely terrified to what is going on. It is like looking into an abyss. Is this code calling a function named "f" with argument "x"? If so, there may be several different functions "f" depending on the type of "x". Maybe none of them has the same type as "x", but there are some conversions that may happen and lead to that. Or maybe "f" is not even a function, but it is an object that has overloaded the parenthesis operator? And then, what happens to the result, whatever type it has. Is it calling a copy constructor (over some inheritance chain)? Is the assignment operator overloaded? If running this line results in an execution error, I'm totally lost as to where to find the problem.On the contrary, in C, the same line says explicitly what code is executed, without need for further context. If the code compiles, there is a single visible definition of a function named "f" and this is the code that is called.
I read much more code than I write. But code with lots of abstractions, like C++ with objects or templates, however elegant was to write, is a disgusting chore to analyze, understand and eventually fix (because the abstractions always fail). On the other hand, analyzing C code is pretty straightforward, even if it was a bit more verbose to write.
Indeed and I think this is the root of all the internet shouting on abstraction-heavy languages vs procedural/"simple" languages. A lot of folks that think in abstraction find it tedious and unsafe to deal with detail-oriented languages, while folks who are more detail-oriented find the abstraction disorienting and unsafe in their own way. Given that one group can't do away with another group, I hope we can all learn to work together.
People do fit into multiple camps... however, the camps definitely exist.
One of the several reasons I didn't go into academia, and one of the bigger ones overall, is that I could tell I wanted to split the difference between the "practicals" and the "mathematicians". And while this may not have been impossible, it was certainly at the very least a "high risk" move, because you end up with the support of neither camp, and there aren't enough people in the middle to make up for it.
- sometimes a practical problem benefits greatly from a well-designed high-level abstraction,
- sometimes a practical problem strictly requires low-level optimization.
And yes, it is totally fine to have one's inclination in general, pursue them to any level in their free time, or in some (but not all) academic research. Yet, if a professional software engineer consistently favours one of these motivations over adding value to the product, usually there are frictions in the workplace.
I guess you all know "let's rewrite it to Haskell" people, or ones using their favourite paradigm for everything, and against everyone. Or ones that squeeze 20% performance in a place of code that does not matter at all for the end user experience.
We need to disabuse ourselves of the notion that "professional" implies any kind of quality, or that the people who program without being paid money are doing a bad job of it, for that matter.
- People who enjoy programming because it’s mathematically beautiful (eg Haskell programmers)
- People who enjoy programming because they like reasoning about machines, and like mechanical sympathy (eg C programmers)
- And people who like programming because it can solve real problems for their users.
I got pushback here and elsewhere that lots of people fit into multiple camps - which makes sense. Maybe they’re better described as an ecology of values. But I also think there’s something real here. I worked in a consulting shop a few years ago and my boss came back from some front end development conference gushing about a talk he’d seen that I had to watch. The talk was a layman’s description of FP’s immutability approach applied to react. My boss had never heard of immutability before because it had never come up in front end web development circles. There’s lots of opportunities for our software to improve by cross contaminating all our best ideas.
[1] https://josephg.com/blog/3-tribes/