DEV Community

loading...
Cover image for JavaScript's Functional Programming Mythology

JavaScript's Functional Programming Mythology

bytebodger profile image Adam Nathaniel Davis Updated on ・9 min read

JavaScript has acquired quite a mythology around itself. Like any good mythos, some of it's based in truth. Some of it's... not. Some take it as gospel. Some look at it skeptically. But the longer the mythos lives on, the harder it becomes to separate fact from fiction.

I'm talking specifically about the mythology that's grown up around JavaScript & Functional Programming.

Any mature technology goes through stages - fads - where people parrot catchphrases and slogans. JS is not unique in this regard.

PMs and dev managers have pull-strings in their backs, and every time you pull them, they say "Agile!" When I first started programming, the snooty senior types couldn't get through a paragraph without mentioning: "abstraction", "encapsulation", "inheritance", or "polymorphism". In the 2000s, no one believed that you could program a Hello World demo without making thorough use of "MVC".

And the JavaScript community can't even manage to cross the street unless they click their heels three times while chanting the JS Buddhist Mantra: "There's no programming like Functional Programming."


Alt Text

Technological Incantations

Every sector of tech experiences trends. Does this mean that every trend is part of a deeper mythos?? Not at all.

When I talk about a "mythos", I'm referring to a handful of key features:

  1. The mythos is often heralded by a smaller group of generally-acknowledged "thought leaders".

  2. There's often disagreement about what the mythos actually means.

  3. Many people tend to blindly invoke the mythos's name - as though merely speaking it is the equivalent of implementing the technology (and solving hairy, real-world problems).

  4. A mythos acquires followers (which I often refer to as: "fanboys"). These followers can be outright caustic in their unyielding support for the mythos - and their aggressive dismissal of alternate solutions.

  5. Alternate histories are often crafted to imply that the mythos "has always been" and "will always be". References are made to the mythos in historical contexts that never previously made any sense.

  6. The mythos's overbearing admirers can often obscure the fact that the mythos has many strong factors in its favor. In other words, if you're a fairly level-headed, empirical thinker, the fanboys can actually sully the reputation of the very thing they're fawning over.

Now look back over these points and tell me whether you personally think any of them can apply to the overall paradigm of Functional Programming? Especially as that paradigm is applied within the JavaScript community??


Alt Text

Some Quick Disclaimers

This is no s**tpost about FP. I'm one of the many, many people over the last 10-or-so years who've started to openly rail against some of the misguided dictates of OOP. As someone who started his career on the "server side", I've found frontend JS development to be downright refreshing.

Although it's taken me awhile, I've been slowly opening my eyes to ever more possibilities that exist in FP. If I'm being honest with myself, I become even more of an FP fanboy nearly every day.

But even though I'm enjoying this little journey, that doesn't mean I'm blind to the ever-growing sheen of hype that's been buffed onto the surface of FP. I don't know if there's a single aspect of FP that I don't like. But I still can't help but to occasionally roll my eyes at the ridiculous love that gets heaped onto the latest "Paradigm du Jour" that we now call "Functional Programming".

Let's explore some of the silliness that I currently see around FP...


Alt Text

Whatever You Want It To Be

FP is the Rorschach Test of the programming world. Ask 10 different programmers to define FP and you'll likely get 10 different answers. And those answers will say far more about those giving the answers than they will about the true meaning of FP.

At the risk of disparaging my own colleagues, I gotta say that FP's amorphousness is especially galling amongst some in the JS community. If you're one of the "cool kids" in JS, you spew endlessly about the mythical powers of FP. But to hang with those "cool kids", there's no entrance exam. All you gotta do is sing the praises of FP and they'll teach you the secret handshake.

If this sounds like I'm ruthlessly targeting some faceless crowd of FP supporters, please believe me - I'm not. Because simply defining Functional Programming isn't the elementary task one might assume it would be.

If you have a taste for programming theory and no social life (like... me), then spend a few nights going down the Google rabbit hole of "What is functional programming?"

Seriously. Give it a spin. I'll wait. Till next week. When you finally get exasperated and crawl back.

I can find hundreds of articles online that all give fairly consistent answers to, "What is object-oriented programming?" But when I try to do the same for FP, it's maddening to see the minute fractals I get pulled down from one site to another.

I'm not claiming that there is no definition of FP. I'm just saying that, if you spend enough time reading enough sites, and talking to enough programmers, and going through enough tutorials, it can be bewildering to see how much contradictory information you find.


Alt Text

Lies, Damn Lies, and Blind Faith

Rather than trying to define exactly what FP means, it may be more expedient to discount what others believe that it means. So here is a sampling of the effery that I routinely hear about FP (especially as it applies to JS).

All of my code is now in functions. Because I love Functional Programming! And this makes my code "FP"!


Umm... no. I'm sorry. This isn't even close to being correct.

Granted, it's a perfectly logical conclusion. It's one that I think most programmers have made at some point early in their careers. And on the surface, it seems... obvious. Right???

But as simple as it would be to state that "my code is in functions, and therefore this is Functional Programming," the simple fact is that most of FP's definitions make it clear that this isn't even vaguely correct.

I've learned (from experience, or by falling inline behind my more-senior programming peers) that OOP sucks. And I'm not even trying to write OOP. Therefore, I write FP.


Honestly, this "definition" isn't that far off from the truth. At least, it's not that far from the "truth" - as it's practiced in most dev shops.

You see, the programming world seems to be waking up from a long, hazy nightmare that we all knew as OOP. At the same time, there seems to be this irrational exuberance targeted on that shiny new prize known as FP.

So... in many scenarios, I've seen FP kinda loosely defined as "everything that's not OOP". I truly think there are some devs who believe that, if they're not writing classes and instantiating objects, then they must be writing FP.

I'm a JavaScript developer. And JavaScript is a Functional-Programming language. Therefore, I'm an FP-coder.


OMFG. STOP IT. Seriously. You have no idea how many times I've heard-or-read this blatant IDIOCY in the last several years.

At first, I brushed it off as a harmless nugget of misinformation. But it's become so pervasive that I'm starting to lose all patience for it. I don't even know where it originated. But at this point, I really feel like anyone spewing this "JS is an FP language" garbage is borderline-harmful.

But don't take my word for it. This is from what is, IMHO, the best general-purpose JavaScript reference site on the web - MDN (emphasis: mine):

"JavaScript is a prototype-based, multi-paradigm, single-threaded, dynamic language, supporting object-oriented, imperative, and declarative (e.g. functional programming) styles."


You may like the idea of writing FP-style code in JS. And JS certainly supports that. But that doesn't mean that JS is, inherently, an FP language. Nor does it mean that you're writing FP-style code merely because your codebase is written in JS.

If that's not enough evidence for you, let's look at what is-or-is-not an object in JavaScript:

  1. An Array is... an object.
  2. A Function is... an object.
  3. NULL is... an object. (Yeah. I know. Wrap your head around that one for a minute.)
  4. A Set is... an object.
  5. Most of the "standard functions" we're accustomed to using in JS are part of... the global object.
  6. I could go on...

Whether JS fanboys want to admit it or not, JS is downright rotten with objects. The language is practically based upon them.

Can you write functional code in JS? Absolutely. Is your code functional because it's written in JS??? Hell, nawwww. If you want to prove your FP chops by writing in something that's truly an FP language, take a look at Elm. (There are others, obviously. That's just the first one that pops into my head.)


Alt Text

A Cruel Taskmaster

I've also noticed that many of the FP fanboys, who blindly sing its praises, don't seem to fully appreciate what FP means. Or what kind of restrictions it would place on their code if they wanted to be truly FP-compliant.

Do you know what a "monad" is? I don't mean: Have you ever heard of that word before? I mean: Can you explain what a monad does? Can you write one in your own code?

I realize that there will be some people reading this post who fully understand monads. But I can guarantee that most other people - people who claim to love FP - cannot actually write a monad, or explain its purpose, to save their life.

Do you like loops? You know... for loops. while loops. forEach loops. Guess what?? In "basic" FP theory - they don't exist.

And while we're on the subject of "core FP principles", let's talk about side effects and immutability.

I've heard many FP acolytes talk lovingly about avoiding side effects and enforcing immutability. And then... I look at their code.

You see, I'm all for the theory of minimizing side effects and pursuing immutability. But when you start writing your app - your real world app - you might find these concepts a bit more difficult to adhere to. These concepts sound grand - in theory - but when you're writing, you know... real apps that people will use, it's pretty damn difficult to religiously adhere to these concepts.


Alt Text

React Hypocrisy

If I sound a little riled-up about this whole "functional programming issue", maybe that's because I'm a React developer. Over the last several years, I've watched as a virtual horde of FP fanboys have overrun the entire infrastructure of React. They came in with their torches and their pitchforks. And they tried to yell down any other React/JS dev who dared to question their holy FP purity.

And then... they gave us components like this:

export const MyComponent = () => {
  const [mySideEffect, updateSideEffect] = useState('love me some FP');

  const callTheFrigginGLOBALStore = () => {
    // let's make some SIDE EFFECTS!!!
  }

  const callTheAPI = () => {
    // LOOK!!!  MORE side effects!  YIPPEE!!!
  }

  return <div>Do some display here...</div>;
}
Enter fullscreen mode Exit fullscreen mode

To be absolutely clear, I write components like this. I have no real problem with code like this. My only "problem" is that the FP fanboys will look at the code above and begin pleasuring themselves over their amazing Functional Programming skills. And they feel compelled to do this because... everything is, technically-speaking, in a function.

Yay???


I'm not exaggerating when I say that some React FP-fanboys truly have no self-awareness about code like this. If I were to put equivalent code into a class (egads!!!), they'd happily yell me down for using those horrible, unconscionable OOP constructs. But they can write code exactly like this, which is (technically), entirely encapsulated in functions, and they'll strain an oblique trying to pat themselves on the back over their beautiful "FP" code.


Alt Text

Own Your Dogma

So what's the point of all this???

I'm not trying to destroy your dreams of Functional Programming bliss. Hell... I share many of those dreams.

I'm not trying to hold you to any puritanical standard of what is-or-is-not "FP compliant". Show me a 100% fully-FP-compliant app, and I'll show you an app that's probably never been deployed anywhere.

I'm just encouraging you, me, all of us, to own our own dogma. Understand that OOP is not The Great Satan. FP is not Our Lord And Savior. Plain ol' imperative code is - a thing. In fact... there is no single programming paradigm that can, by itself, solve all of our challenges.

Resist dogma. Resist mythology and mindless koans. Think for your damn self. Whether you're right-or-wrong - in the end, you'll sleep much better at night.

Discussion (27)

pic
Editor guide
Collapse
merri profile image
Vesa Piittinen

I think the awful part of the Rise of FP is how it keeps happening over and over again right now. My professional worklife has lasted only seven years, but I'm experiencing a second wave of it. It first happened with CoffeeScript: if you found someone using CS it was very likely they were also very "fond" of FP, and had a very bad attitude towards everything else.

These days we have TypeScript. It is better and more usable tool than CoffeeScript ever was (you can actually read what you wrote the last time!), but somehow it seems to have a link to this same kind of fondness to FP. It is a bit odd as there is nothing FP about TypeScript, but I guess it goes with how people want to use new things.

The thing about React's hooks is that you can clearly see it being helpful and easier to reason about than the old classes. With classes you didn't have as clear path managing state and you just had to know what to do in constructor, componentDidUpdate and componentWillUnmount. It might be an interesting exercise to try and make a custom wrapper over the class logic that would let you make something similar to hooks; not exactly like hooks, instead just make it prettier and easier to reason about state.

Now that was a side step. What I was thinking originally... ah yes, hooks. I guess that pattern made more people aware of FP and thus caused a new additional spike to it, and here we are with another wave of newly found FP enthusiasts that give more credit and value for it than it deserves. Especially if they're at the beginning of their programming career.

It is very troublesome when this happens to individuals who are loud speakers with strong opinions, and no ability to listen.

Collapse
bytebodger profile image
Adam Nathaniel Davis Author

I guess that pattern made more people aware of FP and thus caused a new additional spike to it, and here we are with another wave of newly found FP enthusiasts that give more credit and value for it than it deserves. Especially if they're at the beginning of their programming career.

FWIW, I'll state again that I use Hooks. I write code just like the sample shown above. I have no problem with the general concept of Hooks. However, I do have a bit of annoyance over how I believe Hooks came to be.

The crowd that believes FP === puttingYourCodeInFunctions && allCodeInsideFunctions === FP was getting themselves in a tizzy over "standard" class-based components in React. On one hand, they sang the praises of "pure" functions and desired to get all of their React code into functions. On the other hand, there was much about React that you simply could not do inside a function declaration.

So they "solved" this by creating Hooks. Now, all their code could be inside those beauteous functions. And they never had to write another one of those scary class keywords again. And they could feel content in the (misplaced) knowledge that they were now truly writing in an FP style.

Collapse
bytebodger profile image
Adam Nathaniel Davis Author

It is very troublesome when this happens to individuals who are loud speakers with strong opinions, and no ability to listen.

This. Sooooo much this!

This is really my entire point - about any mythology.

Collapse
seanmclem profile image
Seanmclem

they click their heels three times while chanting the JS Buddhist Mantra: "There's no programming like Functional Programming."

Such an emotional stance. You mad? Who cares how people Define things? Everybody's different, and I think that's what's great about JavaScript. It's flexible enough to be however you want to use it.

Collapse
bytebodger profile image
Adam Nathaniel Davis Author

Such an emotional stance. You mad?

Nope. I'm a pretty-chill guy.

Who cares how people Define things? Everybody's different, and I think that's what's great about JavaScript. It's flexible enough to be however you want to use it.

I don't care about how people define things. Define them however you want. I only care about how people interact with each other, after they've created their own, private, isolated, disconnected definition of things.

If you want to call the orange thing in your hand a banana, then... great! You do you, boo. But too many times, in tech, I've seen someone decide that the orange thing is now a "banana" - then proceed to use passive-aggressive techniques against anyone else on the team who doesn't also want to call it a banana.

Collapse
pentacular profile image
pentacular

Functional programming is about leveraging invariant relationships.

It is their invariance which gives benefits, since it means that there is no change in the system.

Which means that time must be modeled explicitly in a functional system.

Not to be confused with procedural abstraction, which leverages decoupling implementation and interface by using procedure calls.

Collapse
bytebodger profile image
Adam Nathaniel Davis Author

This is yet another definition that I've heard for FP.

To be clear, I'm not saying that it's in any way "wrong". I'm just saying that FP tends to evoke a lot of different definitions from a lot of different people.

Collapse
pentacular profile image
pentacular

I think it's broadly misunderstood, and there is usually a conflation of 'functional programming' with a 'functional programming style'.

The functional programming style is generally procedural abstraction, with an aspiration to avoid side effects, but misses the fundamental qualities of functions.

But without understanding the fundamental qualities of functions, it's hard to know where and when it's appropriate, which leads to a general devolution into superstition and mythology. :)

Which is why I always bring it back to time -- it isn't time invariant, it isn't a function.

Once you understand this, everything else flows naturally from this fundamental property.

Thread Thread
bytebodger profile image
Adam Nathaniel Davis Author

You have explained this extremely well. Excellent points - all of them.

Collapse
functional_js profile image
Functional Javascript

Interesting writeup there Adam.

Where are you meeting all these people? LOL
I've never met people like that.
But I sense some creative histrionics.

It's true there are misconceptions about FP.
It's just that we use it to different degrees.

Though my username is "Functional Javascript", I use probably less than 5% of what is considered "pure" or the "mathematical" FP. (I'm a minimalist)

  • No monads
  • No monoids
  • No applicatives
  • No functors
  • No algebraic type
  • No communicative this, or associative that
  • No category theory
  • on and on.

You could analysis mine—or anyone else's software systems—for those attributes, and find them. But I don't think in that way in order to build systems.

One could say I think in building blocks.
We're building waterways (functions) to maximize the flow of the water (data).

To me FP means two things...

  • Thinking and designing in free functions, not in objects
  • Not intertwining data and behavior

(actually, those are kind of one thing ;-)

My goal isn't to be or aspire to be Functional.
It's to try to build systems as simply, fast, performant, robust, secure, readable and changeable as possible.

Everything in life we should split-test.
My "control" piece (or paradigm) is the functional approach to system building.

P.S.
Keep up the good work.
Let's all keep pondering.

Collapse
bytebodger profile image
Adam Nathaniel Davis Author

Where are you meeting all these people? LOL I've never met people like that. But I sense some creative histrionics.

Have I ever taken any creative license?? Sure. But also keep in mind two things: 1) I've been doing this now for almost a quarter century and I tend to be a bit restless in my jobs - so I'm not typically in one place more than a year or two. This means that I've met a lot of people. 2) When I talk, in general, about some of these people, I haven't met many of them in person. But that doesn't mean they don't exist. Some nights I spend hours watching/listening to programming presentations on YouTube. Or reading programming blogs. Or sifting through the new-feature debates in various open source communities. So while I haven't met all of these people in person, I'm very confident that there's a lot of dogma out there.

As for your general approach to FP, I think we're almost perfectly aligned. I'm genuinely a fan of FP concepts. And I keep striving to be a little more FP in my coding. But I don't get hung up on the theory.

Write small standalone (atomic, even) functions that "do one thing, and do it well". Minimize dependence upon global data or any data outside the function scope. Simplify application "flow". Craft features that can be independently tested. I could go on...

I truly believe that FP's greatest strengths lie not in the rigid application of dogma. It's more - as you put it - aspirational.

Collapse
functional_js profile image
Functional Javascript

I think a good way for one to introspect on how they approach designing systems, is to reflect on what one does NOT use.

It helps answer the question, "How minimalist am I?"
Or, how "As simple as possible but no simpler" am I?

I created a list of "program constructs I do not use" here...
dev.to/functional_js/what-subset-o...

Thread Thread
bytebodger profile image
Adam Nathaniel Davis Author

I agree that this a very interesting way to quantify one's approach. With almost any language, there are far more tools / keywords / packages / frameworks / etc. available to us than we would ever use (or ever want to use). The tools you purposely choose to avoid probably say a lot about your coding style and your priorities when crafting solutions.

Collapse
thepeoplesbourgeois profile image
Josh • Edited

I thought the Javascript mantra was this.method = this.method.bind(this);

I mean, it's even got restraint and self-flagellation

Collapse
iquardt profile image
Iven Marquardt

On a technical level I disagree with some aspects of what you say. But on a more pedagogical/sociological level I am with you a 100%:

Own Your Dogma
(and overcome it eventually)

Loving it!

Collapse
bytebodger profile image
Adam Nathaniel Davis Author

Thank you for the feedback!

And yeah... on a technical level, there's certainly some detail in this post to quibble over. But then again - that would kinda be missing the point. :-)

Collapse
iquardt profile image
Iven Marquardt

I'm not there yet, beyond dogma :D

Collapse
siy profile image
Sergiy Yevtushenko

Just plain brilliant!

Collapse
mattk profile image
mattk • Edited

What do you think about wrapping the component with an HOC that does all the side effects so that the component remains a pure function?

Collapse
bytebodger profile image
Adam Nathaniel Davis Author • Edited

I'm not honestly certain whether your comment is sincere or sarcastic. But I think the question evokes some interesting questions for FP methodology so I'll try to answer it sincerely. (And if your comment was sarcastic, then, well... you got me.)

As I tried to make clear in my article, I'm actually an ever-increasing fan of functional programming. And I think there's a ton value to be had in learning it and striving to make your code more FP-compliant (even if JS is NOT inherently a "functional programming language").

So from that perspective, there's absolutely some value to be had in creating those HOCs that wrap all of those nasty side effects and, in turn, leverage the pure functions. My "official" response to that approach is... do it - until it's annoying to do it.

You see, it's all fine-and-good to strive for pure functions. And, in general, I encourage the thought process that leads you to look at every function and think, "But... how can I make this pure???" But there are limits...

This is probably a subject for a separate blog, but if you've been programming for long enough, you might understand what I mean by "limits". When you start trying to think in FP terms, you will probably find that that there are some - or even, many - of your functions that can easily-and-swiftly be converted into pure functions. (In React, another way to think of these functions is as controlled components.) But there's probably a batch of other components that are not so easily converted.

I can tell you from experience that, when you start going down a theoretical rabbit hole (like: the "rabbit hole" of pure functions), it's extremely easy to follow that rabbit hole too damn far. In other words, there are some functions that, due to their very nature, are just damn-near-impossible to convert into pure functions.

When you find such functions, you often need to decide whether you want to A. redesign the whole damn app (which is almost never a good idea), or B. accept the fact that "purity" is a question for theorists - and, at some point, you still need to deliver working code on a manageable deadline.

A good, anecdotal example of this is: any function/component that uses session values. In theory, any function that leverages session values is, by definition, impure. In practice, even if you worship at the altar of pure functions, there are just some times when session values are absolutely positively necessary. So if you're writing the Holy Grail of FP, and you find yourself needing a session value, how do you handle it???

One answer may be to create HOCs. And that might be a viable solution. But I would ask you this: Does your HOC just split into two what might have previously been a simple, concise component?? Even if that "simple, concise" component would've originally leveraged session values (thus, making it "impure"), you may not have solved any problem by chopping it into a (impure) HOC and a (pure) component.

So in conclusion, all I'm trying to say is that your proposal might be a solid approach. But if you are breaking apart all of your "impure" components into HOC and "pure" components, you may find that you're just creating more work for yourself - all for the sake checking off some theoretical box that claims you write pure functions.

Collapse
mattk profile image
mattk

Question was indeed sincere.

Some comments have been hidden by the post's author - find out more