node-forward / discussions

Soliciting ideas and feedback for community driven collaborative projects that help Node.
149 stars 1 forks source link

Why not a real alternative to Node? #9

Open mvalente opened 9 years ago

mvalente commented 9 years ago

Node is great and V8 is great.

But why not take Mozilla's Spider/Eon/Odin/Monkey and create a real alternative to Node? Namely something that would be async/callback Node-compatible but have the alternative of sync-only API to better welcome people that are coming from PHP/Python/etc ?

zzmp commented 9 years ago

There is a sync API for most things - it's just not recommended for performance reasons. Do you want something more? Or just a different base to compete with V8?

Fishrock123 commented 9 years ago

But why not take Mozilla's Spider/Eon/Odin/Monkey

V8 was the fastest at the time, and I believe is still faster. Also, re-writing a new node would be a ton of manpower.

have the alternative of sync-only API

Node has Sync apis for lots of things, but JavaScript is designed in a way that makes a fully "sync" program very sub-par. (Javascript is single-threaded, etc.)

Generators in es6 will help make APIs nicer to use in a "sync" way though.

Edit: Re, below:

If I had my way I'd remove everything with Sync in its name from the core API.

100% Agree.

rvagg commented 9 years ago

http://r.va.gg/presentations/love-the-async/

Because async is why Node is so good at what it does, make it sync and you lose most of what makes Node so compelling--other than the JavaScript.

If I had my way I'd remove everything with Sync in its name from the core API.

Regarding alternative JS engines, I would expect this to develop over time, V8 is actually a huge pain in the backside to track for Node-core because of their development style and having alternatives would be great. It really takes someone with time on their hands to come up with something, ideally something that could be swapped out directly for Node or a way to abstract the parts of Node-core that are directly tied to V8's API.

yoshuawuyts commented 9 years ago

If I had my way I'd remove everything with Sync in its name from the core API.

@rvagg Just for argument's sake, what would the impact of this be for both user land and maintaining core? I find the thought to be quite interesting to say the least.

Qard commented 9 years ago

Well, the entire require system wouldn't work, since it uses fs.readFileSync().

rvagg commented 9 years ago

@Qard obviously you don't break sync require(), no reason it needs to also require a public fs sync API. This is just hypothetical and philosophical anyway; the main point being that I'd rather we put on-boarding effort into helping think in asynchronous terms instead of trying to munge our platforms and languages so that everything is sequential. Same goes for the false-promise of generators, you're just attempting to avoid async when it'd probably be better if you just accept that the world is async, everything we interact with in our programs is async and forcing synchronous behaviours is always going to be suboptimal because it means we're abstracting ourselves away from what's really happening by yet another step just so we can think in classic programming terms.

mvalente commented 9 years ago

No, Node doesnt have sync alternatives for everything.

Yes, I think that a different codebase (SpiderMonkey) would be important.

Yes, V8 was fast at the time. And its fast now. But current SpiderMonkey's versions are pretty fast as well.

I dont agree that rewriting a "new" node would be a ton of manpower. At least not for sync API, since SpiderMonkey has FFI as part of the code and it would be pretty easy to make the FFI interface available to JS.

JS is not singlethreaded. The engine is or isnt. And singlethreadedness hasnt stopped Apache and other webservers from being alternatives.

I undestand the extremist position of "remove everything with Sync". Great. Do understand that there are thousands of programmers (PHP, Python, etc) that find it hard to move to JS serverside because of all the async stuff and callback hell.

I know that async is what makes node fast. I've been around long enough ( http://goo.gl/5UpGwO ). But I find that the async mindset is too extremist. Async is good. Only async is bad. At least in terms of wider adoption of serverside JS.

Node is async and that is great because its fast. Nothing stops Spidermonkey being modified to also be async. And have sync as an alternative.

domenic commented 9 years ago

Async doesn't mean callbacks, any more than structured programming means gotos. Once a language actually has capabilities for handling new forms of programming (e.g. generators or async/await for async, or functions for structured programming) you're in a much better position to take advantage of the inherent power.

rmg commented 9 years ago

Node's async nature comes in large part from libuv and making heavy use of the existing *Sync functions already causes weird behaviour because it blocks the event loop.

Seems to me that to make a sync alternative to Node, you'd probably have to replace libuv before v8.

bmeck commented 9 years ago

@mvalente while interesting, this is probably not the right repository for this discussion. Many similar ideas have spawned around "sync" JS but javascript as a language never had concurrent shared memory and all of the implementations of such have had problems taking off because purely sync IO / scheduling does not match how people historically program Javascript. These have been tried many times and fail since JS programmers are somewhat uncomfortable with threads and synchronous concurrent programming at large scale. See:

bjouhier commented 9 years ago

Async doesn't mean callbacks, any more than structured programming means gotos.

Yes! Async programming can be painful in node. This is not a problem with the async model itself, it is a problem with the language: JS lacks an async/await construct. Once it gets it (ES7? @domenic probably knows better) async programming will be like a breeze. I've been doing it with my own async/await substitute (streamline.js) for more than 3 years and it's really pleasant. With this approach Java or .NET guys get up to speed with node in a few hours.

If I had my way I'd remove everything with Sync in its name from the core API.

Yes, and in a hypothetical world I would also turn require async. This would make it possible to load code modules from a database, a web service, etc.

medikoo commented 9 years ago

I'd love to see some alternative for V8, even if it would be slower (but reasonably)

I think one of the biggest downsides of node is that its limits are dictated mostly by interpreter and not by hardware on which is run.

Currently if your process gets over 1.5Gb in memory, you need to think fast on optimisations or how to split it into multiple processes. It's not just about that it may crash soon, but because every simple operation (e.g. string search) becomes magnitudes slower. V8 is great for light processes, but otherwise seems not well suited.

Still it's just my impression, I'm not sure how other server languages compare in that.

bnoordhuis commented 9 years ago

V8 is actually a huge pain in the backside to track for Node-core because of their development style

I don't disagree with that statement but SpiderMonkey and JSC are even worse. At least the V8 team makes an effort of doing real releases and not breaking API in patch releases.

SpiderMonkey does a big code drop every now and then (last one is from December 2013); JSC doesn't even do that, it's exclusively developed in-tree with WebKit.

Fishrock123 commented 9 years ago

And singlethreadedness hasnt stopped Apache and other webservers from being alternatives.

yeah um, because it does io async so that everything doesn't get clogged up.

mvalente commented 9 years ago

Great. Then nothing would stop a TraceMonkey/JS serverside of doing the same. I could do async io and then you could use sync for the rest. Better yet: you could have async/sync options for all language constructs. And people would opt. Even nicer if NodeJS had the same thing.

On Fri, Oct 17, 2014 at 2:26 PM, Jeremiah Senkpiel <notifications@github.com

wrote:

And singlethreadedness hasnt stopped Apache and other webservers from being alternatives.

yeah um, because it does io async so that everything doesn't get clogged up.

— Reply to this email directly or view it on GitHub https://github.com/node-forward/discussions/issues/9#issuecomment-59511889 .

bmeck commented 9 years ago

@mvalente why not use SilkJS then?

mvalente commented 9 years ago

Indeed. Thats what I've been using. But it uses V8. I think that having a Mozilla serverside JS using ***Monkey would be a nice option to have.

On Fri, Oct 17, 2014 at 3:50 PM, Bradley Meck notifications@github.com wrote:

@mvalente https://github.com/mvalente why not use SilkJS then?

— Reply to this email directly or view it on GitHub https://github.com/node-forward/discussions/issues/9#issuecomment-59523974 .

mikeal commented 9 years ago

While I don't find it all the interesting to do "Node but slightly different" there are some interesting JavaScript projects that are going in a direction that supplant Node in the future like https://github.com/runtimejs

heapwolf commented 9 years ago

Runtime represents a different class of project though. It's more about infrastructure specialization, where as node is meant to run on general purpose systems.

trevnorris commented 9 years ago

@mvalente

JS is not singlethreaded.

What's meant by "JS is single threaded" is that you cannot share JS objects between heaps. Sure you can run multiple JS runtime instances in the same application, but you cannot in any current gen engine pass a constructed JS object from one heap to another.

@bjouhier

Yes! Async programming can be painful in node. This is not a problem with the async model itself, it is a problem with the language: JS lacks an async/await construct.

This is completely subjective. I've been programming JS for 12 years now and using callbacks is so second nature to me that it requires zero additional cognitive reasoning.

Qard commented 9 years ago

It "requires zero additional cognitive reasoning" because you've been doing it for 12 years. People that are new to JS more often than not find the callback pattern tremendously awkward.

I can't even begin to count the number of times I've seen newbies write stuff like this:

app.get('/user/:id', function (req, res) {
  var user
  User.find(this.params.id, function (err, _user) {
    user = _user
  })
  res.json(user)
})

JS is very different from most languages. In some ways good, in others bad. But overall it is very difficult for newbies to get used to. Thing like generators, async/await, and promises try to reduce that learning curve.

mvalente commented 9 years ago

"requires zero additional cognitive reasoning" because you've been doing it for 12 years. "People that are new to JS more often than not find the callback pattern tremendously awkward"

Precisely. And that's a barrier do larger adoption. And it is the main justification from those not adopting

On Fri, Oct 17, 2014 at 7:11 PM, Stephen Belanger notifications@github.com wrote:

It "requires zero additional cognitive reasoning" because you've been doing it for 12 years. People that are new to JS more often than not find the callback pattern tremendously awkward.

I can't even begin to count the number of times I've seen newbies write stuff like this:

app.get('/user/:id', function (req, res) { var user User.find(this.params.id, function (err, _user) { user = _user }) res.json(user) })

JS is very different from most languages. In some ways good, in others bad. But overall it is very difficult for newbies to get used to. Thing like generators, async/await, and promises try to reduce that learning curve.

— Reply to this email directly or view it on GitHub https://github.com/node-forward/discussions/issues/9#issuecomment-59552760 .

bmeck commented 9 years ago

We need to be careful here. One of the reasons eventmachine and twisted struggle is because a lot of ruby/python code is not non-blocking friendly. We can have async/await/generators make code read top to bottom without truly blocking and getting into the nightmares that those libraries suffer from. Merely adding sync for everything will cause major problems for async code (re: fibonacci hilarity).

If we have a proposal that comes up that does not encourage blocking synchronous code I would definitely be interested, but blocking synchronous code does not mesh with Node's ecosystem, or that of most JS environments.

bjouhier commented 9 years ago

@trevnorris I know this is a contentious issue. Some think that the callback model is natural. Others that it isn't. I need a bit of prose to explain my position so I'll do it on my blog.

@mvalente Sync APIs are a horrible fix. If you introduce sync APIs and you want to preserve concurrency you'll need threads. And if you have mutable state (this is JS, not Erlang) you'll need synchronization primitives. Now you'll be in a very different world: complex, inefficient (I've been there before). And you'll have a whole new slug of issues coming from the complex interactions between blocking threaded code and async code (@bmeck's comment above).

A much better fix is to enhance the language so that your can code in sync style, while keeping the simple event loop and async model underneath.

Don't break the node model, just fix the language!

Qard commented 9 years ago

That is exactly why I like generators. You get the sync-like linearity, but have yield keywords telling you where it's releasing control back to the event loop.

Generally, within the context of a single request, there's not much that can be done in parallel. It's really just switching between other requests that node benefits from. And on the rare occasion you actually can do things in parallel, you can yield an array of tasks in koa.

Fishrock123 commented 9 years ago

The main issue with generators and such is that they are inherently much slower than callbacks due to the lack of optimizations. Which brings me back to wondering if regenerator makes more optimizable code.

bmeck commented 9 years ago

@Fishrock123 just to clarify, they are not inherently slower (that would imply that they could not be as fast) just not optimized by the JIT right now.

Fishrock123 commented 9 years ago

@bmeck I belive @trevnorris (& others) indicated they are inherently slower than callbacks.

I think the main reason is related to how they have to be internally structured.

(That is my understanding anyways, that being said generators are great.)

domenic commented 9 years ago

They are likely faster than callbacks as you can avoid generating a new call stack. In fact preliminary benchmarks show them to be faster than callbacks even without JIT.

Fishrock123 commented 9 years ago

OH.

Ok whatever Dominic said. XD

timoxley commented 9 years ago

Most of the stuff people are requesting here will be enabled by ES6/ES7, which has very little to do with node. I advise to wait quietly for these features to land or use traceur to get them today.

Node's core team has indicated they will adopt new language features as they make sense. That discussion has been had a thousand times and there's little point discussing it again as the features required aren't even available yet. Note, without any drastic, opinionated changes to core, you can wrap it with whatever abstractions you want e.g. visionmedia/co-fs i.e. if you want a different interface, just use a package or build one yourself that does what you want. This is likely going to be a better approach anyway – the APIs will be able to evolve faster and you get more fine-grained control over compatibility. Node should try to stay as vanilla as possible so such things can evolve in userland.

Making node easier for beginners by making node more like other platforms is not a particularly compelling argument. Neither JS or node have a problem with adoption, though they do have problems with people refusing to let go of legacy baggage they're lugging around from other ecosystems. Lack of async sugar doesn't actually prevent people from getting work done as there are a myriad of good solutions to augment async handling, available today, without requiring a single change to node.

Mickael-van-der-Beek commented 9 years ago

Seems strange to modify a language purely for adoption purposes.

It the end, even if sync methods would stay as training-wheels for newcomers, they would still be used by a good amount of the community in production just because they wouldn't know better.

The results would be counter productive because sure you'd have a larger user base but the overall performance of the apps produced would be inferior to having more difficult to grasp default concepts like async or generators. This could create image issues where Node.js would be portrayed slow just because a percentage of the community uses the easy route in production.

Completely removing them would be the best choice imo.

Just my two cents as a nobody who uses Node.js.

bjouhier commented 9 years ago

@Mickael-van-der-Beek The performance of the apps produced would not be inferior, it would be catastrophic. This would not create an image of node being slow, it would create an image of node being broken.

You'd need threads to get viable performance levels out of Sync calls (talking about network apps of course, Sync calls are ok for command line utilities, or for app startup code).

mvalente commented 9 years ago

Those pesky webservers apache and nginx, getting away with catastrophic performance all these years....

On Mon, Oct 20, 2014 at 10:51 PM, Bruno Jouhier notifications@github.com wrote:

@Mickael-van-der-Beek https://github.com/Mickael-van-der-Beek The performance of the apps produced would not be inferior, it would be catastrophic. This would not create an image of node being slow, it would create an image of node being broken.

You'd need threads to get viable performance levels out of Sync calls (talking about network apps of course, Sync calls are ok for command line utilities, or for app startup code).

— Reply to this email directly or view it on GitHub https://github.com/node-forward/discussions/issues/9#issuecomment-59845836 .

bjouhier commented 9 years ago

@mvalente They have threads!

bjouhier commented 9 years ago

@mvalente Answered too quickly: Apache has threads, nginx has an event loop and no Sync blocking calls.

mvalente commented 9 years ago

Indeed. That being so, a serverside JS engine can also be built using threads and/or an event loop without the need for (mandatory) async constructs

On Mon, Oct 20, 2014 at 10:56 PM, Bruno Jouhier notifications@github.com wrote:

@mvalente https://github.com/mvalente Answered too quickly: Apache has threads, nginx has an event loop and no Sync blocking calls.

— Reply to this email directly or view it on GitHub https://github.com/node-forward/discussions/issues/9#issuecomment-59846392 .

Fishrock123 commented 9 years ago

using threads

JS doesn't have "threads" that you can just "use" in any current VM that I know of

without the need for (mandatory) async constructs

Considering that "sync" io blocks and that JS runs in a single threaded environment, yeah only if you want it to be awful.

It's better to teach people how to do things correctly for the language at hand.

Should we improve docs / guide / everything community and tutorials? yes Should you build a fully "sync" javascript thing? no

EDIT:

Should there be node alternatives that use not-v8? probably, maybe?

bmeck commented 9 years ago

@mvalente Apache creates new run contexts (could be a thread, could be a CGI process, fast CGI process [which in turn gets to make its own run context], who cares) and then pipes data into that process. It is up to that context to created overlapped IO and has very little to do with apache's core. Also, not sure how this relates to mandatory async syntax when apache does not even mandate anything to the run context except that it will pipe in data as it gets it and read data as the context produces it (which may not be done synchronously prior to the end of the input data). NGINX does a similar approach except using an event loop rather than run context pooling (take note that various Apache tuning can turn it into async IO [use event mode instead of worker mode]).

Overall I am just curious why this matters since most people are not coding directly against the server internals.

rlidwka commented 9 years ago

Should there be node alternatives that use not-v8? probably, maybe?

Yes. I'd definitely like SpiderMonkey alternative, because then I can try the latest ES6 features without any compilers. Or for comparison with v8, easily point out when certain node.js bug is caused by js engine for example.

I heard people work on this, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1005411 , I'd like to see any news though.

mvalente commented 9 years ago

There are some misconceptions in some comments that would be too long too refute.

Fact: there are several alternatives for serverside JS that dont demand async use: SilkJS, JSlibs, TeaJS, Persevere, GPSEE, etc, etc. There's been a module for Apache called mod_js for sometime. Hell there are some of us (me) that actually worked with SSJS in the early 90s using Netscape's Livewire.

Why not use one of them, right? Because of potential risk of work on them being discontinued. A version by Mozilla would solve for that. And aditionally bring credibility.

Does it have to be sync only? No. Does it have to be async only? No. Would it be nice to have the option of choosing sync/async? Yes. Node forces the use of async without the need for it (see above). Would it be great to have a SSJS option coming from Mozilla that focused more on sync? Yes. Would it need to be sync only? No, it could have async primitives, but main focus on sync. Why? Because there are a lot of programmers out there coming from PHP, Python, Perl that find the functional/async programming paradigm to be too difficult and when trying to learn it go into the dreaded callback hell.

SSJS didnt show up in the last couple of years https://developer.mozilla.org/en-US/docs/Archive/Web/Server-Side_JavaScript/Walkthrough

And Node didnt show up in the last couple of years as well http://mvalente.eu/2009/11/25/requirements-for-a-modern-web-development-framework/

Or in 2008 http://www.infoq.com/news/2008/03/tsa-working-group-site http://goo.gl/PYZY35

Jus my 2 cents. I would like to have a sync paradigm SSJS solution. Preferably coming from Mozilla.

mikeal commented 9 years ago

JS doesn't have "threads" that you can just "use" in any current VM that I know of

There actually has been experimentation using v8 isolates in a "thread like manor" for sync style network operations. None of them really took off because it's much slower than the approach Node has taken.

mikeal commented 9 years ago

Node's core team has indicated they will adopt new language features as they make sense.

This is slightly misleading. The core team has said on many occasions that they will maintain a lack of opinion about the maturity of language features and adopt them as they land in v8. If they land in v8 with flags, they are in node with flags. If they land without special flags, they'll be in without special flags. I don't think anyone has ever advocated that features available in v8 be kept from Node users.

This should be enough for the community to adopt them. Node's core APIs won't be adopting new patterns until long after they are proven in the community, if ever. That's a good thing, some of the most troublesome parts of Node are things we adopted too fast and now wish were just modules.

The biggest concern keeping people from these features isn't "core adoption," it's not even v8 adoption, it's a lack of consistent releases that take new versions of v8 as they implement new features.

mvalente commented 9 years ago

One aditional comment regarding the "mandatory" use of async/callback primitives from some recent zealot NodeJs converts: async/callbacks are a way of implementing messaging in programming. There are other messaging options like events, pubsub, promises streams. Personally I prefer events and pubsub.

greelgorke commented 9 years ago

why is this even a discussion here? you want to go sync-style? go for it, there are plenty of options. node.js core api is as low level as it makes sense, and probably should be even lower level. there is the most primitive async model implemented, which can be wrapped into higher lvl constructs. just do it.

if some ppl find async difficult, then point them to the right tool for them. so whats wrong with that? sync+threaded style isn't easy either, why is learning effort even a fact?

bmeck commented 9 years ago

@mvalente it sounds like you want:

  1. SpiderMonkey instead of V8
  2. Sync instead of Async
  3. Threads instead of EventLoop
  4. An IO multiplexer instead of managing IO (Apache comment?)

I am not sure this even sounds like Node, it is comparable to telling PHP/python/perl to move all sync stuff to allow async and change out the underlying IO and runtime.

While some argument could be made for PHP/python/perl programmers having difficulty with Node's paradigms we should remember that Node was created in an opinionated manner and has not had problems with adoptions (quite the opposite). I feel it would be outrageous (literally) to change all of the underlying and move away from JavaScript convention and design patterns to satisfy an adoption concern that simply is not present. The number of hobbyist and enterprise developers using node not just as an HTTP server but as a general tool makes adoption a hard sell. The sheer amount of code academy and acceptance of JS for almost all client side code also makes the difficulty to learn a hard sell.

mvalente commented 9 years ago

"you want to go sync-style? go for it, there are plenty of options"

Yes. All without "relevant/credible" backing that would assure it would be available long term.

"SpiderMonkey instead of V8" Yes. Preferably.

"Sync instead of Async" Yes.

"Threads instead of EventLoop" Not necessarily. But yes.

"An IO multiplexer instead of managing IO" Yes.

"I am not sure this even sounds like Node" Precisely. Thatś why I would like an alternative.

" I feel it would be outrageous (literally) to change all of the underlying" I'm not arguing for that. I'm arguing that, since Node is very unlikely to provide sync primitives (as we can see from this discussion, it has become a religion war like emacs/vi), I just think that an alternative to Node would be to provide a sync implementation of the primitives.

"sheer amount of code academy and acceptance of JS for almost all client side code" I would argue that up until a couple of years ago (and even today) client side JS mostly used events for messaging and the use of callbacks were/are rare. I know long time JS programmers that find it difficult to get into the async/callbacks mindframe.

sam-github commented 9 years ago

Its reasonable to want an alternative to node, but why is this conversation here? How is building a not-node relevant to moving node forward?

Fishrock123 commented 9 years ago

I don't think it is. This should probably be closed. (& locked maybe)

greelgorke commented 9 years ago

@mvalente then just go for vert.x or something. really, no offense, but what you're asking for sonds not like a node other way, but an other tool