Native, fast starting Clojure interpreter for scripting
EPL-1.0 License
Bot releases are hidden (Show)
New in babashka v0.0.67:
Add clojure.test
:
$ bb "(require '[clojure.test :as t]) (t/is (= 4 5))"
FAIL in () (test.clj:370)
expected: (= 4 5)
actual: (not (= 4 5))
false
This makes the spartan.test library deprecated. The missing.test.assertions library now also works with babashka.
Add hierarchies (derive
, isa?
, etc.)
Add multimethods
Although babashka comes with clojure.data.csv built in, the newest version can now also run the clojure-csv
library.
Add StringBuilder
:
$ bb '(time (loop [s "" i 0] (if (< i 100000) (recur (str s (char 67)) (inc i)) (count s))))'
"Elapsed time: 10446.353326 msecs"
100000
$ bb '(time (let [sb (StringBuilder. "")] (dotimes [i 100000] (.appendCodePoint sb 67)) (count (str sb))))'
"Elapsed time: 840.823386 msecs"
100000
-i -O
and -I -o
alter-meta!
and reset-meta!
:reload
in requireclojure.core/time
macro:row
and :col
metadata were renamed to :line
and :column
which is what Clojure tooling like Chlorine expects.Throwable
to default imports*ns*
should be controllable per socket REPL connection-e
argument to be repeatedPerformance enhancements. Compare these two runs between bb 0.0.64 and 0.0.61. With 0.0.64 it runs about 8x faster.
$ time ./bb-0.0.64 "(loop [val 0 cnt 1000000] (if (pos? cnt) (recur (inc val) (dec cnt)) val))"
1000000
./bb-0.0.64 1.32s user 0.07s system 99% cpu 1.400 total
$ time ./bb-0.0.61 "(loop [val 0 cnt 1000000] (if (pos? cnt) (recur (inc val) (dec cnt)) val))"
1000000
./bb-0.0.61 11.42s user 0.08s system 99% cpu 11.507 total
Special thanks to clj-async-profiler.
babashka.classpath/add-classpath
. This function allows to add to the classpath dynamically:(require '[babashka.classpath :refer [add-classpath]]
'[clojure.java.shell :refer [sh]])
(def medley-dep '{:deps {medley {:git/url "https://github.com/borkdude/medley"
:sha "91adfb5da33f8d23f75f0894da1defe567a625c0"}}})
(def cp (:out (sh "clojure" "-Spath" "-Sdeps" (str medley-dep))))
(add-classpath cp)
(require '[medley.core :as m])
(m/index-by :id [{:id 1} {:id 2}]) ;;=> {1 {:id 1}, 2 {:id 2}}
alias
, find-ns
, the-ns
, ns-aliases
, ns-publics
, clojure.repl/dir
fn
--verbose
..
, any?
, inst?
, macroexpand
, macroexpand-1
, clojure.repl/demunge
/ clojure.main/demunge
Most of this was added to support an interpreted version of clojure.spec:
$ bb "(type (. System (getProperties)))"
java.util.Properties
now works, whereas before it didn't.
case
now supports a list, as it should:$ bb '(case 1 (1 2 3) :match)'
:match
alter-var-root
.locking
:$ bb '
(def x (volatile! 0)) (defn inc! [] (vswap! x inc)) (doseq [f (map (fn [_] (future (inc!))) (range 1000))] @f) @x'
994
$ bb '
(def o (Object.)) (def x (volatile! 0)) (defn inc! [] (locking o (vswap! x inc))) (doseq [f (map (fn [_] (future (inc!))) (range 1000))] @f) @x'
1000
See the difference?
$ bb "\`~'#(inc %)"
(fn [%1] (inc %1))
In previous versions the above example would return a map with implementation details that weren't so pretty to look at.
clojure.stacktrace
defn
Example:
$ bb '(clojure.main/repl :init #(println "Welcome to lambda REPL!") :prompt #(print "λ> "))'
Welcome to lambda REPL!
λ>
With this addition, babashka is now able to run the limit-break
library, a debug REPL:
$ export BABASHKA_CLASSPATH="$(clojure -Sdeps '{:deps {limit-break {:git/url "https://github.com/technomancy/limit-break" :sha "050fcfa0ea29fe3340927533a6fa6fffe23bfc2f" :deps/manifest :deps}}}' -Spath)"
$ bb "(require '[limit.break :as lb]) (let [x 1] (lb/break))"
Babashka v0.0.49 REPL.
Use :repl/quit or :repl/exit to quit the REPL.
Clojure rocks, Bash reaches.
break> x
1