Here's another one of those I-shouldn't-have-to-write-this articles. In the past, I've ranted about tech evangelists and mindless fanboys. But if we strip out some of my bombastic terminology, what I'm really fighting against (hopelessly) is the emotional and illogical process we often undertake when we endeavor to assess new technologies.
To aid in this age-old tech quandary, I'm introducing a radical new tool: I call it a Zenn Diagram.
[NOTE: If you think these diagrams look an awful-lot like those silly things called "Venn diagrams", I assure you this is nothing of the sort. Venn diagrams are old and stooopid. You don't wanna be stooopid, do you??]
Unless you've only been coding for a few months, you've probably had this experience:
Your team is using some Gnarly Old Stable Technology (GOST). It's not without its faults. But it works. Just as importantly, you're well-versed in GOST. Your entire team has solid experience with GOST. If you're being honest with yourself, you probably like GOST.
Then something new comes along - a Glorious New Awesome Technology (GNAT). Because you're at least somewhat aware of "industry trends" and you try to keep abreast of new advancements when they suit you, you've heard of GNAT. Heck, you've probably even downloaded the NPM GNAT package and played around with it in your local environment. You may have even heard some "thought leader" singing its praises at a recent convention - or watched an engrossing video about it on YouTube. But you didn't see anything so earth-shattering that you felt the need to adopt it into your own projects.
But you probably don't work alone as a renegade dev. You've probably got other team members, and some of them may be genuinely excited(!) about GNAT. They start talking about it at work. They start pushing for it every time you need to spin up a new feature. They start sneering dismissively any time someone recommends writing more code with GOST. If they've really caught the "bug", they may even be agitating to rewrite some-or-all of the legacy code using GNAT.
This is the moment when things can get... uncomfortable. You're no Luddite. You genuinely want to be open to new techniques. But you've been around the block enough to know that "new" is not always "better". But once that GNAT starts buzzing around your dev team, it can be hard to squash it. And in the back of your mind, you're not even sure if you should be trying to squash it.
But if you simply ignore a GNAT, it rarely just goes away on its own. Even worse, the longer you deny the presence of the GNAT, the more likely it is that other team members will start seeing you as a GOST - some stodgy, old, close-minded codger desperately clinging to the tools you learned when we were all using dial-up.
Thankfully, there are logical ways to address this conundrum. Specifically, a good Zenn Diagram can help to remove the emotion from the debate and help GOSTs and GNATs assess the technology based upon empirical factors.
Let's look at some common Zenn Diagrams:
Cynics might scoff at this diagram. Surely, any new technology won't offer less functionality than its predecessor, right??
Granted, the diagram above is probably relatively rare. The developers of GNAT certainly thought they were giving us some kind of "new" functionality. But I have seen scenarios where the new "flavor of the month" offered no real improvement whatsoever, while abandoning key features of the GOST. In these scenarios, the drive toward GNAT is typically based on broader industry trends, where GOST uses some kinda "ugly" pattern, and GNAT complies with the hot, cool, new pattern.
In this kinda tech debate, it should be relatively simple to present a reasoned argument that, while GNAT may indeed feel "cool", it's not practical to even consider abandoning GOST. I say "should" because you can never fully account for the power of fanboys who've glommed onto GNAT and simply won't let go.
If you're facing this kinda Zenn Diagram, and the rest of your team still wants to jump to GNAT, you might seriously want to consider a new gig. Even if you can choke down your disgust, it's only a matter of time before this GNAT is challenged by yet another, newer GNAT, and then you'll be going through the cycle all over again.
Although this situation may seem rare - unthinkable, even - I've found that foolhardy decisions like this can be made on teams that simply have too much freedom (yes, that can be a thing) or too much time on their hands.
As stated above, it's relatively rare to find a GNAT that offers no new benefits, while orphaning a huge chunk of the GOST's benefits. However, I don't personally feel it's at all rare to run into a situation like the Zenn Diagram shown above.
In this scenario, there's not much that you did with GOST that you can't also do with GNAT. So that's a huge argument in favor of GNAT, right??
The problem is that there's not much that you can do with GNAT that you couldn't already do with GOST. In other words, switching to GNAT is mostly an exercise in chasing trends.
For example, imagine that functional programming is your GOST. And at the latest big programming conference, some charismatic rebel introduced an exciting new paradigm - conceptual programming. He even announced an entirely-new language called ConceptScript (CS) that enforces all the core tenets of conceptual programming.
Some of your colleagues attended this conference and whoa boy! are they excited! Functional programming is suddenly stooopid. Conceptual programming is suddenly the only way to write applications faster and bug-free!
You're genuinely curious, so you spend a good bit of time investigating this bold new "conceptual programming" technique. But the more you look at it, the more it seems like CP is doing nearly all the things you've been doing - for years - with functional programming.
Even worse, the more you inspect CP's core features, the more you find yourself thinking that this isn't a "better" way to do FP. It's just a different way to do everything you're already doing in FP.
These kinda Zenn Diagrams occur at the onset of foundational shifts. For example: moving from OOP to FP. There's not any single thing that you can do with FP that you can't do with OOP. Conversely, there's not any single thing that you can do with OOP that you can't do with FP. And yet, over time, one gains favor - and one gets relegated to the "stodgy old guy" bin.
These diagrams can lead to some of the nastiest Holy Wars - because they tend to occur when entire industry-wide practices are evolving. Is FP "better" than OOP? I tend to think so. But anyone who's thinking even somewhat rationally about it will probably admit that OOP isn't inherently "wrong" and FP isn't inherently "right". They're just two (fundamentally) different approaches to solving the same problem.
In the hypothetical I gave above, should you suddenly drop all of your FP development to embrace a radical departure to "conceptual programming"? The answer is a clear and unequivocal:
Probably not - but keep your eye on the trends.
Just by looking at the Zenn Diagram above, it would appear that the latest GNAT offers few improvements at the price of massive time-and-effort for new training and, in some cases, rewriting existing tech. Then again, such tectonic shifts do occur. And when they do, you don't wanna be left as one of the last shops still cranking out GOST code.
The clearest advice I can give is to hold the line (for awhile, at least). When the changes do not provide clear-and-immediate benefits, you probably don't wanna be on the bleeding edge of that trend - especially because some of these trends fizzle out.
But you don't want to become a programming dinosaur, either. Even if GNAT offers few tactical advantages, but the trend is sweeping through the industry, there can be a solid business case for, eventually, switching to the GNAT.
Some technologies truly offer everything we had with their predecessor - plus a huge buncha cool stuff! That would seem to be a pretty clear win for the GNAT, right??
In this diagram, it's clear that GNAT offers a good deal more functionality, while sacrificing almost none of the GOST functionality. But it can be foolhardy to evaluate this diagram based on nothing more than the net difference.
For example: Let's imagine that GNAT now allows us to
makeToast(). And it allows us to
makeJelly(). And it provides a native
HipsterToastCafe primitive that allows us to spin up cutting-edge, over-priced, artisinal applications with little-to-no effort. So that settles it, right? I mean, why wouldn't you switch to GNAT??
Well... just because the GNAT provides new tools, and just because it (theoretically) supports our stodgy old GOST tools, doesn't necessarily mean that it's worth making the switch. If you've never before had a need to
makeToast() and you couldn't care less about
makeJelly() and you can't imagine how you'd possibly use the
HipsterToastCafe primitive, then it's entirely possible that adopting the GNAT will be a massive waste of time and money (and if you're not keeping score at home, time is money).
Like the Trend-Chasing Diagram above, it's entirely possible that, at some point in the future, you might find yourself migrating to the GNAT. You might end up doing this, even though you have no desire whatsoever for that magical
makeToast() method. But switching is not a trivial matter.
And if you can't see an immediate benefit from the GNAT's (supposedly) revolutionary features, there's nothing wrong with sticking to your guns for awhile and arguing in favor of the GOST. Even if that makes you look like a relic.
If all parties are being honest about the decision (and... they rarely are), the diagram usually looks more like the one above. That's because advancements are usually incremental. The GNAT often allows us to do most of the things we could do with GOST. Similarly, the GNAT usually provides a handful of intriguing new features. It also typically orphans at least some of our beloved GOST features - or it ports them over in a manner that is painful for those who've grown accustomed to GOST.
So how do we evaluate this kind of diagram?
Look carefully at the features that are supposedly shared by both. When a new technology is introduced, its purveyors will typically claim that you can do nearly all of the things that you could do in the old technology. But just because there's some way to do the same thing, doesn't mean that it's desirable, or even feasible.
Be honest about the "new" GNAT features. Just because they're "new" doesn't necessarily mean that you need them - or that you even want them.
Be honest about any old GOST features that are being orphaned. In my experience, the GNAT fanboys will dismissively scoff and claim that you don't need those old features anyway. They get so caught up in the glory of their GNAT, that they downplay anything you could previously do with GOST. (NOTE: If you're advocating for the GNAT, and you feel tempted to brand the GOST's lost functionality as silly or unnecessary, this is a fabulous way to identify yourself as a douchebag.)
IMHO, decisions like these are harmed by evangelistic ravings - on either side. And they're aided by honest investigation by all parties. Don't cling stubbornly to the GOST. Don't squeal with glee any time anyone even mentions the GNAT. Don't get all snotty just because someone has a hard time seeing the benefits of GNAT, or professes their preference for GOST.
Assuming that the "shared" functionality in the center of the Zenn Diagram is truly available in both solutions, it's helpful to ask everyone some hard questions like:
What are we gaining with the GNAT? Is it really a critical improvement? Or is it just... new?
What are we losing with the GOST? How painful will it be to craft GNAT equivalents? How does this affect legacy systems? Is it possible to do a wholesale migration (unlikely). Or will this lead to some indeterminate period (probably, years) where we're forced to support both GOST and GNAT solutions?
I've made a lotta vague references to things like "features" and "functionality". But it's critical to remember that this is rarely based simply upon the features that are baked into any particular technology. In other words, in a "perfect" analysis, the Zenn Diagram should account for ALL THE THINGS!!!
For example, let's consider the Trade-Off Diagram from above. If those circles represent nothing but the raw functionality of the competing technologies, then that diagram is not very helpful at all.
Imagine that you're truly considering a switch to that hot new "conceptual programming" paradigm - and the associated ConceptScript language - that many of your devs are raving about. Let's also imagine that you sat down and did a deep dive on all of the inherent features of CS compared to that old, funky JS that your team's been using for years.
At the end of this analysis, you've found that CS really does provide some cool new features that you just can't get in JS. CS allows you to do most of what you were already doing in JS. Furthermore, you've determined that anything you're losing from JS really isn't that big'ah deal.
So it's settled. You should switch to ConceptScript, post haste, right??
Not so fast...
If you've got a dozen experienced devs on the team, and they all have years of expertise with JS, and they all have zero expertise with CS, then that GOST circle should probably be a bit bigger.
If the marketplace for new JS devs is massive - and the marketplace for new CS devs is... nearly nonexistent, that GOST circle should continue growing.
If you rarely get the chance to spin up true "green fields" projects, and all of your "new" dev will just be adding/expanding features in the legacy JS codebase, that GNAT circle should be shrinking.
In fact, even if all the tangible features of the languages are properly taken into account, and even if the GNAT seems to be a true "net positive", you may still find that your Zenn Diagram looks like this after taking into account all the broader factors from your team and your environment:
You may be thinking, "This dude just cranked out several thousand words in a programming blog to talk to us about... Venn diagrams??"
No! They're Zenn Diagrams!
Seriously, though. I realize that a Venn diagram isn't exactly a revolutionary new idea. Personally, I don't care if you never utter the words "Zenn Diagram" again.
What I do care about is the fact that, far too often, we base these decisions on emotional factors. Or we base them on flimsy anecdotal evidence.
Dick worked on a TypeScript project in 2013 that was an absolute nightmare. So now he tries to shout down anyone who dares to even suggest TS in any future projects.
Dick follows this guy called "Thaught Laider" on TikTok. And Thaught swears that functional programming is dead and conceptual programming is the wave of the future. So now, Dick simply won't shut up about it.
Dick desperately wants to tinker with NestJS. So now he makes snide little comments under his breath any time we spin up a new Express endpoint.
Don't be a Dick.