4 ms·
For JS: straight-forward batch processing. Open this CSV, iterate over the data, munge it in some way, spit it out again as a new CSV. This kind of thing is lik
by apendleton 8y ago
For JS: straight-forward batch processing. Open this CSV, iterate over the data, munge it in some way, spit it out again as a new CSV. This kind of thing is like a 4-line Python script but in JS/Node requires readline or some other kind of standard library thing, nest-y callbacks and/or promises, or maybe async and understanding how that works (which, for a brand new dev... have fun with that), etc. If you need to do IO but don't have a task that benefits from async, things in JS tend to feel unnecessarily torturous.
- jdlshore 8y agoIt's not so bad. const fs = require("fs"); const filename = process.argv[2]; const fileContents = fs.readFileSync(filename, "utf8"); const output = munge(fileContents); process.stdout.write(output); It's worse if you want to use async IO, mostly because the ecosystem is still catching up to async/await. But with a bit of boilerplate or a willingness to use experimental APIs, it's also not bad: // This API is still experimental const fs = require("fs").promises; // This will become unnecessary when top-level await is supported run().catch((err) => console.error(err)); async function run() { const filename = process.argv[2]; const fileContents = await fs.readFile(filename, "utf8"); const output = munge(fileContents); process.stdout.write(output); } My Node.js projects' tooling is all written in Node.js and I enjoy it.
- apendleton 8y agoThe specific situation I've encountered is that it's a file that's bigger than I want to hold in memory and I want to read it and process it a line at a time, but I don't want to do anything fancy or threaded or concurrent. Read a line, do something to it, write a line. Bog-standard ETL stuff. And yeah, async/await helps, but is unambiguously ergonomically worse than: import csv incsv = csv.reader(open('file1.csv')) outcsv = csv.writer(open('file2.csv', 'w')) for row in incsv: outcsv.writerow([row[0], row[1] + ' blah']) and also just requires understanding a lot more stuff before you can be productive if you're new to the language. I'm not saying it's not possible to do it in JS, just that it's not a task that plays to JS's ergonomic strengths, just like it's possible to write a linked list in Rust but kind of sucks.
- jdlshore 8y agoI would call it a weakness of JS's ecosystem, not an ergonomic problem. I believe JS could allow nearly the same code. Haven't tried it, though: const fs = require("fs"); const csv = require("some-csv-package"); const incsv = csv.reader(fs.createReadStream("file1.csv")); const outcsv = csv.writer(fs.createWriteStream("file2.csv")); for await (row of incsv) { await outcsv.writeRow([ row[0], `${row[1]} blah` ]); } Granted, that package doesn't exist, and the popular CSV package for Node [1] makes my eyes cross. As for me, none of the scripting I do with Node involves files that exceed Node's 1GB memory limit, so I take the cheap and easy way out and just readFile(). Which I suppose proves your point, although, again, I would argue it's an ecosystem problem, not a ergonomic problem. [1] https://csv.js.org/project/examples/ https://csv.js.org/project/examples/