Node.js is one of the worst things to happen to the software industry in recent times, a whole generation of programmers are being taught the worst of all ways of doing concurrency, in a system that doesn't scale either in performance or project size and with one of the languages most plagued by pitfalls ever created.
JavaScript was already painful enough in the browser, why on earth anyone ever thought it was a good idea to use it on the server boggles the mind.
We will be paying the price of this misguided hyped fad for decades to come.
Of all the ways of doing concurrency, callbacks are by far the worst, Twisted was plagued by them and is the main reason why it failed, and that was with a much more sane and reasonable language like Python (stackless Python was a much better alternative and used a model similar to Go's CSP).
And the sad thing is that there are much better alternatives around with much more sound models and environments, Erlang and Go are the two obvious examples, and that is for the highly specialized situations where you have great concurrency needs, for any other problem anything else will be much better than Node.js, even PHP.
I agree that the Node.js model of concurrency is one of the weakest models out there. CPS is for the compiler writer, not for the programmer.
The underlying problem is that sequential languages do bad when you "bolt on" concurrency to them - unless said language is expressive enough to make it bearable (Haskell and some MLs come to mind). For all other language, you are just frankensteining your system.
The reactor-model, of which Twisted, Node.js and a couple of like systems are built around has one advantage: It is fairly easy to get going. It is by far the simplest model you can get bolted onto a system with relative ease. The crux of the problem is that we have a lot of sequentially oriented programmers who suddenly need to do full concurrency. This is the first attempt.
To a professional Erlang programmer like me, it does look rather odd that one would hail a reactor model as being anything decent to work with. There are other concurrent calculi out there, which may be better than what Erlang provides, but none of them worries about callbacks in the style of Node.
I have a hunch the kid must be dragged screaming into the concurrency shop.
> The underlying problem is that sequential languages do bad when you "bolt on" concurrency to them - unless said language is expressive enough to make it bearable
Really?
I'm not familiar with Erlang, but have you tried Go? Concurrency fits seamlessly into the language.
Go is not sequential, but concurrent. It has built-in primitives for handling concurrency, witness the `go` keyword. It also has special syntax for doing selective receive over channels, which in turn means that the concurrency of that language is definitely not "bolted on" in the sense I meant.
Perhaps you are confusing my definition of "sequential" with yours. I tend to use "sequential" as the opposite of "concurrent" like I have another, orthogonal, axis for "serial"/"parallel". So you can be serial/concurrent (Node.js is close to this. So is a 4.4BSD OS without any SMP support). And you can be sequential/parallel (GPUs is my preferred example).
No JavaScript in all honesty was painful because the way it was designed (it was made in ten days). Equality operator ('==') is a cause of MAJOR headache and so is the global scoping, the bizzaro addition operator, etc.
http://stackoverflow.com/a/9033306 - this "wat" meme is getting old. At best, you people that keep posting this are automatically qualified as trolls. The fact is that probably none of you folks from the "wat" crowd didn't take the time to read the ECMA standard. I don't claim that the behavior is intuitive, or appropriate for some cases. But the lack of RTFM isn't excusable either.
And yes, developing under node is not the same as developing for the browser where you need to use the lowest common denominator, which usually is IE6.
I'd say that the issue is the "omg node.js" crowd that promoted it as the hammer for every issues that may pop out. It isn't. But this doesn't mean that it is completely useless.
Sorry, but please explain how is this issue somehow elevated by node when it is a part of language standard (ECMAScript standard linked in the article it posted)? Does V8 break ECMAScript? This is a gotcha of a language. It uses + operator that does something completely differently than what it usually does on almost any other language with similar syntax. It's the definition of counter-intuitive.
> I don't claim that the behavior is intuitive, or appropriate for some cases. But the lack of RTFM isn't excusable either.
You failed the read test. Twice. The first was the manual itself.
> please explain how is this issue somehow elevated by node when it is a part of language standard
You failed the read test. For the third time. Please indicate the part where I claim that node elevates the issue vs. standard ECMAScript behavior. I said something about the node vs browser runtimes. This is a totally different beast.
> This is a gotcha of a language. It uses + operator that does something completely differently than what it usually does on almost any other language with similar syntax. It's the definition of counter-intuitive.
The only gotcha is the coercion that some regard as dark magic vs statically typed languages vs the operators themselves. The "+" and "-" operators in JavaScript: "+" for summing Numbers or String concatenation, "-" for subtracting a Number from another Number (which basically makes it a strict arithmetic operator, you know, stuff for Numbers).
Besides:
- PHP uses the + and - as strictly arithmetic operators (it has the . operator for string concatenation), while summing up two strings equals int(0) since (int) 'foo' === 0: http://php.net/manual/en/language.operators.arithmetic.php
- C (and to some extent C++) uses the + and - as strictly arithmetic operators: invalid operands to binary + (have ‘char ’ and ‘char ’)
Yes, I may have skimmed a little. But this doesn't excuse language makers for not anticipating such a use common case and returning a result that can be said to be expected (i.e. error, trying to add one list on other). If there isn't a real comparison, you should take a couple of people that are likely to use this and say "what should [] + [] return". You can't say that they couldn't have implemented " []+[] " throws a TypeError or something, even in a dynamic language.
It is said that API is UX for programmers. Well this is UX for a computer language. And JS fails at it. Big time. And this isn't the only stumbling rock (see global variables, == operator, semi-colon insertion, etc.).
My point was that developing under Node.js is same as developing under a browser only the lowest common denominator changes to V8.
Edit: I'm pretty sure + operator in Ruby concatenates two arrays.
Couldn't agree more. But that's the standard. At some point I hoped that the ES5 'use strict' would fix all of this SNAFU, but it didn't.
However, not even once I tried to sum [] + [] or {} + {} till that "wat" video. Funny, but unrealistic, therefore: close, but no cigar. One could operate the "World's safest table saw", but the common sense tells us that usually finger vs. saw => saw wins. Safer tools are desirable, but it's up to the craftsman to use them properly.
> the lowest common denominator changes to V8
V8 is pretty much on par with its competition with the ES5 adoption, therefore we can hardly talk about a lowest common denominator that's actually low. The only thing that I actually missed in V8 vs. the Mozilla engines is the support for E4X (which most runtimes don't support anyway).
http://kangax.github.com/es5-compat-table/ - even if IE6 and IE7 are gone from the traffic stats, IE8 is there to stay with the XP users. Some of us still don't have the possibility to just drop those users as long as the analytic data shows a fair share of legacy users.
Ruby isn't part of the "similar syntax" family. The '==' operator isn't recommended in JS (and PHP). In fact, jslint yells at you if you use it. That's why '===' exists. The semi-colon insertion is one of the big failures on the "allowed" part. Wish that never happened. But any developer that doesn't try to adhere to some hipster JavaScript coding style uses the semi-colon at the end of the statement.
I don't find that makes much difference in practice because most developers learn about the good parts of JavaScript early on and so ignore these things.
Yes, the lack of proper standards made it even worse, and yes, JavaScript has 'good parts', but JavaScript is still chockfull of wat: https://www.destroyallsoftware.com/talks/wat
That video is completely misleading due to a quirk of the repl treating {} as a block not an object, not really a language wart.
Try it yourself:
var a = [] + {};
var b = {} + [];
Miraculously they are same (but only because the list is empty, string concat order matters obviously)! The only time that wat can ever happen is a case that would never exist in any actual code. The Dom is full of wat but I still havent seen any legitimate cases in js itself.
Why not? A thread allows for two parts of the program to be running concurrently. Whether or not they run in parallel is orthogonal. Why don't you think they allow for concurrency?
So who's wrong here? The world leading academics behind Haskell, Scheme and Oz? The industrialists and pragmatists behind Java? Or little old you?
The reality is that threads were created only to allow for concurrency. They were then re-used to allow for parallelism when we had multi-processors and then multi-cores.
Edit: does this guy work at Google? Unbelieveable.
>In computer science, concurrency is a property of systems in which several computations are executing simultaneously, and potentially interacting with each other. The computations may be executing on multiple cores in the same chip, preemptively time-shared threads on the same processor, or executed on physically separated processors. A number of mathematical models have been developed for general concurrent computation including Petri nets, process calculi, the Parallel Random Access Machine model, the Actor model and the Reo Coordination Language.
You can certainly build the actor model on the backs of threads.
What are you on about? Concurrent programming is the set of problems that exists when there are multiple 'computational processes' accessing shared state. This is a 'thread' (overloaded use) about JS, but Java has a package called java.util.concurrent and there's also a seminal book called "concurrency in practice", these are about nothing but threads.
Parallelism is just a new buzz word for people who have just discovered that threads\processes exist and they can have multiple things running at the same time. They just removed the shared state cause they don't want to have to deal with the headaches of concurrent programming.
And I quote, "In computer science, unbounded nondeterminism or unbounded indeterminacy is a property of concurrency by which the amount of delay in servicing a request can become unbounded as a result of arbitration of contention for shared resources while still guaranteeing that the request will eventually be serviced. Unbounded nondeterminism became an important issue in the development of the denotational semantics of concurrency, and later became part of research into the theoretical concept of hypercomputation."
If you haven't even read the wiki page, what have you read about concurrency exactly? Are you just making it up as you go along? Is confabulation about topics subject to factual review a habit for you?
Unfortunately can does not mean always will. For example, lock-free algorithms do not have any contention, ergo we can have concurrency without running into unbounded non-determinism. Please try to actually understand what you're talking about before being so rude to people. Copying and pasting the first thing you find on Google is no substitute for learning and careful research.
I'm actually pretty familiar with the current state of deterministic concurrency as a field of research and it has little to do with lock-free algorithms at all.
For that matter, what little of deterministic concurrency exists (FP interleaving, coroutines), it is only the palest imitation of true concurrency and how it gets used in practice for which one can SAFELY assume that useful and meaningful concurrency DOES IN FACT constitute non-determinism which also happens to be an apt way to summarize and contrast the subject with parallelism.
What? You can't just dismiss coroutines as not "meaningful concurrency". Given that every major language outside of C and Fortran has a native implementation, I'd call that pretty useful, and pretty meaningful.
> Concurrency is by definition, non-determinism.
The fact is that you are wrong: coroutines are a form of deterministic concurrency. They're also very useful.
JavaScript was already painful enough in the browser, why on earth anyone ever thought it was a good idea to use it on the server boggles the mind.
We will be paying the price of this misguided hyped fad for decades to come.
Of all the ways of doing concurrency, callbacks are by far the worst, Twisted was plagued by them and is the main reason why it failed, and that was with a much more sane and reasonable language like Python (stackless Python was a much better alternative and used a model similar to Go's CSP).
And the sad thing is that there are much better alternatives around with much more sound models and environments, Erlang and Go are the two obvious examples, and that is for the highly specialized situations where you have great concurrency needs, for any other problem anything else will be much better than Node.js, even PHP.