Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why not a real alternative to Node? #9

Open
mvalente opened this issue Oct 17, 2014 · 109 comments
Open

Why not a real alternative to Node? #9

mvalente opened this issue Oct 17, 2014 · 109 comments

Comments

@mvalente
Copy link

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
Copy link

zzmp commented Oct 17, 2014

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
Copy link
Member

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
Copy link

rvagg commented Oct 17, 2014

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
Copy link

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
Copy link
Member

Qard commented Oct 17, 2014

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

@rvagg
Copy link

rvagg commented Oct 17, 2014

@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
Copy link
Author

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
Copy link

domenic commented Oct 17, 2014

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
Copy link
Member

rmg commented Oct 17, 2014

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
Copy link

bmeck commented Oct 17, 2014

@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:

  • JXCore
  • Vert.x
  • SilkJS
  • Ringo.js
  • Rhino (Dyn.js now really)
  • WScript (now that takes me back, and this is the worst for threads... ever...)

@bjouhier
Copy link

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
Copy link
Member

medikoo commented Oct 17, 2014

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
Copy link
Member

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
Copy link
Member

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
Copy link
Author

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
#9 (comment)
.

@bmeck
Copy link

bmeck commented Oct 17, 2014

@mvalente why not use SilkJS then?

@mvalente
Copy link
Author

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
#9 (comment)
.

@mikeal
Copy link
Member

mikeal commented Oct 17, 2014

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
Copy link
Member

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
Copy link

@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
Copy link
Member

Qard commented Oct 17, 2014

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
Copy link
Author

"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
#9 (comment)
.

@bmeck
Copy link

bmeck commented Oct 17, 2014

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
Copy link

@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
Copy link
Member

Qard commented Oct 17, 2014

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
Copy link
Member

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
Copy link

bmeck commented Oct 18, 2014

@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
Copy link
Member

@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
Copy link

domenic commented Oct 18, 2014

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
Copy link
Member

OH.

Ok whatever Dominic said. XD

@domenic
Copy link

domenic commented Nov 5, 2014

@trevnorris re: fill, http://people.mozilla.org/~jorendorff/es6-draft.html#sec-%typedarray%.prototype.fill

But, in general, thanks for the detailed comparison. I still would hope that if we were starting from a world in which typed arrays already existed, we wouldn't invent Buffers. The uninitialized-memory thing seems like the only potential actual dealbreaker.

@trevnorris
Copy link

@domenic Thanks for the link to the specification.

One difference between that fill() implementation and what's coming in v0.12 is that:

var b = Buffer(8).fill('abcd');
console.log(b.toString());
// output: 'abcdabcd'

Minor, but still useful.

Also, was I mistaken that TextDecoder doesn't support ISO-8859-1? I hope it does.

@domenic
Copy link

domenic commented Nov 5, 2014

Minor, but still useful.

Yeah, in general it seems like Buffer has more ergonomic text-manipulation stuff.

Also, was I mistaken that TextDecoder doesn't support ISO-8859-1? I hope it does.

You can decode iso-8859-1 (aka windows-1252, and lots more), but you can only encode as UTF-8 or UTF-16.

@trevnorris
Copy link

You can decode iso-8859-1 (aka windows-1252)

If that were the case then I wouldn't expect the following:

var b = new Buffer(1);
b[0] = 159;
// 'binary' is V8's one-byte encoding (ISO-8859-1)
b.toString('binary');
// output: '�'
// expected: 'Ÿ'

That might just be a V8-ism, and is possible it changes. Just FYI.

but you can only encode as UTF-8 or UTF-16.

Ah, that's painful. Know if there's any discussion about extending that in the future?

@domenic
Copy link

domenic commented Nov 5, 2014

That might just be a V8-ism, and is possible it changes.

Yeah, not sure what relation V8's encoding has to windows-1252/iso-8859-1/etc.

Know if there's any discussion about extending that in the future?

Not for the web; the proliferation of non-UTF-8 text is harmful (I'm hoping we can remove UTF-16 actually...) and shouldn't be convenient. You can make the argument that it's more necessary for a server-side runtime I guess, but then again you can make the same argument that non-UTF-8 encodings are harmful and should be inconvenient (i.e. require user-created encoders).

@piscisaureus
Copy link
Member

TextDecoder has several pit falls. First is that it doesn't support ISO-8859-1

Well node doesn't either. The "binary" encoding is effectively latin-1.

@piscisaureus
Copy link
Member

@domenic @trevnorris I think it's be better to move TypedArray/Buffer talk to a separate issue

@jamlfy
Copy link

jamlfy commented Nov 5, 2014

In conclusion we have problems with the buffer and the character encoding? To construct an alternative

@5nyper
Copy link

5nyper commented Nov 22, 2014

An alternative to nose could be Dart, benchmarks prove the DartVM is faster than V8

@rlidwka
Copy link
Member

rlidwka commented Nov 22, 2014

An alternative to nose could be Dart, benchmarks prove the DartVM is faster than V8

I surely hope it's a joke. If not, I'll happily suggest to switch to Erlang instead. :)

@feross
Copy link
Member

feross commented Nov 22, 2014

Yo guys, let me tell you about Haskell... It's just like node (except not
really...)
On Sat, Nov 22, 2014 at 10:56 PM Alex Kocharin notifications@github.com
wrote:

An alternative to nose could be Dart, benchmarks prove the DartVM is
faster than V8

I surely hope it's a joke. If not, I'll happily suggest to switch to
Erlang. :)


Reply to this email directly or view it on GitHub
#9 (comment)
.

@5nyper
Copy link

5nyper commented Nov 22, 2014

No it isn't a joke, what I HOPE that your reply is a joke.

@Fishrock123
Copy link
Member

looks like we are switching to erlang guys

@5nyper
Copy link

5nyper commented Nov 23, 2014

Take a look at this then: http://www.infoq.com/news/2013/05/Dart-Java-DeltaBlue

@Fishrock123
Copy link
Member

Ok, node is named node.[javascript] for a reason. Quite frankly there are many other languages already out there for I/O (go, rust, java, etc).

I think anything that isn't about node as a javascript I/O is definitely off-topic. (Not that this thread hasn't been for a long time.)

@kav
Copy link

kav commented Dec 4, 2014

It seems that the primary confusion here is this: Node was designed as a platform for writing async server applications that happens to use javascript.

Many folks seem to think node is for writing server applications in javascript and happens to be async.

Thus they confuse the urge to remove problematic Sync constructs as zealotry when it's a totally rational move for a non-blocking server environment. Conversely they can't figure out why everyone gives them looks when they want to add a solid synchronous model. Which does make perfect sense if you just want one language on your client and server.

Node is non-blocking and async first and foremost and uses javascript secondarily. Adding a bunch of sync stuff thus doesn't really make sense from a fundamental standpoint.

This does seem to come up an awful lot. More and more as big companies join the party. Does anyone have a great resource to point to that explains the what and whys of node? Might help explain the crazy looks and perception of zealotry.

TL;DR
It'd be easier to drive planes if they didn't have wings and go up in the air. But then we'd call them cars, not planes.

@domenic
Copy link

domenic commented Dec 4, 2014

Node is non-blocking and async first and foremost and uses javascript secondarily.

Asserting this does not make it true.

@mvalente
Copy link
Author

mvalente commented Dec 4, 2014

And then there are people who have been on the JS serverside camp for
more
than 6 years and who find it funny to see displays of crazy looks and
zealotry which
are actually proper for the newly converted.

http://mvalente.eu/?s=Tracemonkey&x=13&y=12

On Thu, Dec 4, 2014 at 5:49 AM, Domenic Denicola notifications@github.com
wrote:

Node is non-blocking and async first and foremost and uses javascript
secondarily.

Asserting this does not make it true.


Reply to this email directly or view it on GitHub
#9 (comment)
.

@Fishrock123
Copy link
Member

I hear io.js is a good alternative to node.js

@erikcorry
Copy link

@medikoo If you can boil down your large-heap performance issues to a reasonable repro, then the V8 team are very interested in bug reports. The GC of V8 is not as scalable as the JVM's, which is said to scale to dozens of threads and 100s of Gbytes, but 1.5Gbyte should be no problem.

Note that you may need to up the sizes of various limits. Primarily --max-old-space-size and --max-executable-size . You may want to experiment with --nouse-idle-notification too.

@medikoo
Copy link
Member

medikoo commented Dec 5, 2014

@erikcorry great thanks for that valuable information. I'll try to investigate that further and eventually I'll come up with some solid test case

@bnoordhuis
Copy link
Member

@medikoo Just a heads up, --nouse-idle-notification is a no-op in v0.10 and newer; I removed idle notifications in nodejs/node@d607d856.

@kaizhu256
Copy link

synchrounous io is legitimate in one-time calls like initializing server configuration and models. after spending 2 years as an async zealot, I've come to realize its very inefficient and brittle for writing nontrivial init code.

@mvalente
Copy link
Author

mvalente commented Apr 1, 2015

Oh, looky here! Building a real alternative to Node using Spidermonkey is actually possible, contrary to the naysayers...

https://github.com/jxcore/jxcore

http://jxcore.com/home/

@erikcorry
Copy link

Nice try, but I know what the date is today!

@mvalente
Copy link
Author

mvalente commented Apr 1, 2015

:-)

On Wed, Apr 1, 2015 at 9:23 PM, Erik Corry notifications@github.com wrote:

Nice try, but I know what the date is today!


Reply to this email directly or view it on GitHub
#9 (comment)
.

@Fishrock123
Copy link
Member

https://github.com/jxcore/jxcore

Cool. That's good, there should be options.

Our business is node/io.js. If we have the resources to one day make the js engine swappable, that'd be great. For now though, that simply isn't the case.

@mikeal Can you lock this?

@node-forward node-forward locked and limited conversation to collaborators Apr 2, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests