Live data from Hacker News

ZX – A tool for writing better scripts

github.com

131–140 of 143 posts

Re: ZX – A tool for writing better scripts

#131
post #18

This looks really cool, actually, and I'm surprised I haven't heard of this before. My incorrect gut intuition is that JavaScript devs usually don't do very much in depth terminal level command work, but that's of course false on a Bayesian level. There are far more JavaScript developers in the world than there are even Python developers, to say nothing of the long tail of even less popular languages. If 30% of JS de…

> There are far more JavaScript developers in the world than there are even Python developers I don’t think that’s true. Anecdotally when I was interviewing at a recruiting company (and we let candidates pick any language to be assessed in), Python was by far the most popular choice, chosen by about 60% of candidates or something like that. Java and JavaScript came after, followed by a long tail of languages like C#…

I could probably say "you're moving the goalposts here, I'm taking all developers not all working developers" or something, but I think these days you're basically correct. Python was relatively more niche when I picked it up in 2009 or so, but it's really become the lingua franca of our industry.

Re: ZX – A tool for writing better scripts

#132
post #96

Earlier quoted context omitted.

That allows other code to run while e.g. files are being moved. It indeed can be somewhat painful ([1] is the classic criticism) and in shell scripts is not as beneficial. I think there are even sync alternatives (i.e. equivalent functions that don't need `await`) for most of them, but again: these are the APIs I'm already familiar with, which is the entire point - and thus the await-stuff comes naturally for me, bec…

Yes and a shell script would do it with one &, while this goop is a mountain of async, nesting, futures management, and boilerplate. No thanks.

Sure, but again: I know and recognise this syntax and the APIs. What's boilerplate to me, I hardly see, whereas compact Bash operators are noise to my eyes.

Re: ZX – A tool for writing better scripts

#135
post #77

Earlier quoted context omitted.

Here's an example: https://gitlab.com/vincenttunru/penny/-/blob/main/scripts/bu... That used to be a shell script. But this I can way more easily read (even after not touching it for a long time), I get autocompletion, and I can use the APIs I'm already familiar with. It's a pretty neat QoL improvement for me specifically.

Wouldn't the `await fs.move` run sync? Why not just return the Promise from fs.move() so that Promise.all() can run the multiple moves async? await Promise.all( unneededPages.map(async (page) => { await fs.move(page, `scripts/.cache/${page}`, { overwrite: true }); }) ); Similar to what you do on line 26.

Do you mean the `await fs.move` on line 13? Because yes, I do need that to complete before I can run the next command, the build, on line 40.

I could have appended it to the Promises that I'm creating on line 9 to run it in parallel with those moves, but this is not performance-critical code, and moving the two conceptually-unrelated concepts into the same expression wouldn't aid legibility, in my opinion. And since I'm the only one who needs to read the code, that opinion wins by default :)

Re: ZX – A tool for writing better scripts

#136
post #135

Earlier quoted context omitted.

Wouldn't the `await fs.move` run sync? Why not just return the Promise from fs.move() so that Promise.all() can run the multiple moves async? await Promise.all( unneededPages.map(async (page) => { await fs.move(page, `scripts/.cache/${page}`, { overwrite: true }); }) ); Similar to what you do on line 26.

Do you mean the `await fs.move` on line 13? Because yes, I do need that to complete before I can run the next command, the build, on line 40. I could have appended it to the Promises that I'm creating on line 9 to run it in parallel with those moves, but this is not performance-critical code, and moving the two conceptually-unrelated concepts into the same expression wouldn't aid legibility, in my opinion. And since…

Above: You have `await Promise.all()`. Remove the `await` in front of `fs.move()`.

You don't need the second `await` for blocking purposes.

Sure, it is your code to do as you like, but if you're going to post it as an example, you might want to correct it first so that others don't make the same mistakes.

Re: ZX – A tool for writing better scripts

#137
post #132

Earlier quoted context omitted.

Yes and a shell script would do it with one &, while this goop is a mountain of async, nesting, futures management, and boilerplate. No thanks.

Sure, but again: I know and recognise this syntax and the APIs. What's boilerplate to me, I hardly see, whereas compact Bash operators are noise to my eyes.

(Though to be honest, I'm also somewhat sceptical that a single & in Bash would be sufficient to move a bunch of files in a particular order, and restore them properly if the process gets terminated somewhere halfway along the process. But what I'm sure about is that I wouldn't have been able to write that in a reasonable amount of time!)

Re: ZX – A tool for writing better scripts

#138
post #135

Earlier quoted context omitted.

Do you mean the `await fs.move` on line 13? Because yes, I do need that to complete before I can run the next command, the build, on line 40. I could have appended it to the Promises that I'm creating on line 9 to run it in parallel with those moves, but this is not performance-critical code, and moving the two conceptually-unrelated concepts into the same expression wouldn't aid legibility, in my opinion. And since…

Above: You have `await Promise.all()`. Remove the `await` in front of `fs.move()`. You don't need the second `await` for blocking purposes. Sure, it is your code to do as you like, but if you're going to post it as an example, you might want to correct it first so that others don't make the same mistakes.

Ah! You mean that

    await Promise.all(
      unneededPages.map(async (page) => {
        await fs.move(page, `scripts/.cache/${page}`, { overwrite: true });
      })
    );
could also have been written as

    await Promise.all(
      unneededPages.map((page) => {
        fs.move(page, `scripts/.cache/${page}`, { overwrite: true });
      })
    );
That is absolutely correct! I wasn't intending it as an example of how to write flawless JS code though, just as an example of the type of script that ZX is useful for - but if I remember next time I open my dev env, I'll update it :)

Edit: though maybe I'm misunderstanding given that you said it would make them run sync, because as far as I know, the functions would still run in parallel? Essentially, I believe it would roughly be the equivalent of this:

    await Promise.all(
      unneededPages.map((page) => {
        fs.move(page, `scripts/.cache/${page}`, { overwrite: true });
      }).then(result => result)
    );

Re: ZX – A tool for writing better scripts

#140
post #8

Please don’t make me install Node.js to run your shell script.

Yeah that wouldn't be great. But: This feels to me like it might be a really useful tool to do systems-integration work around an app that is built in Node.js. For example, to integrate with incrond or cron, or get a supervisor task into JS. The smallest sensible "shell-ish" wrapper that gets you access to your codebase in JS and stops the coding effort being divided so much between technologies.

Sure. But I can easily see this becoming the default way to write shell scripts in the near future in the same way Electron is becoming the default way to write desktop applications.
Post reply on HN