I just watched an interesting discussion of Java and Node supporters on Youtube. The videos are in Spanish here and here. This subject is not indifferent to me. Soon my brain started to generate ideas, past facts, even traumatic experiences.
- Provide a simple scripting language "inspired by" Java to control embedded Java applets in web pages.
- A simple scripting language to control forms.
As you can see, the initial motivation was not to create a complete and powerful language to develop web client applications.
Monothread Asynchronous Programming Is More Performant Than Thread Based Programming
Sure you have read many times how bad and costly thread context switching is and how good mono-thread programming delegating blocking operations are to a thread pool (yes again, a thread pool, the dark secret of Node).
But, the real facts do not agree. Take a look Paul Tyma experiments, my own insights, or the famous Tech Empower benchmarks. Take a look how the venerable raw Java servlet blocking threads in I/O are performing and the position of async I/O Java alternatives—of course Node is even in a lower position.
It depends, if you are doing a very simple web application with Node, yes you are going to deliver some result before Java developers, but when the code becomes bigger and bigger the missing types are more a problem for productivity than an advantage.
The optional generics Java type system is not an evil invention to make the life of Java developers sadder; it is a tool to make your code more robust. The verbosity cost is backed with better code. Any Java developer understands that "List<User> hello" is a list of User (readability) and only can contain User objects (robust) in spite of the stupid variable name... is it bad?
Can you make big web applications in Node? Yes, of course. Anything is possible with effort and discipline (in weak typed languages the discipline must be "military", even more strict than a explicitly typed one), but in the long term a dynamic, weak typed language becomes a nightmare in projects with a lot of code, even in projects with a single developer (in my experience).
The Problem of Argumentation Based on Inferiority Complex
I remember when Java was invented and was becoming more and more popular. Java was initially a C++ simplification—many C++ developers received Java with some skepticism. To win more Java developers from C++, Java supporters praised the "simplification" as a feature. For instance, the Java class system lacked the powerful templating system of C++, "you don't need it, everything is more simple in Java." This kind of argument—trying to convert the inferiority in an advantage—is unfair and a bad trick, but it usually works. Years later, Java 1.5 introduced generics, yes conceptually similar to the venerable C++ templates.
This is an example of the art of converting a limitation into a feature. In spite of being a Java guy for many years (and a C++ guy before), Java marketing was dishonest.
A Node instance has only one working thread—no concurrency problems. On the other hand, end developers are forced to execute all business logic of all concurrent users in the same single thread. This introduces a severe limitation, the problem of "CPU bound applications." Your business logic must be very simple and quick, otherwise all users will be stalled.
Related to the previous limitation, do you know the anecdote "Why npm's progress bar slows down install time by ~20%". The explanation is simple, the progress bar updating is time consuming and is executed in the main thread instead of starting a new thread. I'm sure it will be fixed, maybe executing the log operation in an extension coded in C/C++ in a different thread or similar. This makes me wonder, are we living in the year 1970? Are we coding on Windows 3.1/95 (the later with a crappy not preemptive thread system)?
In practice any Node application is multithread because blocking I/O operations are executed through a thread pool, whether the thread context switching is time costly, Node has the same problem as a thread per request pool.
Is Java the best language OOP/functional of the world? Of course it is not. In the OOP space, I'm sure most people agree with me that Scala, Kotlin, Ceylon, typed Groovy, or C# are superior languages, no problem, and in no way is Java the best functional language.
"The Language Is Not Important, the Developer Is"
Yes, you heard/read this polite phrase often. And yes, a good developer can be good in any language, but...
- A good surgeon is a good surgeon in a shelter tent and in a conventional operating room of a modern hospital. Try asking him/her what is the best place for surgery...
- Can you do surgery with a kitchen knife? Yes, you can, but I'm sure you'd prefer a scalpel.
- Do you think a veterinary surgeon is appropriated to do surgery to humans?
The Myth of Complexity of Concurrence Management in "Conventional" Request-thread Web Apps
This is a very bad argument. A very big percentage of conventional web apps have no problem with thread concurrency because, in most of them, all of the code is single thread because they have no need to deal with other parallel requests (threads). The database is, in practice, the synchronization point; all decent RDBMS ensure consistency in column writes and if you need a more sophisticated synchronization you have transactions.
Java is not only the language, a large library is part of the Java platform. It doesn't prevent smart developers from picking alternatives (for instance Guava, Apache HttpClient, Apache Commons, etc.)
An Explicit Type System is Not Only to Reduce the Number of Tests
Yes, you know how useful a good type system is; if you do something wrong usually some other place breaks and the compiler advises you without the need of executing tests.
However, an explicit type system provides more, very important benefits:
- Readability: read the code of a Java class from a decent open source product, I'm sure you're going to understand the function of the class by just reading the types.
- Robust code: MyClass obj only can reference MyClass objects or inherited from, List<MyClass> list is a list and only can contain objects of MyClass or inherited (a final class is also possible).
- Reliable code navigation: any decent Java IDE offers a "Find Usages" ("References" in Eclipse) feature, if you use this feature selecting "any" element of your code, the IDE is going to show with precision all uses of this element (an attribute, param, local variable, method, constructor, class name etc).
- Reliable code refactoring: any decent Java IDE offers many options for easy and secure refactoring, for instance, name changing (the simpler case, IDEs offer more complex refactoring options). Brutal refactorings can be performed with almost no risk.
Paradigms, Paradigms, Paradigms
At the end of the day, the moar important characteristic of your preferred language is the paradigms supported, for instance, structured (ex. C), OOP, OOP+functional (Java, Scala...), pure functional (Lisp, Haskell, Closure...).
I'm not kidding, take a look this C like code of Mozilla based products (for instance FireFox).
The Myth of Inheritance Abuse
Some people say that "people" usually abuse using inheritance, one reason for bashing OOP (the typical all-or-nothing argument—a bad argument in my opinion.)
I don't agree—in the real world it is the contrary. Many people inherit only when there is no other option (when the API being used provides an abstract class or interface to implement) but rarely you are seeing fully user defined inheritance trees not forced by the frameworks. Of course, this is my personal opinion and isn't scientifically backed.
Many people ignore how to model a class system including inheritance, encapsulation, and polymorphism when appropriated; others maybe because they are following the mantra of some "gurus" saying "inheritance is bad".
A long time ago when OOP became popular, many people abused inheritance trying to fit too many things in the same class tree—for instance, a class User inherited with visual code, persistent code, networking, etc. Fortunately, that time is gone, however, some people today harken back to this old, crazy approach because they don't like the modern layering/services approaches (and usually they are the same people saying that inheritance is bad).
Fortunately, good OOP developers use inheritance (the complete OOP features in general) when needed.
Can You Answer These Questions?
- A Big Data tool made in Node.js:
Hadoop, HBase, Spark, Storm, Kafka, Cassandra, Kubernetes, Docker? Most of the Big Data tools are made in Java or a similar JVM lang (Docker and Kubernetes are Go).
- Replacing Java Android core on top of C++ by Node.js
Maybe, but...is this really a good idea? I remember years ago the filtered statement of a Google executive about the language on Android being something like "Java is the only option, anything else is crap" (modern JVM statically typed langs were not created yet).
- A desktop application in Node.js
Does Node.js Have a Reasonable Place in the World?
Yes course, Node is useful for conventional web sites with small and relatively simple business code.
Oh yes, some important parts of PayPal are built with Node, almost all of the public web site. Right, okay. However, PayPal is a relatively easy service. Yes really, PayPal is a far cry away from the enormous complexity of the Google, Amazon, or Apple ecosystems. I remember the article about the "competition" of the options, Java and Node, for replacing the old C++ based tech of PayPal, I'm sure you know Node won.
In my opinion, it is quicker to make simple spaghetti than a solid Java application, and, as far as I remember, the Java developers in PayPal tried to include every Java framework invented in SpringSource and GitHub (the competition was to make a quick prototype of a service, not a production service) and imported also the kitchen sink. Yes, Node is fine in the short term, the long term is different... remember the case of Twitter and Ruby—I respect Ruby. Twitter is as is thanks to the flexibility of Ruby in the beginning, before becoming the current monster, by the way, today based mainly on Java.