Hacker News new | ask | show | jobs
by geewee 2313 days ago
I think it's partly "you can", but surprisingly enough I also feel that node's single-threaded architecture makes code surprisingly easy to reason about.
3 comments

Golang is about as far from single threaded as you can get, and I find it much easier to understand than Node. I actually switched from Node to Go on a Greenfield project, and I find myself much more productive now, and when things need to be done in parallel, Go is much easier to read, write, and maintain.

Edit: to respond to the GP, I think sharing a language between front end and back end can enable people on either side go full stack with more ease. That's a benefit I guess, but not one I considered of particular value.

I’ve seen people think they’re reasoning about it when I fact they are not. I was on a project where the developers we Node pros for years. They were flummoxed when they couldn’t introduce transactions because they didn’t close over the database connection. When I said they had to hold the same connection through all the method calls, I was told I was wrong and that a global pool would be able to handle that without some external tracking mechanism.
Until you have to deal with aaync/callback/promises and mixing those to deal with various library dependencies.

I would love to see JavaScript turn into a less verbose, more consistent and less golf-oriented language.

I don't really see how JS could be less verbose in its concurrency-management side.

    result = somePromise() // run while the next promises are resolving
    pages = await Promise.map(url, url => crawlUrl(url), {
      concurrency: 4
    })
    allResults = await Promise.all([result, pages])
is some of the simplest concurrency code there is. You can keep chucking in more async logic and it doesn't get much more difficult to understand and doesn't introduce much more code.

If you want verbosity, look at Go's equivalent (wait groups) or, god forbid, any concurrency management in Swift.

The only problem you run into with callbacks imo are event-emitters like streams which you need to actually understand. Though I don't think this is any more trivial in other languages with evented/callback APIs like Java and Rust, I think reasoning about event callbacks is always harder for humans but a useful construct and necessary evil in evented code.