views:

344

answers:

3

I'm new to Node.js and I have been reading about Narwhal that is a framework based on Rhino.

My questions:

  1. If I'm using Node.js, should/could I use Narwhal and it's libraries/modules?
  2. Aren't the libraries/modules in Narwhal IO-blocked (why Node.js got this huge popularity)?
  3. Is Node.js only for creating Web servers or is it for creating general applications, just like Narwhal?

Thanks.

A: 

Node.js should not be compared to Narwhal, instead it should be compared to Rhino. Like Rhino, Node.js is a javascript interpreter.

Node.js conform to the CommonJS specification for modules so all libraries for it are CommonJS compatible. It looks like Narwhal is also CommonJS compatible which would mean that they would be usable in Node.

But first look at Node's standard modules since there seem to be a lot of overlap there with Narwhal. Also, have a look at the list of 3rd party modules available for Node.js: http://github.com/ry/node/wiki/modules


Additional answer:

Ah, I see now. Narwhal is indeed like Node. You said that Narwhal is a framework which threw me off. I see now that it is not. Indeed, the intro page says that you can run frameworks like Nitro on top of the Narwhal interpreter.

The difference between Narwhal and Node is basically Narwhal uses a pluggable javascript engine architecture while Node just use V8. Both are javascript "shells" proper (lets call them that for now to avoid confusion with the term "interpreter").

I'm not sure how far one can take CommonJS libraries written for either platform and use it on the other platform. I would guess certainly all the pure-JS libs are cross compatible. Node does use a nonblocking I/O model so some binary modules for Narwhal may not work correctly on Node.

Node does stress callback style programming though (to make maximum use of nonblocking I/O). For a seasoned JS programmer this is not an issue since we're used to setTimeout(), XMLHttpRequest etc. In fact, as a seasoned JS programmer, I sort of prefer Node's style. Narwhal feels too much like C.


Examples:

Here's what I mean by the different "feel" of Node over Narwhal.

In Narwhal, the example for slurping a file is:

var fs = require("file");
var data = fs.read(myfilename); /* code stops at this point
                                 * until all data is read
                                 */
/* process data here */

In Node.js it is:

var fs = require('fs');
fs.readFile(myfilename, function(err,data) {
    /* process data here */
});

/* readFile returns immediately and code continues
 * executing while file is being read
 */

Just like setTimeout, reading files in Node is asynchronous (your code need to wait for the hard disk to seek and read data during which time you can run other pieces of code).

slebetman
But isn't Rhino comparable with V8?
never_had_a_name
Yes and no. Rhino.java is comparable to V8 and Rhino.jar is comparable to Node.js. One is a library of the engine while the other is an application that makes the library executable.
slebetman
Node.js is not a JavaScript interpreter. V8 is a JavaScript interpreter, as is Rhino. Node.js is an evented I/O framework for V8. Wikipedia provides a fairly good description of what Node.js is: http://en.wikipedia.org/wiki/Node.js
echo-flow
@echo-flow: But node is not a framework though. It is an executable. More specifically, it is a javascript shell (most languages refer to them as interpreters) in the classical sense that bash and tclsh are shells. Take the tcl programming language for example. Colloquially people call tclsh the tcl interpreter but it is not. The real tcl interpreter is a C library that you can include in your C programs and tclsh was originally shipped as an example of how to do it.
slebetman
@echo-flow: Also, neither Node.js nor Narwhal claim to be frameworks themselves and the usage of the term framework in the wikipedia article is contrary to wikipedia's own definition of what frameworks are.
slebetman
A more fair comparison would be: var fs = require("file"); var data = fs.read(myfilename);The main difference is Narwhal's APIs are mostly synchronous while Node's are mostly asynchronous.
tlrobinson
@tirobinson: unpdated my answer although it doesn't change anything. I wasn't trying to show succinctness but rather the different philosophies behind each implementation.
slebetman
I just realized that there is a sort-of standard name for what Node.js is (not sure about Narwhal because I'm still not sure how it's implemented). Node.js is a "chrome" or "environment". Node.js is comparable to Firefox or Internet Explorer in that like Firefox and Explorer it is a program with a javascript engine embedded within it. And like Firefox and Explorer it also exposes its own proprietary and non-standard JS API along with the standard JS API that it supports. I'm not sure if anyone would call Firefox a javascript "framework".
slebetman
+13  A: 
  1. If you're using either Node or Narwhal, only use packages and modules that advertise compatibility with your respective engine. There are presently many nuances to writing applications, packages, and modules that work on both engines. Kris Zyp from Dojo has put quite a bit of effort into making his packages work on both systems and I cannot think of anyone else.

  2. Narwhal's input and output modules are blocking, much like the standard libraries for Python, Ruby, Tcl, Perl, C, Java, and so on.

    There is, however, a class of applications that cannot be effectively written with blocking IO, like games that maintain their state in the memory of the server and stateful communication with numerous clients. Only experimentation can reveal whether threads or event loops perform better for individual applications. But, it is furthermore difficult and perilous to write "evented" applications in most programming languages and library ecosystems because the benefits of using non-blocking IO can be quickly obviated by making use of any blocking IO, and blocking IO is frequently hidden in the layers of architecture, even as low as the operating system interface. Node is exciting because it is creating an ecosystem with strictly asynchronous IO, which makes it the first system in which this class of application is reasonably easy to write.

    Proponents like Doug Crockford and Mark Miller argue that asynchronous event loop programming is the way most applications should be written because it is easier to reason about data flow, concurrency, and security in these systems and to blindly compose such subsystems without compromising correctness or integrity.

    However, if you want to take advantage of JavaScript as a language but do not want to buy into the additional complexity of event-loop programming, Narwhal is designed to work on both JavaScriptCore, the fast JavaScript engine behind Safari, and also on Rhino. Using Rhino gives you access to Google's AppEngine. Narwhal was designed to give you flexibility of your JavaScript engine, but it did not account for Node's IO model. Narwhal is also used extensively by the 280 North software ecosystem, for build tools and servers for Cappuccino Objective-J applications, like Jake and Jack.

  3. Both Node and Narwhal can be used for general applications and web servers. Node is particularly well-suited for network clients and servers. Narwhal is particularly well suited for Unix-style programs and JSGI, CGI-like web servers, and is designed to run JSGI applications on a variety of web servers without alteration.

Writing applications that work on both Narwhal and Node is difficult but possible. Writing "packages" that work for Narwhal and Node is possible but must be done deliberately. If a package does not advertise that it's been designed and tested on both Narwhal and Node, you can bet it will only work on one or the other.

io: Modules that do not make use of IO subsystems, like parsers, formatters, encoders, and decoders, are particularly well suited for code sharing between both Narwhal and Node.

packages: There are differences in the way packages are laid out for NPM (Node Package Manager) and Tusk (Narwhal's package manager). They both use package.json, but "dependencies" have different meanings on each. There is an upcoming patch for Narwhal that allows it to tollerate this inconsistency. When packages are installed in Narwhal, they all share the same module name-space, like Ruby. With NPM, each package has a subtree of the module name space by the same name as the package.

modules: Node and Narwhal both provide varying extensions to the CommonJS module specification.

  1. Node provides additional free variables like __dirname.
  2. Node allows the exports object to be reassigned with module.exports = x.
  3. Narwhal provides require.once(id, scope) for executing a module once (regardless of whether it has been previously loaded) with extra free variables in scope (these are sometimes erroneously called "globals").
  4. Node does not provide the CommonJS module.path for the file name of the current module.
  5. Narwhal and Node provide incompatible systems for extending the module loader to handle alternate languages for modules, like CoffeeScript and ObjectiveJ.
Kris Kowal
oberhamsi
+2  A: 

I would just add RingoJS to the mix. It is Rhino-based CommonJS system, but comparing to Narwhal it is much more mature (its primary author has been developing its predecessor Helma for years) and by following both gits its development RingoJS seems to be much more active. Development of narwhal seems to be kind of slow these days.

mcepl