This morning, LinkedIn suggested this post in my feed:
I will never, ever use reduce in Javascript.
.
.
”Reduce is more elegant.”
”Real devs use functional methods”
”Loops are old-school.”
”It’s just one line, bro.”
These are not principles.
They’re just disguised best practices.
But here’s the truth:
You’re not writing code for applause.
You’re writing it to be understood.
👎 .reduce() hides logic in syntax
👎 It often obscures the intent.
👎 It sacrifices readability for cleverness
You know what doesn’t do that?
✅ A simple for loop.
Because when the code breaks at 2AM,
It won’t be the code that saves you.
It’ll be the line you can actually read quickly.
The first line makes it clear right off the bat that this is rage bait. And particularly low-effort AI rage bait at that. It’s an opinion designed to be so outrageous and unconventional absurd that more seasoned engineers can’t help but comment, which in turn maximizes the author’s reach.
Content like this goes beyond basic ignorance or lack of experience/expertise into a level of technical disinformation that we as an industry need to get better at identifying and discouraging.
The key piece of context that pushes this into disinformation territory comes with a deeper understanding of the declarative paradigm itself, which focuses on making code more readable by building up small, compositional abstractions that can result in an almost DSL-like experience at scale.
Most examples of declarative programming in JS/TS focus on built-in array methods, so if you look it up or ask AI you’re likely to get an example like this one, where let’s say a new array is created from an existing array by removing null values and converting the remaining numeric values to strings:
const arr = [1, 2, 3, 4, null, 6, 7, null, 9, null]; const newArr = [] as Array<string>; /* Imperative Approach */ for (let i = 0; i < arr.length; i++) { if (arr[i] !== null) { newArr.push(String(arr[i])); } } /* Declarative Approach */ const newArr = arr.filter((value) => value !== null).map(String);While built-in Array methods like .filter(), .map(), and .reduce() are declarative, examples like these don’t fully illustrate why declarative code is advantageous beyond just eliminating a few lines of code here and there.
The paradigm itself is more about increasing readability by writing code in a way where the thing you want to do happens by simply calling a method .doTheThing() rather than describing how the thing is done. Declarative methods can use loops and other imperative control flows under the hood, so a slightly better example would be rewriting an implementation that starts out like this:
🗒️ Note
You probably won’t actually have this kind of business logic in a real app, but it gets the idea across so hear me out.
While we do have our logic broken up into specialized functions, this code is not declarative because each function has to be told which Person is moving as a parameter, so we have to pass alice in as an argument every time. In a more functional approach, you could curry the move() function to get around this like so:
const move = (person: Person) => (speed: number, distance = 1, effort = speed) => { if (person.energy) { for (let i = distance; i > 0; i -= speed) { person.position += speed; person.energy -= effort; } } }; const aliceMoves = move(alice); const aliceWalks = (distance = 1) => aliceMoves(0.5, distance); const aliceRuns = (distance = 1) => aliceMoves(2, distance); const aliceJumps = (distance = 1) => aliceMoves(1, distance, 1.5); aliceWalks(10); aliceRuns(5); aliceJumps(4); aliceWalks(8);This is a lot better in terms of readability but not so much scalability because we still need discrete functions for each person we want to move. In order to make this code declarative, we need to go beyond simply updating Alice’s position and return an updated copy of alice:
interface Person { position: number; readonly name: string; readonly move(speed: number, distance: number, effort: number) => this; readonly walk(distance: number) => this; readonly run(distance: number) => this; readonly jump(distance: number) => this; } const alice: Person = { name: 'Alice', energy: 100, position: 0, move(speed: number, distance = 1, effort = speed) { if (this.energy) { for (let i = distance; i > 0; i -= speed) { this.position += speed; this.energy -= effort; } } return this; }, walk(distance = 1) { return this.move(0.5, distance); }, run(distance = 1) { return this.move(2, distance); }, jump(distance = 1) { return this.move(1, distance, 1.5); }, };Writing our code this way allows us to move Alice like this:
alice.walk(10).run(5).jump(4).walk(8);Like I said, you probably won’t actually shift a Person object’s position in a real app, but the same principles apply whenever you need a series of heterogeneous transformations (e.g., applying user profile updates, composing query filters, or processing form data.)
☝️ If this section was helpful let me know!
I’m considering writing up a more in-depth post that dives into this with more relevant examples; I might also do it as a 2-part series that builds on this and shows how I’ve used RxJS with React in the past to build web apps with declarative streams that have insane performance.
Now that we understand what declarative methods like .reduce() are all about, we can start to get a better sense of why this kind of content isn’t eligible for the same benefits of the doubt we would typically afford the author of the rage bait from earlier, who has just under 3 years of experience at this point.
Given the examples above, we can see how the 👎 points being labelled as such is misleading. Except for the last one, the points themselves are fine but should be 👍 instead. Hiding logic in syntax is a feature of declarative code not a bug. It is, in fact, the point.
The only time I’ve seen .reduce() kinda sacrifice readability for cleverness is when it’s used to pipe async functions sequentially, like this:
asyncFunctions.reduce( (resolved, next) => resolved .then((result) => next(result)) .catch(console.error), Promise.resolve(), );In most cases though, it’s used to build objects from arrays in situations where Object.fromEntries() isn’t an option.
The final two sentences would normally get a pass as well (albeit with a raised eyebrow) but given how sus his whole post is already, I’m not inclined to start now. Anyone who’s actually had to respond to a production incident at 2am can tell you it’s not simple code that saves you, it’s your recognition- which is faster than recall- leveraging the mental shortcuts you’ve built up.
In the beginning (of people teaching themselves to code,) we had books. Fat. Ass. Books. My dad had a book somewhere on one of his bookshelves on C++ that’s 30 years old now and girthier than my whole fist. Expert software engineers were the people who literally wrote the canonical book or manual on the technical subject of their expertise, or they made a name for themselves as the creator of that subject. Plenty did both.
Even in the 2010s, posting something like this on your Medium blog intentionally as an aspiring professional would be akin to shouting “I’m just an imposter, don’t hire me!”
The tradition of sharing knowledge in this way meant that people positioning themselves as rising stars still had to demonstrate a solid understanding of more sophisticated technique, or at least an eagerness to learn.
Aimee Knight and Lydia Hallie come to mind as engineers who stood out to me around this time as particularly admirable for their ability to bring others along with them as they entered the field and grew. As Juniors they had no problem talking shop with seasoned experts. If you take a look at Aimee's blog today, it’s as technical as one would expect from an expert software engineer. Lydia’s technical expertise and her desire to share it continues to speak for itself.
Bootcamps have flooded the industry with new Engineers, especially on the frontend. While the idea that this number doubles every 5 years is more of a myth these days, data from the most recent Stack Overflow Annual Developer Survey does show that the average Frontend Engineer has less than 8 years of experience.
I’ve definitely noticed the impact of this especially over the past few years; at least the last two organizations I've been at have had ICs under Staff that were a standard deviation below what I’d typically expect in terms of technical expertise at every level. And it’s not just me who’s noticed! In one of these roles this was a widely acknowledged fact amongst the Staff+ group.
At first I chalked it up to that organization having scaled too rapidly, but seeing this pattern across multiple organizations consecutively has made the talent gap in the industry crystal clear.

With the advent of AI upon us, Juniors by today’s standards have been all but replaced, along with some contractors who do team augmentation as an extra pair of hands. We don’t need new people who write code without having any idea how it works because we have AI for that now! And AI is at least much, much faster.
But companies aren’t just going to stop hiring Juniors. ICs get old after a while, and expensive, and become consultants or go into management or leadership or retire early. We still need new folks to start somewhere, so the job description needs a revamp. The problem for recent grads is that the job market, already oversaturated as it is, is insanely bottom-heavy.
The intensity of this competition effectively raises the bar and, I believe, will eventually close the talent gap. The demand for experts is decreasing, but the value of expertise itself is actually increasing. What I would never tell a candidate I’m passing on is that you can have an Ivy League CS degree and 5 FAANG/MAMAA internships but there’s a line of folks out the door who are just as eager to learn and capable of doing so just as quickly, so if you’re only as technical as your AI then you aren’t going to yield the best return on investment.
💭 BTW
If you do actually have an Ivy League CS degree and 5 FAANG/MAMAA internships you’re gonna be fine. Eventually.
Back to the LinkedIn post at the top, it should go without saying at this point that dishing out a blatantly bad technical opinion is probably a bad idea. It’s not that it won’t work- it unfortunately does work to a certain degree or else this guy wouldn’t be doing it.
Not sure how many followers he added but his comments were riddled with Seniors calling him out as a bad engineer (“sounds like a skill issue”). And that was unfortunately the whole idea. So I threw him on my blocklist, and I’m sure I wasn’t the only one.
But if I’m looking at the trade-offs, in the long-run, building an audience at the cost of connecting with more technical peers who strive to make a name for themselves by actually knowing what they’re talking about doesn’t seem worth it. These folks will someday surpass you both in talent and pay, if they aren’t already ahead. And this will lock you in as Yet Another Engineer Who Only Writes About Soft Skills, because the audience that you do have are going to be chalk full of vibe coders and Product/Growth Developers.
Look, I’m not even saying don’t ever use rage bait. We all do it sometimes; I have opinions in my Notes that, while genuine, definitely come across as rage bait-ey. What matters is that these are opinions I’ve formed as a result of a decade of industry experience; I’m not contriving them just to increase my numbers.
If you must resort to technical hot takes on LinkedIn, at least use The “Prove Me Wrong” variant so you don’t make yourself look like an asshole who is unable or unwilling to take feedback in code review.
🙏 BTW my subscribers are the best, my previous post on Aligning Components with Custom HTML Attributes achieved an 80% open rate and I can’t thank each of you enough for taking the time to read it!
✍️ (In Progress) How to maximize correct assumptions and create a pit of success
✍️ (In Progress) How to implement session management middleware the right way
🏗️ (Outlined) Why we use musical scales in design systems
Any thoughts on what else you’d like to see? Leave a comment or hop into chat and let me know! I’ll be on vacation most of this month but have plenty to dive into as soon as I’m back.