7 ms·
Fogus: Node.js should become its own language
- jasongullickson 15y agoI'm all for a new version of Javascript that eliminates the junk and keeps just the "Good Parts", but I'm averse to anything that serves to abstract away the bad parts by building a subset of functionality on top of the existing version javascript for a niche application (server framework in this case, other cases include cappuccino for UI, coffeescript for...everything? etc.) The Javascript that can be used only via add-ons is not the eternal Javascript...
- KeithMajhor 15y ago"My problem with Javascript has always been that expertise is defined more in terms of understanding its faults rather than its features." That's mostly just true for browsers. Javascript itself has very few faults. My biggest annoyances with the language are: Lack of lexical scope, no trailing commas and semicolon usage that differs from C. I could complain all day about my annoyances with browsers (or just IE).
- wladimir 15y agoMy most common annoyance about Javascript is the lack of bound methods like in Python Ruby etc. When you specify callbacks, you always have to provide the value of 'this' as well. If you forget, it's basically random and you're in for some heavy debugging.
- Cushman 15y agoYou should also try CoffeeScript. dosomethingasync => #etc will automagically bind the closure to the current value of this.
- demallien 15y ago'this' is evil in Javascript. The very first line in any constructor function that I write is: var that = this; From then on, I use 'that' instead of 'this', relying on closure magic to make things work. You never have to worry about how the function is bound thereafter.
- wladimir 15y agoThanks. I think I like that solution, as it's extremely simple. Are there any drawbacks? CoffeeScript is cool, as it is basically "Python in JS" but I have some resistance against languages that convert to other languages. I'm not so sure why.
- demallien 15y agoNo, no drawbacks that I'm aware of. You're basically using a closure to bind the object to the callback, instead of using Javascript's weird 'this' binding rules, that's all...
- pygy_ 15y agoExcept that Javascript has lexical scope. Use the var keyword to define local variables. foo = function(){ var bar=0 return function(){ bar=bar+1 return bar } } baz=foo() baz() // => 1 baz() // => 2 baz() // => 3 bar; // => ERROR: bar is not defined
- udp 15y agoThey're "hoisted" and only local to the function, though. I'd (personally) prefer it if it worked like C, and a variable was defined from the "var" statement until the next closing brace. Then you could have a variable local to one branch of an if statement, etc, without faking scopes by abusing closures (eg (function() { })(); ). And nested loops that both use "i" would work.
- deleted 15y ago[deleted]
- sedachv 15y ago"I'd (personally) prefer it if it worked like C, and a variable was defined from the "var" statement until the next closing brace." It does work like C. The scoping you're talking about was introduced in C99.
- cyrus_ 15y agoSpidermonkey (or whatever they are calling it nowadays) supports this using the "let" keyword, fwiw.
- KeithMajhor 15y agoTry this: for ( var i = 1; i < 10; ++i ) setTimeout( function( ) { alert( i ) }, i * 250 ) You might expect it to alert 1..2..3..etc. It actually alerts 10..10..10..etc.
- udp 15y agoThat's because closures actually capture the variable, not the current value of it. They'd be a lot less useful if they just made a copy of the variables...
- swannodette 15y ago> Javascript itself has very few faults Having coded JavaScript professionally and enjoyed it thoroughly for 6+ years now, I respectfully degree. The Harmony project shows just how much work there is to be done to make JS more fun/practical to use day in and day out.
- fogus 15y agoJavascript itself has very few faults. We disagree. Signed, Douglas Crockford, Jeremy Ashkenas, and Brendan Eich
- KeithMajhor 15y agoCould you elaborate?
- dminor 15y agoCrockford wrote a book titled "JavaScript: The Good Parts", which more or less implies there are bad parts as well.
- dionidium 15y agoI think maybe you mean to say that you wish JavaScript had block scope. Lexical scope, it has.
- Cushman 15y agoWhy would you write this: [long_io_operation with callback] When you can instead write this: [long_io_operation without callback] Off the top of my head, I'd say because "var result = long_io_operation(req);" is not only not self-documenting but actively deceptive if long_io_operation is an asynchronous call. I'm not sure I see what's to be gained by pretending closures don't exist.
- fogus 15y agoIt's not closures that I hope to avoid, but callbacks.
- metabrew 15y agoIt's not deceptive if you have a preemptively multitasking runtime that you trust (like the Erlang VM); it's a much more natural way of writing code. Single-threaded, event-driven callback spaghetti makes code harder to read, and inherently means more code. If someone took v8, added lightweight coroutines, and wrote a preemptive scheduler for it, I bet you could massively reduce the SLOC count for large node.js apps.
- sovande 15y ago> It's not deceptive if you have a preemptively multitasking runtime that you trust That may be so, but since Javascript is inherently single threaded _and_ this is about javascript I agree with Cushman that it is indeed deceptive.
- jerf 15y agoBut we aren't talking about Javascript. It's about a theoretical replacement language. Also, the reason you care about the "synchronicity" in the first place is because your environment forces you to care! When it all Just Works (TM), you don't care whether it's "synchronous" or not. That's a deficiency in your language, not a feature. I'm not theorizing. I program in this sort of language all the time. You worry much more simply about how long something will take, which you can never not worry about, rather than how many bits are "synchronous".
- ericmoritz 15y agoall I'm asking for with Javascript is a shorter function keyword. Let me have dosomethingasync(f() { }); With a language so dependent on callbacks, anonymous function are so verbose.
- Cushman 15y agoTry CoffeeScript. dosomethingasync -> #etc
- balakk 15y agoIs it ML week on HN? Sounds like everybody has got ML envy now..
- hasenj 15y agoI prefer coffee-script. It also works in the browser. http://jashkenas.github.com/coffee-script/ http://jashkenas.github.com/coffee-script/
- raganwald 15y agoThe good news for fogus is that everyone who prefers CoffeeScript validates the idea that an alternative syntax is enough of a win to be worth the adoption headaches.
- hasenj 15y agoIt's not just syntax, but some semantics too. Last expression in a function is returned. This includes assignment statements which are in fact expressions. foo = () -> a = bar() z = () -> if a b = fu() else b = kar() Here, foo returns the function z, and z returns either fu() or kar() while assigning the value to b One could argue this is just syntax but I think this way beyond the kind of thing that comes to mind when somebody thinks of "syntactic sugar".
- Homunculiheaded 15y agoDespite all of the weirdness of JavaScript, the lack of implicit return is it's biggest design flaw imho. The functional/scheme-like virtues of JS are well touted, but this small missing feature means implementing them always requires the slight but constant overhead of ending every expression with 'return', which then means that programming in a way which should be natural to javascript, isn't.
- jashkenas 15y agoFYI, you don't have to include an empty parameter list for defining functions that don't take any arguments. Just the arrow will do. foo = -> a = bar() z = -> if a b = fu() else b = kar()
- irahul 15y agoBut whatever he is after have to be much more lucrative than writing coffeescript. Apart from pleasant syntax, coffeescript also improves upon semantics where it can - this binding, lexical scoping etc etc. People are willing to adopt Coffeescript because it compiles to javascript, it has improved semantics and clean & mostly familiar syntax. To sum it up, the inertia is small when moving from JS to cofffeescript. That doesn't look like the case with funode.
- joelangeway 15y agoMy greatest hope is that the makers of node.js will continue to abstain from language changes. Some inconvenient syntax is a small price to pay for the confidence that node.js isn't going to get turned into another regurgitation of Java meets Perl by hordes of perfectly well meaning but unsatisfiable programmers who want everything to work like the things they know. I don't mean to insult the makers or users of other languages, just to highlight the distinction of Javascript.
- moomin 15y agoDon't get me wrong, this could end up being the best thing since sliced bread, but the advantage of closures is that a higher-order approach can work wonders. Just take a look at async.js. For me, more interesting than a pure assault on callbacks would be to see if you could handle more asynchronous scenarios, using async.js as a baseline. e.g. callback waterfall, callback when all children are finished, callback when any children are finished
- randylahey 15y agoI wish this was rated higher. I don't understand the fuss about "spaghetti code". Do all those people write spaghetti code in other languages? Because I see that not as a language failing but as sloppy programming. What's so hard about this to get a sequential execution of functions/blocks, error'ing out on the first error: async.waterfall( [ function (callback) { // do thing 1 callback(); } , function (callback) { // do thing 2 callback(); } , function (callback) { // do thing 3 callback(); } ] , function (error) { if (error) { // ohnoes errors } // all done! } );
- travisglines 15y agoAs someone who has spent the last six months coding in Node.js, I completely disagree with this notion. One of my favorite advantages of Node is in fact that it is based on javascript. When building my application I can share code between client/sever side (string formatting methods for example) and don't need to do any mental context switching when it comes to languages. I've developed in javascript for years and all that I have learned doesn't go out the window here, all I need to do is learn how to use a few libraries. The "faults" of javascript are primarily inexperience with event looped architectures that use callbacks (people complaining about having to use callbacks and the spaghetti code messes they make), people remembering the past horrible browser implementations of it (where something would work/be fast in one browser and not another ... Internet Explorer I'm looking at you) and confusion over how prototypical languages work vs. standard OOP. Callbacks aren't that bad and a few extra nesting levels shouldn't create chaos in your code. Since its based entirely off of one javascript implementation (V8) the cross browser stuff is gone. How it handles OOP is different, just watch these videos first and you'll be fine: http://www.yuiblog.com/blog/2007/01/24/video-crockford-tjpl/ http://www.yuiblog.com/blog/2007/01/24/video-crockford-tjpl/ As far as speed goes it gets huge benefits by being javascript. Every time the Google coding machine feels like making V8 a little faster, Node gets faster too. Yes its different, no its not worse ... its better but takes some getting used to.
- scott_s 15y agoI think the fundamental objection fogus has is that the language does not support the programming model. For example, I can program object-orientedly in C, but that language does not help me do it. I have to do much of the work myself. So you can program in JavaScript in an event-based way using Node.js, but JavaScript itself does not help you much in doing so. It requires that you do most of the work yourself - work that is mechanical, and basically requires that you be a human compiler. Disclaimer: I don't program in JavaScript or Node.js. So I'm talking from conceptual understanding, not experience.
- DTrejo 15y agoIt requires that you do most of the work yourself - work that is mechanical, and basically requires that you be a human compiler. It would be a good idea to write some JavaScript before you make statements like these with so much conviction.
- DTrejo 15y agoNot sure why he uses this as a code sample, as it's also not how someone would write code (though I suppose he is entitled to his style). The original from the article function do_request(req) { return long_io_operation( req, callback=function(results) { return create_something_from(results); }); } How it might be written if you saw it in a codebase function do_request(req, callback) { long_io_operation(req, function(err, results) { callback(err, create_something_from(results)); }); } It seems like the article is not finished, so I can understand that there might be questionable sections. Also you'll note that he forgot the `error, results` argument pattern for callbacks, making me think that he is not terribly familiar with node.
- Fester 15y agoFix the language, then fix event processing approach, then spend 10 yeard maturing in the highly concurrent environments and end up being Erlang. w00t.
- jerf 15y agoSince fogus is responding here: Other than hitching your wagon onto the fantastic hype storm that Node.js has generated, which I must say is a good move overall, reading your target description, why not start with Haskell or Erlang? You could start from there and mutate out but actually have a library base to start from. Or one of the languages sitting on top of Erlang like Reia. (Or discover that you don't need to mutate away after all.) Starting from scratch is going to be difficult at this point; by the time you even have a half-decent stack you're going to be way behind. (At the very least... you do realize this has been done and you don't have to start from scratch, right? Rather a lot of Node.js users have exactly the cognitive holes I'd expect from not knowing that Node.js is at best "keeping up", rather than being anything like cutting edge. And I'd say this style of programming was actually on its way to the dust heap of history before being brushed off and gotten a shiny new coat of paint sprayed on... it really doesn't work very well....)
- MrMan 15y agoI will upvote you if you explain what you mean by the last part about "this style of programming" previously being on its (it's? anyone) way out. Do you mean an asynchronous style using callbacks?
- jerf 15y agoYes. Asynchronous style using callbacks has been done many, many, many times, and it really doesn't work very well. It does small things quickly, but have you noticed the number of complaints about how Node.js produces spaghetti code increasing lately, quietly and slowly but steadily? It's still buried under the hype, but expect it to get worse. And not "get worse before it gets better", just... get worse. I laid it out more at http://news.ycombinator.com/item?id=2370303 http://news.ycombinator.com/item?id=2370303 . Javascript doesn't particularly bring any abstraction capabilities to the table that Perl (POE, Event::Lib, IO::Async), Python (Twisted), or Ruby (EventMachine) doesn't, and current Javascript is actually deficient in the abstraction department by comparison. (The latest ECMAscript spec can compare to them, so Javascript will get there. Something like Python generators allow you to string together a couple more tricks together before the complexity becomes a problem, and Javascript will eventually have this.) They all result in programs that end up the same way. There are some tricks you can play that improve the situation a bit over raw callbacks, like trying to sequence them, but composing these tricks together gets harder and harder the fancier you get. None of those libraries really took off and some of them I know had way more effort poured into them than Node.js has seen yet, like Twisted. And it's because the style, combined with language runtimes that can't manage the scheduling for you while retaining the code context, has certain inevitable results. You can (and should!) delay the inevitable, but it's still inevitable. At the very least, I would suggest that if you going to consider using Node.js you should be aware of the fact that it's not a blindingly new thing, it's a relatively well-explored space being translated into a new language, and you can get a good sense of the tradeoffs from the many previous explorations of this space. There are still places where it may be the right choice; as I said in that other message, I have chosen event-based coding in another context because it was still the right choice. But I knew the tradeoffs going in, and took steps to mitigate them, rather than being blindsided by them.
- kreek 15y agoHow about Node.as? Flash doesn't get much love these days but I've always thought ActionScript 3 would make a great server side language. It's more like other OOP languages, has an event model like JavaScript (sync or async), and doesn't have many of JS's idiosyncrasies. Edit: http://haxe.org/ http://haxe.org/ is based on AS3
- jpravetz 15y agoI agree. I had to go back from AS3 to AS2 for a project and it felt like a step backwards, and AS2 is more like Javascript. Adobe has also open sourced the AS3 runtime. But of course the practicality is that we have Javascript in browsers, and there's a big get-the-job-done benefit to using a common language.
- faceplant 15y agoAS3 is based on ECMAScript 4, which was expected to become the new standard many years ago but became a dead-end after the ECMAScript committee abandoned it. That's why there's no "4" anymore between ES3.5 and ES5... ActionScript is it.
- MrMan 15y agoTake a look at this, I am sure it has been posted on HN before: http://beamjs.org/ http://beamjs.org/ This allows you to trade off all the cool speed of V8, but running node.js singlethreaded, for running on an alpha port of V8 for the Beam VM. If you want to sidestep the problems with Node.js, but keep the good parts, this might be a way forward. Additionally, JS on the Beam VM can seamlessly interact with any other Erlang code, so you get all kinds of other benefits that are erlangy.