News for hackers. Stuff that matters.
Re:“Node.js is one of the worst things to happen to the soft... by Illniyar on Tuesday August 23, 2016 @01:25AM (#12341586)
Doing synchronious is much clearer and easier, most of the async patterns (like yield/await and promises) really just try to simulate a sync paradigm.

But there is one great reason why node's async first mentality is superior- when you want to do async in node, you don't have to worry that some library you are using is going to lock up your thread.

In any other language, you have to painstaikingly make sure everything you use isn't doing sync, or try and monkeypatch all io operations (python has something like that).

Frankly, for me, when I'm dealing with webservers I find myself needing to use async quite a lot.

Re:“Node.js is one of the worst things to happen to the soft... by icebraining on Tuesday August 23, 2016 @02:27AM (#12341795)
In any other language

No; for example, in Go, every time the code does IO, the scheduler will re-assign another goroutine, and they asynchronously get back to the other when the IO finishes. It doesn't need any special support by the library.

Re:“Node.js is one of the worst things to happen to the soft... by Illniyar on Tuesday August 23, 2016 @03:25AM (#12341974)
That sounds like an implicit async/await, which sounds rather awesome.

I haven't really gotten around to trying Go yet, but there are definitely great things going on there.

Re:“Node.js is one of the worst things to happen to the soft... by zigzigzag on Tuesday August 23, 2016 @05:45AM (#12342477)
It's just green threading, which has been around for a long time.

You can run millions of threads on a single machine with modern Linux kernels if you either have lots of memory or simply minimize your stack sizes and usage. The kernel doesn't care much. You don't really need any special language features. The main reason fibers/green threads/goroutines/etc have become popular lately is that common language runtimes and standard libraries don't resize thread stacks on the fly and tend to like very deep call stacks, so minimising your memory usage can be rather hard.

Re:“Node.js is one of the worst things to happen to the soft... by soulbadguy on Tuesday August 23, 2016 @11:06AM (#12344307)
> he main reason fibers/green threads/goroutines/etc have become popular lately is that common language runtimes and standard libraries don't resize thread stacks on the fly and tend to like very deep call stacks, so minimising your memory usage can be rather hard.

Green-thread, coroutine have been around for a long time, the recent popular is probably due to increase prevalence of people trying to solve the C10K problem.

Green thread, are more efficient both in term of memory consumption and context switching than kernel thread (even more so with compiler support).

The linux kernel might be able to handle millions of threads, but thruth is one can do it much more efficiently in userland

Re:“Node.js is one of the worst things to happen to the soft... by Mister_Snuggles on Tuesday August 23, 2016 @01:05PM (#12345286)
> Doing synchronious is much clearer and easier, most of the async patterns (like yield/await and promises) really just try to simulate a sync paradigm.

I'm currently working on some lighting (DMX-based theatre lighting) software and the ability to have my 'effects' written in a sequential manner by using 'yield' is actually incredible. It's simplified my code a huge amount and made it a lot easier to reason about.

There is a function called every frame, which then calls each effect. Since each effect is a Python generator function, it can be written sequentially and just has to yield whenever the frame is computed.

Re:“Node.js is one of the worst things to happen to the soft... by epidemian on Tuesday August 23, 2016 @02:28AM (#12341800)
> when you want to do async in node, you don't have to worry that some library you are using is going to lock up your thread.

> In any other language, you have to painstaikingly make sure everything you use isn't doing sync

I haven't found that to be the case TBH. In most other languages i've used i don't have to worry about foo() being syncronous or not. I can assume that. In other words, after the control returns from the foo() call, i can assume that what foo() is supposed to do has been completed. In the case that foo() needs to do some IO operation, i can usually rely on it doing a syscall that will block the thread and put it to sleep, instead of doing something nefarious like busy waiting.

And that's it. The current thread will sleep while the IO operation in foo() completes, and the OS (or VM if we're talking green threads) will switch the CPU to do something else in the main time. And if it's a web server we're talking about, that something else may be another web server thread, serving a different request. Yay, preemptive multitasking!

In the case of node, you do very much have to worry about a function call being synchronous or asynchronous, as it defines the way it has to be called. In the former case, it can be called "normally":

  let a = foo()
  // use `a`
In the async case, some code gymnastics need to be involved:

  // Either callbacks:
  foo(a => { 
    // use `a`
  })
  // Or promises:
  foo().then(a => {
    // use `a`
  })
  // Or promises + await syntax:
  let a = await foo()
It may not seem a big problem at first, especially if using the `await` syntax is an option. But to me the biggest problem of this technique is that the "async-ness" of a function cannot be abstracted away. If a function `foo` that has always been synchronous, and that is used in several places, needs to be changed, and this change implies `foo` calling an async function `bar`, then `foo` will need to become async too, and all the places where `foo` is called will need to be changed. Even though this internal `bar` async call was an implementation detail of `foo` that shouldn't have concerned `foo` callers. And this propagates all the way up: if any of the places where `foo` was called was, in turn, a synchronous function too, then that function will also need to be refactored into an async one, and so on and so forth.

And that's basically why i find node's distinction between sync and async functions so frustrating :(

PS: Cooperative multitasking does not imply this weird syntax complexity of having two different kinds of function calls that cannot be freely intermixed. For instance, Eralng "processes" use cooperative multitasking, but the "yields" are managed implicitly by the VM, so you don't need to explicitly yield control of the current thread to let other stuff run concurrently.