'Shake: Every Program Can Be a Clojure Function'

Fri 21 September 2012
  • ANN tags:
  • clojure
  • github
  • linux published: true comments: true

You might have heard of sh, which brings python an interface to call subprocesses. The API of sh is pretty cool: Every command can be treated as a python function, and imported from a namespace. Options and arguments are passed in as python string.

But I think in Clojure, things can be even cooler. We dynamically create symbols for every program. We will have a beautiful DSL so you don't have to quote arguments as string. So when you are using this library, it may look like:

[cc lang="clojure"]
(ls)
(uname -a)
(ip -4 addr)
[/cc]

And actually it's just like that! I create this library called shake. When you load `shake.core`, it indexes all the executables in your path. Then all programs are available to you in a clojure native way.

[cc lang="clojure"]

(use 'shake.core)
(uname -a) ;; returns a java.lang.Process, that you can send data, read data and wait for termination.

;; for those just need output
(alter-var-root *print-outpt* (fn [_] true))
(uname -a)
;; it prints ...
[/cc]

There's a lot of fun in implementing this library. First, to be able to use custom symbol in the DSL, you have to make these executables as macros. Second, find a way to programmably create vars which are named by string. The power of Clojure enables all the ideas and makes it possible. Check out the source code if you are interested in: https://github.com/sunng87/shake/.