Skip to content

Instantly share code, notes, and snippets.

@veselosky
Last active December 12, 2015 08:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save veselosky/4747369 to your computer and use it in GitHub Desktop.
Save veselosky/4747369 to your computer and use it in GitHub Desktop.
Toy: Node.js vs. Python

Not sure how I feel about Node.js after this experiment. Trying to wrap my mind around the fact that any function that performs I/O cannot return a value, but must instead take a callback that would operate on that value. Which means that any function that MIGHT one day perform I/O (or call something that does) cannot return a value, but must take a callback instead. In my mind, this makes it unsafe EVER to write a function that merely returns a value, unless what it is doing is pure calculation (in which case you could probably inline it).

This toy script takes a directory as an argument, finds all the files in that directory (without recursing), and prints their contents.

The Python version seems pretty straight-forward to me, easy to read, easy to write.

The Node version was harder to write, but only because of my inexperience I think. However, my first try had a subtle bug that caused it to produce the wrong output (commented).

What kills me is how path.exists() must take a callback, because it has to perform I/O (stat). Node doesn't implement the Python path.isfile and related functions, but if it did, it would have to take callbacks for those too. This adds code and complexity. And then there is that tail, six lines of punctuation to make the interpreter happy. Yuck.

I hate to think what the code would look like if I wanted to do something more complex with the output, such as concatenate all the contents into a third file, in order. Since I need them to be in order, I can't just let each callback write to an output stream, the order would be unpredictable then. I suppose I would need to create some kind of accumulator object, but then I would have to eat potentially a lot of RAM.

If this were a network application, would there be a way to guarantee that submitted data had been written before success was returned?

This is going to take my brain a while to get used to.

var fs = require('fs');
var path = require('path');
var argv = require('optimist').argv;
var dirname = argv._[0];
fs.exists(dirname, function(exists){
if (!exists) {
throw("Does not exist: " + dirname);
}
fs.readdir(dirname, function(err, files){
if (err) { console.log("Directory err: " + dirname + err); return; }
files.map(function(f){
var file = path.join(dirname, f); // BUG if you forget `var`
fs.stat(file, function(err, stats){
if (err) { console.log("File err: " + file + err); return; }
if (stats.isFile()) {
fs.readFile(file, 'utf-8', function(err, data){
if (err) { console.log("Read err: " + file + err); return; }
console.log(data);
});
}
});
});
});
});
import os
import sys
dirname = sys.argv[1]
if not os.path.exists(dirname):
raise("Does not exist: " + dirname)
for f in os.listdir(dirname):
filename = os.path.join(dirname, f)
if not os.path.isfile(filename):
print "file err: " + filename
continue
with open(filename) as thefile:
print thefile.read()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment