A Shell Language in Lisp
github.com
github.com
What modern alternatives to `.sh` scripting exist? Tcl? Is Fish objectively better than Bash and ZSH? Are there any thin wrappers and transpilers on top of sh? Or maybe just good old Perl?
And how does this project address normal pain points of shell scripting, like using arrays and iterating on them for example?
I was thinking a lot on the topic lately and currently have no good answers (never studied the topic in detail). I suppose just replacing `sh` scripting with Golang is also an option. Not the strongest typed or least verbosive language out there but it has a very good cross-compilation story, compiles really fast and produces single binaries that are easy to distribute. So might go with that.
Python is out because startup time wasn't great last I used it for CLI tools (might be an outdated info however, any metrics)? Ruby is also a pretty solid candidate; the lack of static typing is, eh, 50/50 -- might not be important after all.
I also know a guy who replaced Python with OCaml for quick scripting which is rather bizarre to me but knowing a bit more about OCaml nowadays, that actually can work just fine -- and OCaml is very terse.
I would prioritize speed of startup and terse code over everything else. Static typing I want but can very likely do without. I don't care much how portable the program/runtime is; I can distribute it to my machines and I have some influence in my work about what tooling to use.
Any practical recommendations?
> I would prioritize speed of startup and terse code over everything else.
If speed of startup and terse code are all you want... what's the problem with OCaml? It's got static typing too.
Was just wondering if there are replacements for shell scripting that are quicker to learn.
for i in {1..10}; do echo $i; done
worked and was equivalent to: for((i=1;i<=10;i++)); do echo $i; done
for i in 1 2 3 4 5 6 7 8 9 10; do echo $i; donefor x in `seq 5 10`; do ...
for ((i = 0; i < 10; i++)); do
echo $i
doneI quickly realized nearly everything I didn't like about "ruby" was actually rails. After a couple of years I moved on and don't do rails anymore, but I ruby is still my go to for any script that requires arrays or maps (the point where bash begins to be really painful).
Ruby is the best scripting language ever IMHO*. Ruby one-liners (inherited from Perl tradition) make it plug nicely into a bash script also.
* I haven't tried Julia yet but plan to.
How is the startup time though? That's important.
> time ruby hello.rb
Hello, world!
ruby hello.rb 0.11s user 0.13s system 81% cpu 0.297 total
> time node hello.js
Hello, world!
node hello.js 0.10s user 0.16s system 84% cpu 0.307 totalMaybe I got spoiled by Rust and OCaml that start in the matter of 3-8ms. :D But these Ruby and Node startup times are good.
Sane quoting eliminates and a lack of recursive expansion make ssh a breeze.
Pattern matching, backquote status, and pipe status simplification are all incredibly easy to get right.
C-like syntax for blocks means nested hierarchies are easy to understand and to write correctly.
Simple small binary, doesn't require readline and can be built for almost every architecture and OS.
Yes GNU Parallel (that's what you're referring to I assume) can still run under rc, though I'm not sure exactly what makes you think it couldn't!
Thank you! Looks lightweight and less confusing. I'll give it a go.
It works just like any script (.fsx files) and you can also compile it ahead of time.
There is a REPL for experimenting and the type system provides for a superior IDE experience.
It has the full .NET ecosystem at its disposal. And algebraic data types to ensure you cover all edge cases.
And last but not least - if you are scripting any kind of data wrangling, the Type Providers feature of F# offers a very powerful way to build those ETL jobs with type safety with just a few lines of code.
Most steps are short scripts of a few hundred lines and compile quickly.
Downloading dependencies (libraries) may take a while depending on how much you pull in from e.g. NuGet (seconds not minutes) but you can keep these between runs.
For historical context, around 1994, I ditched shell with heavy awk and add use in favour of Perl to avoid the heavy overhead of multiple processes being spawned by the shell scripts.
So you have to know both what you need but also which alternatives you are benchmarking it against.
But I can still agree with you!
> For historical context, around 1994, I ditched shell with heavy awk and add use in favour of Perl to avoid the heavy overhead of multiple processes being spawned by the shell scripts.
I feel a novice now. :D
To be fair, there weren't things I wasn't able to achieve with zsh scripts and `parallel` and the usual suspects (sed, awk et. al.) but when I measure how much time -- and sometimes sanity -- I lose until I make something rather trivial work, the analysis isn't in favour of my current workflow. 500 "quick and dirty" scripts each wasting you 3h as opposed to 5-10 minutes amounts to a LOT of wasted work time.
To be fair, I was not inclined to use F#. OCaml always impressed me with its amazingly fast compiler. But you have a very solid point that with F# you can use the entire .NET ecosystem...
> So you have to know both what you need but also which alternatives you are benchmarking it against.
I don't know exactly what I need, for the better or the worse. I just want to do one big switch (away from sh/bash/zsh scripting) and not have to redo it anytime soon, is all.
Most tasks are I/O bound anyway so normal shell scripting and `parallel` can take you VERY far. But I've been bitten by weak typing and surprisingly parsed values so I am looking for something stricter. Runtime speed is hardly relevant to anything because again, I/O bound is the norm (_especially_ when you work with the network; most network-bound tasks that people put in their scripts nowadays could easily be handled by a Pentium III from back in the day, I feel).
The art is to select trade-offs that benefit the main line of work you want to do without causing too much trouble.
Personally my scripting preferences have changed over time depending on the types of problems I had to solve and what else I were doing at the same time. I have never found The One Solution but seen things slowly change back and forth over the years.
Sadly that's quite true.
So let me correct my statement: I am looking for "shell scripting on steroids" for when I intuit (or discover after 10 minutes of trying) that normal shell scripting won't cut it. I'll still use it but I want to have an extra tool in my belt for those cases when I need something a bit feature-rich but still quick to iterate on.
For now, looking through the sub-thread and brushing off on old knowledge and searching the net for an hour or so, my 3 top contestants are (in that priority order) -- OCaml, Ruby, the RC shell.
The API seems to have changed a bit since I last used it, so not sure how nice the current version is. It's also apparently used by a shell-like language called Rash, but I've not used that either https://docs.racket-lang.org/rash
For those who aren't aware, Naver is the Google/Yahoo equivalent in South Korea. Their main product is a search engine and web portal, but they also have community pages (Naver Cafe), Music, Translation, Webtoons (webcomics) and so on. They have a subsidiary company that's created the LINE messenger app.
As a newcomer to clojure my question is: what would be the practical differences and deciding factors for doing what would be a ".sh" in babashka vs closh?
But the readme doesn't say if the record and field separators can be changed. Space delimited fields are not always useful.