• Functional programming in JavaScript is an antipattern
  • Written by Alex Dixon
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: sunui
  • Proofread by: LeviDing, Xekri

Clojure is simpler

After a few months of Clojure I started writing JavaScript again. Even when I’m trying to write something mundane, I always think about the following questions:

“Is this an ImmutableJS variable or a JavaScript variable?”

“How do I map an object and return an object?

“If it is immutable, use either < this function > of < this syntax > or < another version of the same function > of < different syntax and completely different behavior >”

Can the state of a React component be an immutable Map?

“Has Lodash been introduced yet?”

“FromJS then < write code > then.tojs ()?”

These questions seem unnecessary. But I guess I’ve thought about these questions a million times and just haven’t noticed, because IT’s all I know.

I see no way to avoid this kind of thinking when writing JavaScript using any combination of React, Redux, ImmutableJS, LoDash, and functional programming libraries like LoDash/FP and Ramda.

I need to keep these things in mind:

  • The LODash API, the Immutable API, the LoDash/FP API, the Ramda API, and the native JS API or some combination of them
  • Variable programming techniques for dealing with JavaScript data structures
  • An Immutable programming technique for dealing with Immutable data structures
  • Immutable programming of mutable JavaScript data structures when using Redux or React

Even if I could remember these things, I would still have all the above problems. Immutable data, mutable data, and in some cases mutable data that cannot be changed. The same is true for the signatures and return values of some common functions, and almost every line of code has a different case to consider. I find it tricky to use functional programming techniques in JavaScript.

By convention libraries like Redux and React require immutability. So even if I don’t use ImmutableJS, I have to remember that “this place can’t change”. Immutable transformations are harder to use in JavaScript than they are. I felt like the language had put a pit in my path. In addition, JavaScript does not have basic functions like object.map. So like more than 43 million people last month, I use LoDash, which provides a lot of functions that JavaScript doesn’t have on its own. However, its API is not friendly and supports immutable. Some functions return new values, while others change existing data. Again, it’s not cost-effective to take the time to distinguish them. The truth is, to work with JavaScript, I need to know loDash, its function name, its signature, and its return value. Worse, its “collection first, arguments later” approach isn’t ideal for functional programming either.

It would have been better if I had used Ramda or Lodash/FP to easily combine functions and write clean code. However, it cannot be used with Immutable data structures. I might still have to write some code where the set of arguments comes last and the rest of the time comes first. I had to know more function names, signatures, return values, and introduce more basic functions.

When I use ImmutableJS alone, some things get easier. Map.set returns the new value. Everything returns a new value! That’s what I want. Unfortunately, ImmutableJS also has some kinks. Inevitably, I had to deal with two different sets of data structures. So I have to know whether X is Immutable or JavaScript. By learning its API and overall way of thinking, I can use Immutable to learn how to solve problems in 2 seconds. When I used native JS, I had to skip that solution and solve the problem in a different way. Just like Ramda and Lodash, there are tons of functions I need to know — what they return, their signatures, their names. I also need to classify all functions I know into two classes: one for Immutable and one for the other. This also tends to affect the way I approach problems. Sometimes I can’t help but think of solutions to Currization and composition functions. But it cannot be used with ImmutableJS. So I’ll skip this solution and think of something else.

When I had it all figured out, I could try to write some code. Then I move to another file and do the same thing again.

Functional programming in JavaScript.

Visualization of anti-patterns.

I’ve gone out of my way to call functional programming in JavaScript an anti-pattern. It’s a fascinating path that leads me into a maze. It seemed to solve some problems and ended up creating more. The point is that there seems to be no higher-level solution to these problems that will keep me from dealing with them over and over again.

What are the long-term costs of this?

I don’t have the exact number, but I can tell you that without thinking, “What function can I use here?” “And” Can I change this variable? “so I can develop more efficiently. These issues don’t make any sense to the problem I’m trying to solve or the feature I’m trying to add. They are the result of language itself. The only way I can think of to avoid this problem is to stop at the beginning of the road — not using ImmutableJS, ImmutableJS data structures, immutable data from the Redux/React concept, and ramda expressions and LoDash. The bottom line is write JavaScript and don’t use functional programming techniques, it doesn’t seem like a good solution.

If you’re sure and agree with what I’m saying (and if you’re not, fine), THEN I think it’s worth taking 5 minutes or a day or even a week to consider: What are the long-term costs of staying on JavaScript rather than replacing it with something different?

This so-called different thing to me is Clojurescript. It is a “compile-to-JS” language like ES6. Basically, it’s JavaScript with a different syntax. Underneath it is a language designed for functional programming, manipulating immutable data structures. For me, it’s easier and more promising than JavaScript.

What is Clojure/Clojurescript?

Clojurescript is similar to Clojure, except that its host language is JavaScript instead of Java. The syntax is identical: if you learn Clojurescript, you learn Clojure. This means that if you know Clojurescript, you can write JavaScript and Java. “Java running on 3 billion devices”; I’m pretty sure JavaScript is running on other devices.

Like JavaScript, Clojure and Clojurescript are dynamically typed. You can use Clojurescript to write full-stack server applications in Node 100% of the time. You can also choose to write a Java-based servrer to support multithreading, as opposed to languages compiled into JavaScript alone.

As an average JavaScript/Node developer, learning the language and its ecosystem wasn’t difficult for me.

What makes Clojurescript easier?

Execute any code you want in the editor.

  1. You can execute any code in the editor with one click. Indeed, you can type whatever code you want to write into the editor, select it (or place your cursor over it), then run it and see the results. You can define a function and then call it with the parameters you want. You can do this while your application is running. So, if you don’t know how something works, you can evaluate it in your editor’s REPL and see what happens.
  2. The function can operate on arrays and objects.Map, Reduce, and filter have the same effect on arrays and objects. That’s design. We don’t have to worry aboutmapDifferences between arrays and objects.
  3. Immutable data structures. All Clojurescript data structures are immutable. So you don’t have to worry about whether something can change. Nor do you need to switch programming paradigms from mutable to immutable. You’re in the realm of immutable data structures.
  4. Some basic functions are included in the language itself. Functions like Map, filter, Reduce, compose, and many others are part of the core language and do not require external introduction. Map, lodash.map, ramda.map, Immutable map. You only need to know one.
  5. It’s neat. More than any other programming language, it takes just a few lines of code to express your ideas. (Usually much less)
  6. Functional programming. Clojurescript is a thoroughly functional programming language — it supports implicit return declarations, functions being first-class citizens, lambda expressions, and more.
  7. Use whatever you need in JavaScript.You can use JavaScript for everything and its ecosystem fromconsole.logGo to the NPM library.
  8. Performance.Clojurescript uses the Google Closure compiler to optimize the JavaScript output. The Bundle is extremely small. The packaging process for production does not need to be optimized from setup to:advancedComplex configuration.
  9. Readable library code. Sometimes you get to know “What does this library do?” Is very useful. When I use “jump to definition” in JavaScript, I usually see compressed or misplaced source code. Both Clojure and Clojurescript libraries are displayed as written, so it’s easy to read the source code without leaving your editor to see how something works.
  10. It’s a dialect of LISP.It’s hard to list the benefits because there are so many. One thing I like about it is that it’s formulaic, (there’s a pattern to fall back on) that the code is expressed in the language’s data structure. (This makes metaprogramming easy). Clojure is different from LISP because it is not 100%(a). It can be used in code and data structures[]{}, like most programming languages.
  11. Metaprogramming. Clojurescript allows you to write code that generates code. This has huge implications that I don’t want to gloss over. One is that you can effectively extend the language itself. Here’s an example from Clojure for the Brave and True:
(defmacro infix
  [infixed]
  (list (second infixed) (first infixed) (last infixed)))
(infix (1 + 1))
=> 2
(macroexpand '(infix (1 + 1))) => (+ 1 1) ; This macro passes it into Clojure, and Clojure executes correctly because it's Clojure's native syntax.Copy the code

Why isn’t it popular?

If it’s so great, why isn’t it heavenly? Some point out that it’s already popular, it’s just not as popular as Lodash, React, Redux, etc. But since it’s better, shouldn’t it be as popular as they are? Why haven’t JS developers who prefer functional programming, immutability, and React migrated to Clojurescript?

Because of a lack of jobs? Clojure compiles to JavaScript and Java. It actually compiles to C# as well. So a lot of JavaScript works as if it were Clojurescript. It is a functional language that does all the work for all the compilation goals. Regardless of its value, a 2017 StackOverflow survey revealed that Clojure developers earn the highest average salaries of any language in the world.

Is it because JS developers are lazy? And it isn’t. As I showed above, we did a lot of work. There’s a term called JavaScript fatigue, which you’ve probably heard.

Do we resist learning something new? And it isn’t. We have become notorious for adopting new technologies.

Lack of familiar frameworks and tools? This may feel like a reason, but there’s something in Javascript that Clojurescript has its counterpart: Re-frame for Redux, Reagent for React, FigWheel for Webpack/ hot loading, Leiningen for YARN/NPM, and Clojurescript for Underscore/Lodash.

Is it because the parentheses make the language too difficult to write? Maybe we haven’t talked enough about this, but we don’t have to differentiate between parentheses and square parentheses. Basically, Parinfer makes Clojure a blank space language.

Because it’s hard to use at work? Probably. It’s a new technology, like React and Redux were, and at times hard to promote. Even there are no technical limitations — Clojurescript is integrated into existing code bases in a similar way to React. You can add Clojurescript to an existing code base and rewrite the old code one file at a time, and the new code can still interact with the old code that has not changed.

Not popular enough? Unfortunately, I think that’s the reason for it. Part of the reason I use JavaScript is because it has a huge community. Clojurescript is too niche. Part of the reason I use React is because it’s maintained by Facebook. Clojure’s maintainers are long-haired guys who spend a lot of time thinking.

There’s a numerical disadvantage. I accept that. But “numbers in numbers” negates all other possible factors.

Suppose there was a path to $100 that was very unpopular, and there was a path to $10 that was extremely popular, would I take the popular path?

Well, maybe it will. There are successful precedents. It must be safer than the other way, because more people choose it. Nothing terrible can happen to them. The other way sounds nice, but I’m sure it’s a trap. If it’s as good as it looks, it’s the most popular one.


The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. Android, iOS, React, front end, back end, product, design, etc. Keep an eye on the Nuggets Translation project for more quality translations.