Babashka is a fast-starting scripting environment for Clojure
medium.com
medium.com
It starts just as fast as Python too, if not faster, at least on my machine:
time python3 -c 'import os.path; print(os.path.exists("README.md"))'
time bb -e '(.exists (new java.io.File "README.md"))'
Python averages around 40-50ms, and bb averages 30-40ms.Sounds like you have a slow harddrive here, rather than measuring the startup of the interpreters.
With hyperfine:
$ hyperfine --warmup=100 --runs=1000 'python3 -c "import os.path; print(os.path.exists('"'README.md'"'))"' 'bb -e '"'(.exists (new java.io.File "'"README.md"'"))'"''
Benchmark 1: python3 -c "import os.path; print(os.path.exists('README.md'))"
Time (mean ± σ): 5.3 ms ± 0.7 ms [User: 4.9 ms, System: 1.2 ms]
Range (min … max): 4.5 ms … 9.8 ms 1000 runs
Benchmark 2: bb -e '(.exists (new java.io.File "README.md"))'
Time (mean ± σ): 6.0 ms ± 2.5 ms [User: 2.5 ms, System: 4.3 ms]
Range (min … max): 0.4 ms … 10.6 ms 1000 runs
Summary
'python3 -c "import os.path; print(os.path.exists('README.md'))"' ran
1.12 ± 0.49 times faster than 'bb -e '(.exists (new java.io.File "README.md"))''
Running on the following "not absolutely shabby" specs:> Intel i7-1185G7, 6.0.11-arch, Toshiba NVMe SSD (KBG40ZNS256G)
Seems Python has more consistent startup performance (`4.5 ms … 9.8 ms`) while Babashka can startup faster (`0.4 ms … 10.6 ms`) but on average, Python startups faster.
Main drawback of using a lisp for professional development is that it's really hard to go back to anything else afterwards. "Why use Assembly if you have C?" (unless you have a really good use case for it, of course), that's a bit the feeling you get.
But the pleasure of iterating towards the solution and building and quickly testing each of the constituents is joy-inducing.
For example, I often start with something like `(slurp "inputs/day-2")` and keep wrapping that until I get a structure I'm happy with. Then I split it into a few fns so I can keep testing with the smaller input
My solution times so far have scaled pretty heavily with "how long did I futz around with parsing the input?" I did well on days 3, 4, and 6, because the parsing was so trivial and it was just a quick function composition. Day 5 I spend entirely too much time parsing the input (In retrospect, I probably should have just edited it into an initial data structure in emacs.)
I still use bash for short <5 line scripts but everything else is bb (though I’ve started looking into nbb because you can use node libs like ink which seems pretty cool)
And repl integration with neovim and conjure is great!
The server runs on a Raspberry Pi with a 1-2TB USB disk attached.
super-easy shell interop + instant nREPL = replaces any complex bash script, driven from emacs!
what's more, you can namespace your scripts and import them. functionalizing code makes scripts easy to refactor, or even trivially move into a full Clojure backend or ClojureScript frontend. With squint-cljs you can even generate self-contained JavaScript directly from babashka code.
The documentation is a little lacking though, I had to look up other examples on GitHub to figure out how to use all the features.
https://github.com/babashka/pod-registry
Pods can be written in any language and they can expose functions to babashka by implementing a protocol.
One pod exposing HTML parsing is:
https://github.com/retrogradeorbit/bootleg
Here is an example of how to use that:
https://github.com/babashka/pod-registry/blob/master/example...
It includes the Hickory library: https://github.com/clj-commons/hickory
I'm a previous BeautifulSoup user and have found the combination of (1) having the scraped data presented in plain Clojure data structures, and (2) Hickory's built in selectors, to be a very nice experience.
Happy scraping!
And bb supports Honey SQL and SQL pods (https://github.com/babashka/babashka-sql-pods) - so you might be already compatible!
Here is an, admitedly not very clean, example that grabs stream urls from hltv.org:
https://github.com/TimDeve/.dotfiles/blob/master/scripts/gen...
Also a basic RSS reader using the clojure XML lib:
https://github.com/TimDeve/.dotfiles/blob/master/scripts/gen...
For personal stuff I use it in a lot of scripts used by Alfred.app including quick-fill for Things with date parsing, emoji completion, etc
None the less, a lovely tool and the couple of scripts I wrote are mostly still in use and well maintained for a reason ;) Clojure is just fantastic and so is the speed of the GraalVM.
I began to put together a "distribution" of useful CL libraries for everyday tasks: https://github.com/ciel-lang/CIEL/ It comes as:
- a lisp core, which you can use in your editor setup instead of sbcl or ccl, the advantage is that it loads instantly with all these libraries built-in (instead of quickloading all of them when needed)
- a readline REPL, with completion, syntax highlighting and some goodies (a shell passthrough, quick doc lookup…), albeit it needs more love
- a lisp library which you can quickload like the rest, it just comes with a bunch of dependencies.
- I want to add scripting capacity too.
It ships libraries for: HTTP requests, file formats handling (JSON, XML, CSV, TOML…), shell utils, file utils, threads, a nice hash-table notation, DB access, plotting, strings, other language extensions etc.
It is not finished but I am doog-fooding it for clients' projects.
So the scope of it is like Janet-lang, right?
$ ciel myscript.lisp
where we can use all the available libraries, it works instantly.It's brand new, not many options right now ;)
> like janet-lang
I don't think so, since Janet advertises itself as an embedable Lisp like Lua or Guile (and ECL). But yes, in the sense it comes with batteries included. Like Babashka, I guess.
Thanks for your initial question!
---
So, in CIEL scripts right now, we can make HTTP requests (dex:get or http:get), parse JSON, CSV etc, run shell commands (cmd:cmd, the "!" shortcut in the CIEL shell), or even
(defalias ! #'cmd:cmd)
(! "pwd")
and more. $ ./myscript.lispIt is also a tool to install various CL implementations, and to install software.
It doesn't come with a choice of built-in libraries.