4 ms·
Talk about sledgehammer to crack a nut - honestly, why does anyone need type safety in a simple templating operation? Dynamic languages have their uses, you kno
by cutler 4y ago
Talk about sledgehammer to crack a nut - honestly, why does anyone need type safety in a simple templating operation? Dynamic languages have their uses, you know. Type safety is a tool, not an ideology.
- cercatrova 4y agoI basically never use dynamic languages anymore. If there aren't algebraic data types in a language I simply don't use it. Sometimes people think I'm exaggerating but it's truly great to use a language with ADTs that you get spoiled.
- cutler 4y agoSo what do you use for shell scripting?
- cercatrova 4y agoI like using Nim or Rust, or TypeScript, depends on the script. If it's just a few lines, sure I'll write it in bash, but if it gets a little larger, I convert it into a real programming language.
- dotancohen 4y agoRust as a replacement for a bash script? My bash scripts are often edited, I could not imagine using a compiled language where I would have to store the source as a separate file from the executable, then compile it each time. I'd love to know your more specific use cases, if you don't mind. I'm always happy to learn something new. Could you share some Rust that most people would script in Bash as an example? What's your build and deploy (to ~/.local/bin I presume) strategy?
- cercatrova 4y ago> where I would have to store the source as a separate file from the executable, then compile it each time > What's your build and deploy (to ~/.local/bin I presume) strategy? You can run scripts as you would with bash, you don't have to manually build and run the executable. For example, `cargo run (inside the script source folder)` and `sh script.sh` do basically the same thing, end user wise. `nim compile --run script.nim` is similar in that the language compiler will automatically compile and run it together. > Could you share some Rust that most people would script in Bash as an example? I was creating dotfiles the other day and I didn't want to use some dotfile manager program as I had some specific steps I wanted to follow, so I started it as a bash script. Well, it got kind of annoying so I made it into a Rust script with some nice features like interactive prompts, text coloring, etc with libraries like `clap`. You can do this in bash of course, but the Rust version was more ergonomic. When I need to run the script, I just did `cargo run` and it worked great.
- dotancohen 4y agoI see, but then your scripts are not nice compact commands. For instance, my most-used bash script takes a file as input and opens either VIM or Emacs depending on whether the file is a .md or .org (simplified example). I run it like so: $ n foo.org I can edit ~/.local/bin/n and update the file, and use it immediately. I actually have my whole ~/.local/bin in version control. Having to type out e.g. $ nim compile --run n foo.org ...would make the whole experience far less fluent. I probably would never use it. I'm asking because I'd love to rewrite this script in e.g. Rust, but I don't see any good way to deploy it to ~/.local/bin/n.
- cercatrova 4y agoJust alias the command in your .bashrc? e.g. `alias n="nim compile --run n"`. I'm not sure what the issue is with longer commands because the benefits of writing in a strongly statically typed language definitely outweigh a few extra characters to type, which you don't even need to do with aliases.
- cb321 4y ago
- paldepind2 4y agoBut TypeScript doesn’t have ADTs which you stated was a hard requirement. It has some other features that can achieve similar things though, so maybe that’s good enough?
- mind-blight 4y agoDiscriminated unions aren't quite as nice, but they're pretty close.
- piaste 4y agoKinda nitpicky. Sure ADTs are a pattern in Typescript rather than a first-class entity, but they're an extremely well-supported pattern, exhaustiveness checking and all. type ADT = | { case : 'a', a : Number } | { case : 'b', b : string } function f (c : ADT) { switch(c.case) { case 'a' : return c.a case 'b' : return Number.parseInt(c.b) // case 'c' : return 0 // compile error // case 'b' : return c.a // also compile error } }
- wpietri 4y agoFor sure. I'm a big fan of type safety in larger codebases with reasonably stable domains. But when a project's small or new enough to be relatively volatile, the overhead just isn't worth it for me.
- Yiin 4y agobecause it's nice to know whether that `post` variable contains a property `createdAt` or `published` At without leaving the template. Arguing "I don't use it why should you" is unproductive.
- cercatrova 4y agoAgreed, you get all the benefits of type inference even in a template. It's a pain to debug template variables that don't exist, I've written enough Handlebars to know.