News for hackers. Stuff that matters.
Re:After a year of using Node.js in production by Silhouette on Monday May 02, 2016 @06:52PM (#11616392)
I find that JS often seems to tie programmers in the most extraordinary knots just to implement even quite simple logic, because of the single-threaded nature of the language.

In the programming model used by most other mainstream languages today, if you've got some work to do that interacts with some external system and might take a while, you'd probably start another thread for that task. You'd write the required logic in the usual linear fashion, and just let the thread block if and when it needs to. Modelling this using fork/join semantics and techniques to co-ordinate access to shared resources from different threads are reasonably well understood ideas.

Because there is no general support for concurrency and parallelism in JS, you only get one thread, and so in most cases you can't afford to ever block it. Consequently, you get this highly asynchronous style that feels like writing everything manually in continuation passing style, just so you can carry on with something else instead of waiting. That in turn leads to callback hell, where you start to lose cohesion and locality in your code, even though usually you're still just trying to represent a simple, linear sequence of operations.

Async/await help to bring that cohesion and locality back by writing code in a style that is closer to the natural linear behaviour it is modelling. However, even those feel a bit like papering over the cracks in some cases. Async/await kinda sorta give us some simple fork/join semantics, but as the blog post linked from the parent shows, we have a lot of promise-based details remaining underneath.

Fundamentally, the problem seems to be that JS is increasingly being used to deal with concurrent behaviours, but it lacks an execution model and language tools to describe that behaviour in a natural, systematic way as most other widely used languages can. Being strictly single-threaded avoided all the synchronisation problems in the early days, when the most you had to worry about was a couple of different browser events firing close together and it was helpful to know the handler for one would complete before anything else started happening. I'm not sure it's still a plus point now that we're trying to use JS for much more demanding concurrent systems, though.

Re:After a year of using Node.js in production by firasd on Monday May 02, 2016 @07:23PM (#11616610)
Re:After a year of using Node.js in production by Touche on Monday May 02, 2016 @07:04PM (#11616469)
> Modelling this using fork/join semantics and techniques to co-ordinate access to shared resources from different threads are reasonably well understood ideas.

Writing thread-safe code is anything but easy in languages that support threads.

Re:After a year of using Node.js in production by Silhouette on Monday May 02, 2016 @07:26PM (#11616621)
I respectfully disagree.

Dealing with shared state is not always easy when you're working with multiple threads. If you can't reasonably avoid that sharing because of the nature of your problem, and if your choice of language and tools only provide tools on the level of manual locking, then I agree that writing correct, thread-safe code has its challenges.

However, there are plenty of scenarios where you don't need much if any state to be shared between threads. That includes almost every example of JS promises or async/await that I've seen this evening while reading this discussion and the examples people are linking to.

There are also plenty of more sophisticated models for co-ordinating threads that do need to interact, from message passing to software transactional memory. These are hardly obscure ideas today, and I don't think anyone could reasonably argue that for example message passing makes things complicated but async/await/promises make things simple.