Babashka pods for beginners


Babashka pods: Wrap any library, use it from Clojure

Motivation: Babashka pods are a mechanism to build functionality in any language, and expose those features in Clojure. You can build a high performance numerics library in Rust, and use it from Clojure. Or wrap around some nice existing library.

I read the section on pods in the babashka book and the babashka pods README, and still didn’t feel like everything made sense. So, why not write the introduction that I would have wanted.

Q: give me a minimal example of pods

Sure. Here are the moving pieces:

  1. Your program
  2. The babashka/babashka.pods library
  3. A pod

Q: what is a pod?

An executable program that takes commands on stdin, and prints results to stdout.

Q: what kind of commands on stdin?

There are three commands: describe, invoke and shutdown.

Q: what do they do?

list of provided namespaces, and provided vars for each namespace.
invoke a function
stop any processes the pod is running

Q: that doesn’t sound too complicated!

I thought it was way more complicated too! But that’s it, really. You write an application in some language, and follow a convention for stdin and stdout.

Q: But … I might want to use stdin and stdout for other things.

Yup! When the babashka pods library starts your executable, it sets the environment variable BABASHKA_POD to true. So you can default to your normal behavior otherwise. For a practical example, see rorokimdim’s stash or justone’s tabl.

What’s bencode?

Here are some examples:

(ns explore.bencode-examples
  (:require [explore.bencode :as bencode]))

(bencode/encode {:foo "bar"})
;; => "d3:foo3:bare"

(= (bencode/encode {:foo "bar"})
   (bencode/encode {"foo" "bar"}))
;; => true

(-> {:foo "bar"}
;; => {"foo" "bar"}

(bencode/encode "teodor")
;; => "6:teodor"

(bencode/encode 99)
;; => "i99e"

(bencode/encode 1.2)
;; => error - integers only!

(bencode/decode "i99e")
;; => 99

(defn examples [f & exs]
  (for [e exs]
    [e (f e)]))

(examples bencode/encode
          {"x" 1}
          {"name" "tom"}
          ["n" "tom"]
          [1 2 3]
          [1 2]
;; => ([{"x" 1} "d1:xi1ee"]
;;     [{"name" "tom"} "d4:name3:tome"]
;;     [["n" "tom"] "l1:n3:tome"]
;;     [[1 2 3] "li1ei2ei3ee"]
;;     [[1 2] "li1ei2ee"])

But there’s a caveat. I’m cheating! I’m pretending that all binary data is UTF-8 serialized text.

But that’s enough for us now. If you want do dig further into bencode, please read the Bencode Wikipedia page and the nrepl/bencode tests.

Why do we need bencode?


local preview | view on the web