Thank you for you advice. But could you elaborate about the technical insight? The author has also made Advanced Explorer, a JavaScript + Node.js version of a file manager previously written in Java, so he has some knowledge on the topic.
It would probably help if you had experience on both sides - as the comment suggests, the author doesn't seem to have much insight into how PHP works: "PHP also allows you to link libraries written in C, but we must recompile the interpreter with the appropriate options".
It reads like someone who isn't a native English speaker (not a bad thing, their grammar is very good, but the cadence isn't quite natural), and the design screams "content farm", which makes you perceive the writing style negatively. It's not a great article, but the context makes it look even worse.
The argument about "same language on client and server" doesn't hold for me.
For one thing, client and server share only a small part of the overall functionality. Usually the database interfacing on the server and the user interfacing on the client will require substantially different code.
For another point, Python, Ruby and even PHP come with a lot of available packages and libraries. Node.js has lots of them too, but generally I prefer Django's API design to be more pleasant to work with than node.js
I have been teaching myself programming and web development for a little less than 2 years now using only online resources. I have been learning and tinkering with many languages and frameworks including asp.net, rails, php, and flask. Each language/framework taught me something new and showed me the fundementals in a novel way which helped me reinforce them. But recently, I was becoming frustrated because after all this study, I still had little to show for my effort as far as shipping things. So I decided I would focus on making some simple apps that consume apis.
I have found node and the express framework specifically to be the only tools so far that don't overwhelm me and allows me just hack things together without having to google too much. JavaScripts pleasantly simple syntax, and expresses minimalism let me focus on the important parts of web development like how things fit together on a high level. Eventually, I will go back to learning Ruby and Rails, but for now I am happy to actually be working on things instead of just studying.
So, from my perspective, I like server-side js more than PHP and I think it will continue to grow and improve.
The use of client-side JavaScript is uncontroversial - most anybody who is targeting the web browser as their client platform will choose to use JavaScript to implement the client user interface and logic. Many client applications which required plugins or native code can now be implemented in JavaScript using advanced HTML5 features.
I presume your question is actually… why server-side JavaScript?
One language, one toolset
The use of a single platform on the client and server means that developer skills will transfer more easily from client to server work. This can lead to more consistent project quality and easier developer scheduling.
DOM and library portability
By using JavaScript everywhere, it is possible to have the same functions on both the client and server, and to run them "close to the data" to avoid unnecessary latency and bandwidth costs. Using libraries like jsdom, it is even possible to write DOM manipulation code on the server, so that more capable clients can render the UI on the client while backwards-compatibility (with IE6, for example) is maintained through server-side rendering.
Node.js and asynchronicity
The use of server-side JavaScript is still quite new, however, and the critical development there is node.js. By using node.js, developers can implement fast, JIT-compiled, garbage-collected server logic, with libraries that enforce asynchronicity. Asynchronous servers are (usually) able to deliver more application throughput than threaded servers on the same hardware, but asynchronous (or "event-based", or "non-blocking") server programming has traditionally been very difficult and error prone.
JavaScript, by the fact of being a highly dynamic functional language, tends to make writing event-based programs a bit simpler, or at least easier for the average programmer to comprehend.
For more background on event-based server programming, read up on Twisted and libevent, and read the classic papers "Threads: Threat or Menace?", "Why Threads Are a Bad Idea (For Most Purposes)", and "Threads Considered Harmful".
Threads are not a menace if implemented correctly. Note how almost every evented system is written in a language with horrible threads support, e.g. Python. Take a language like Go or Haskell, and threads become a highly performant (by virtue of transparently asynchronous I/O operations) means of writing code with many threads of control, and saves you from getting bundled up in callback spaghetti. (I love Twisted, but I really don't miss the callback spaghetti it inevitably causes. InlineCallbacks made it nicer, but it was still a pain.)
If you absolutely want to use JavaScript, then yes, you'll be writing event-driven code using a continuation passing style. JavaScript is probably one of the better languages for doing so, since the language is fundamentally single-threaded, and so virtually everything is asynchronous. The biggest argument for this is that you don't have to worry about synchronization. But please don't imply that event-driven programming is The One Way, or even the right way at all. If you want to scale, then you will eventually need to consider threading of some kind, whether it be the poor man's kind that Python and Node use, spawning multiple processes, or the good kind, fibers that automatically multiplex onto OS threads, as the Go and Haskell runtimes implement. Even the async poster-boy, nginx, does this via its workers.
While it's true that threads are ok if implemented correctly, one needs to be smart to correctly work with threads, and still any concurrent code will be ~10x more expensive to write and maintain.
In my perspective lack of threads is a blessing because it takes this complexity out of the equation.
On the other hand, working with async callbacks also takes training and more careful thought of the bindings and closures.
For me, after 6 months with node, I can say that I like it. It's superfast, ample modules to work with, and javascript is very convenient for working with data.
Yeah, like I said, running single-threaded, e.g. in Python with the GIL, or in JavaScript, saves you having to worry about synchronization. But that should be the only big argument for it, not performance and scalability.
> The use of server-side JavaScript is still quite new
I'm not sure I'd say that, I talked with a few companies that were doing it in the early 2000s, but it wasn't exactly widespread. I vaguely remember at the time the only interpreter was available for Windows, and maybe not a *NIX-like platform so it wasn't really moving.
Node.js is too opinionated about how to do things that it could ever replace anything on the server-side of things, be it PHP, Python, Ruby, Lua, whatever. Their "event-driven, non-blocking I/O" experiment should be entirely optional, and for the afficionados only. Do you know of any other scripting engine that imposes that kind of experiments on its users?
I would be entirely ok with replacing mod_php or su_php with mod_js or su_js, but I am really not interested in joining their callback hell.
It's really not an experiment. Python's largest networking framework, Twisted, uses event-driven, non-blocking I/O with callbacks; however, Twisted implements a number of wrappers and patterns to make it a bit more usable. (There are also a number of other commonly-used libraries for all sorts of languages which follow a similar concept; thread-oriented network programming is now a bit of a rarity in new code for things outside the "old" one-way web.)
Where in node.js, a vaguely procedural programming pattern is usually adhered to, Twisted uses a lot of objects with state to manage protocols and business logic. Many of these objects will adhere to various pre-defined interfaces within Twisted, especially when they are directly dealing with network protocols.
This means that when you're implementing that new protobuf-based protocol, you will always subclass Protocol or one of the simple Protocol subclasses in twisted.protocols.basic, implementing dataReceived() (or the relevant message-oriented function for your subclass), then create a subclass of Factory to create these protocols, then, when you want to connect, you hook up the Factory to an Endpoint.
"Callback hell" is thus mitigated by the fact that you will typically name every callback as a method on the object, and each callback can be as short as a few lines. You also don't tend to bury yourself 6 layers down waiting for a read; instead, you store a bit of state on the object, and wait for dataReceived() (or your buffer-emptying callback) to be called again.
In cases where it's still hell, for whatever reason, the @defer.inlineCallbacks decorator will help by allowing you to write code like this:
All in all, my proposal is that node.js's issue isn't that it's too opinionated; it's that it's not opinionated enough, implementing only the base layer of something which needs a lot of opinion to be usable.
Within a year ES6 will be shipping and available, already generators have been implemented in V8. Combine them with http://taskjs.org/ and you have callback hell relegated to a distant memory.
Though I do agree that JavaScript needs an indescribable "something" to make it less formulaic and demanding ("opinionated" is good here but I don't want to steal your wording).