Why I'm Learning Node(rdegges.com) |
Why I'm Learning Node(rdegges.com) |
Most 'popular' languages these days are descendants of C in some form, which means that the differences between any two are very small, in the grand scheme of things. (I'm talking about programming paradigms here - I understand that things like running time and library support are real factors, but to me those define the implementation of a language, not the language itself).
Javascript may be different from most C-derived languages in that it promotes certain paradigms that others don't, but to me, it doesn't offer anything as a language that other languages that I like (and use) don't. Prototypal inheritance is familiar to me from Python (yes, you read that right), and functional paradigms (including first-class/higher-order functions and closures) are familiar to me from Scala and Lisp.
If we want to talk about actual implementation and the runtime environment, I'm still not convinced that Javascript has any real inherent advantages over other languages for most of the non-DOM tasks that people try and use it for. Maybe it promotes familiarity with a single language, but I see that as a detractor, not an asset.
So in the end, while Javascript may be 'more than just the DOM' these days, for me, that's still where its use case lies. Just because I can use it for other things doesn't mean I want to; for anything that I want to do other than manipulating the DOM, I can find an environment that suits me much better.
The most important thing about the choice of programming tools is productivity. Node.JS does not promise you any productivity gains. Node sells itself as a solution to "slowness" caused by "blocking IO". What's the solution? All I/O is evented! This means you have to write everything with callbacks.
You may see some very nice libraries/tools coming out around node.js, like jade, coffeescript, and stylus. These are all nice and good, and they do increase your productivity, but, only on the client side.
If you're looking for performance and non-blocking IO, use Go, it's much better at that.
Most of these negative things were (are being?) written by people who target Node's shortcomings without giving due concern to the areas it shines in.
Good Parts is definitely a good read. If anyone is looking for more reading materials on JavaScript, I had written a post about it recently: http://kishorelive.com/2012/02/23/my-javascript-reading-list...
If you're learning JavaScript to get familiar with front-end and UI, Node.js is just a distraction. Instead, my advice is to learn raw HTML/CSS/JS without frameworks.
You know those cheesy web-based "OSes"/Desktops that no one really uses? Building one is actually quite helpful to developing JavaScript skills. Try building a Window manager in HTML/CSS/JS. You'll go through the entire gauntlet of what JavaScript has to offer (e.g. closures, prototypes) while dealing with a practical front-end problem (DOM manipulation, CSS styling) while learning a lot about why the modern js frameworks are so useful (e.g. jQuery for DOM, backbone.js for MVC). You'll also start getting exposure to some basic decisions that make up the foundations of a good UI sense. I consider this sort of exercise much more appropriate for polishing front-end skills.
Other possible exercises include re-implementing common jQuery UI components - drop-down menus, trees, tabs, etc. But do them without jQuery. It might sound like reinventing the wheel, but learning fundamentals sometimes requires retreading worn out paths.
Any experienced programmer should definitely start elsewhere so he can make up his own mind about Crockfords ideas about how programming should be. While the book is ok-ish almost half of the material is about Crockfords personal preferences for coding style and can be applied to any language.
JavaScript - The Definite Guide by David Flanagan is in my opinion the best book on the subject. No other JS book comes even close in clarity and thoroughness.
http://www.amazon.com/JavaScript-Definitive-Guide-Activate-G...
http://www.gabordemooij.com/articles/jsoop.html
This approach also makes it possible to treat JS more like a traditional OOP language and it does not require external libraries, sugar code or new browser technology. It works in the most ancient browsers.
I can say without a doubt that my experience with Node has translated to some upside in terms of my front-end JavaScript abilities - being able to really master the ins and outs of JavaScript language itself has made it much easier for me to work with even some pretty nasty front-end bits.
In addition, you pick up a lot of tools in Node that are translatable to client-side JS development. Many of the unit testing frameworks work just as well at testing client-side code as they do server-side.
Begin with semantic HTML. It's really the basis. The best front-enders I know first write all the HTML for a project, and only then start adding CSS and JS. Learn why <b> is wrong and <strong> isn't. Make sure you're HTML validates.
Now go to CSS. It's really easy to add some colours or fonts. You learn CSS as you go. But there is one hurdle here: the box model. Learn about float:left, position:absolute, display:block and how they entangle.
This will be harder than you think. You will need to learn some tools to debug this. Install Firebug and the Webdevelopers Toolbar in Firefox and see how you can fix your layout. Browsers aren't that scary.
We're only learning here, so skip IE for now. That one is actually kinda scary. Though if you really want to learn front-end, it's all about browser differences.
And then Javascript. Now it will be easy. Stick with jQuery and connect with your Node instance with socket.io. Learn Backbone if you want to make snappy web apps. There's a lot to learn in this 'grey field' between back-end and front-end. But at least you now know front-end.
Anyway, I don't understand why the front-end is relevant at all. It's not the same problem, and the fact that most people do both doesn't mean that learning to do a good front-end will teach you to do a good back-end.
Famous last words.
I always wanted Python on the client (here's looking at you, Jython!) -- js on the server may be the closest thing I'm going to get.
The client, on the other hand, can persist data and objects through requests, and the only time it needs to be fully refreshed is on a full reload.
I did learn something from its event-driven callback system though. Made me realize I was approaching things the wrong way in a libevent-based daemon I'm developing in C.
I disagree. Firstly, CoffeScript is not confined to the client-side. Besides, there are some modules like socket.io for which you will hardly find any substitues in other eco-systems.
You're also discounting the effects of context shifts between two separate languages - one on the client side, and the other on the server side.
Lastly, I would like to know what you find productive about Go, that's not the case with either CS/JS on Node.
I know exactly what you mean, because that's what I thought a year ago. I was going on and on about this to everyone. Mea culpa.
Then I actually tried node and learned the functional side of JavaScript (I don't mean the semantics, which are very simple; I mean powerful LISPish design patterns). Now I don't think about callbacks anymore, because I have a functional toolkit that mostly hides them.
You say asynchronous coding makes simple algorithms annoying to write. So let's have an example. Read two files -- in parallel -- trap I/O errors and warn about them, otherwise merge and sort the files by line, write the result to a third file, and warn about I/O errors there as well. Simple enough?
My solution is 8 lines, formatted. It was very pleasant to write.
fork(
['lines.txt', 'lines2.txt'].map(function(name) {
return fs.readFile.bind(fs, name);
}),
check(console.warn.bind(console), function(a) {
fs.writeFile('linesOut.txt', a.sum().split('\n').sort().join('\n'), check(console.warn.bind(console)));
})
)
If you've seen enough JS to deduce what the lib definitions for fork() and check() might be, then this code will seem obvious -- almost trivial. Otherwise, you will probably claim shenanigans or 'spaghetti' because it doesn't look like insert favorite programming language/framework here.So it saddens me to hear people whining about this aspect of node -- partly because it recalls my own naivety, and partly because I know from experience that they're missing out on something great.
I'd say it's almost like writing in assembly. You have to write your code in some pseudo code first, synchronously, then translate that into the asynchronous callback spaghetti than node requires.
> Lastly, I would like to know what you find productive about Go, that's not the case with either CS/JS on Node.
Not having to write everything asynchronously?
I haven't actually used go, but the way goroutines communicate (and synchronize) with channels suggests to me (from what I've read/seen) that this callback spaghetti problem is non-existent in Go.
People say this over and over, complaining about nested callbacks and what not. I can tell you from experience that it is not true. I've been working on a Node application for a few weeks now. It is our first server side Javascript endeavour as a company, I had only tinkered with it in my own time before this. And the experience is pretty good. Writing in a more functional style makes me more productive and makes quite some problems more straightforward to describe (implement).
- The Reactor Pattern, a never-been-before paradigm.
- V8 and its mind-blowing speed.
- Evented I/O, a game changer.
- It also allows you to program all that with the best language known to man, Javascript, ON - THE - EFFIN - SERVER (zomg).
Hats off to the Node community though, they're getting good at emulating Rails' PR tactics of buzzwords, fluff and overblown hype.
Every language has solutions for non-blocking I/O, even the boring ones.
The better examples will be in a few years when programmers have more experience with Node and the projects' code reflect that.
I won't be returning back to Node after the project though because it reminds me of earlier days writing XML with Spring.
User-level threads are non-standard, and ordinary threads are too heavy. All forms of threads lose much of C's benefit due to the relatively heavy stack allocation per thread.
This is a sign of a not-fully-adopted paradigm shift. Like, when someone first learns a new (spoken) language, they translate it to their native language in their head.
Fluent speakers don't translate, they simply understand. Similarly, when you fully grok functional programming, coding with callbacks will cease to feel unnatural.
That said, it does take some getting used to, which is a real cost that needs to be considered when choosing Node.
A minor remark from my experience with functional programming, continuation-passing style is actually something I prefer to avoid.
I don't understand this comment. Javascript, while having first-class functions, does not have call/cc. This is the source of complaints that Javascript encourages callback-spaghetti. As people have mentioned elsewhere, continuation-passing style is meant for compilers, not humans.
This is why I said it's like writing assembly.
Edit: Found web.go. Screw it it's a long weekend, I'll give learning Go a go.
As for frameworks, it seems the http package comes builtin with a server and a url router. Also, Google's AppEngine supports Go.