Clojure

Clojure is a dialect of Lisp that runs in the JVM. It shares with Lisp the code-as-data philosophy and a powerful macro system. Clojure is predominantly a functional programming language, and features a rich set of immutable, persistent data structures. It has strong support for reliable multithreading and concurrency.

In [ ]:
; lazy infinite sequence with recursive definition
(def fib-seq-lazy 
  ((fn rfib [a b] 
     (lazy-seq (cons a (rfib b (+ a b)))))
   0 1))
(take 20 fib-seq-lazy)
In [ ]:
; 'unless' cannot be defined with a function because
; it does not always evaluate both its arguments.
(defmacro unless [pred a b]
  `(if (not ~pred) ~a ~b))
(unless false (println "Will print") (println "Will not print"))
In [ ]:
(defn run [nvecs nitems nthreads niters]
  (let [vec-refs (vec (map (comp ref vec)
                           (partition nitems (range (* nvecs nitems)))))
        swap #(let [v1 (rand-int nvecs)
                    v2 (rand-int nvecs)
                    i1 (rand-int nitems)
                    i2 (rand-int nitems)]
                (dosync
                 (let [temp (nth @(vec-refs v1) i1)]
                   (alter (vec-refs v1) assoc i1 (nth @(vec-refs v2) i2))
                   (alter (vec-refs v2) assoc i2 temp))))
        report #(do
                 (prn (map deref vec-refs))
                 (println "Distinct:"
                          (count (distinct (apply concat (map deref vec-refs))))))]
    (report)
    (dorun (apply pcalls (repeat nthreads #(dotimes [_ niters] (swap)))))
    (report)))
; When run, we see no values get lost or duplicated in the shuffle.
; There are 36 distinct numbers before and after. 
(run 6 6 6 100000)

Using the classpath to load a jar

This first cell shows that you get an error if you try to import a class not built-in to BeakerX:

In [ ]:
(import com.beaker.BeakerXClasspathTest)
(def classpathTest (new BeakerXClasspathTest))

The magic %classpath allows you to add jars to your kernel.

In [ ]:
%classpath add jar ../resources/jar/BeakerXClasspathTest.jar
In [ ]:
(import com.beaker.BeakerXClasspathTest)
(def classpathTest (new BeakerXClasspathTest))
In [ ]:
(BeakerXClasspathTest/staticTest)
In [ ]:
(. classpathTest getObjectTest)

Array of Maps with Properties

In [ ]:
[{:foo 1}{:foo 2}]

Interactive Plot

In [ ]:
(import '[com.twosigma.beakerx.chart.xychart Plot]
        '[com.twosigma.beakerx.chart.xychart.plotitem Line])
(doto (Plot.)
            (.setTitle "We Will Control the Title")
            (.setXLabel "Horizontal")
            (.setYLabel "Vertical")
            (.add (doto (Line.)
                        (.setX [0, 1, 2, 3, 4, 5])
                        (.setY [0, 1, 6, 5, 2, 8]))))

EasyForm

In [ ]:
(def form (doto (com.twosigma.beakerx.easyform.EasyForm. "Test Form")
                (.addTextField "Name")
                (.addButton "Reverse" "reverse")))
form
In [ ]:
(reverse (get form "Name"))

Import/Unimport magic command

In [ ]:
%import com.twosigma.beakerx.widget.IntSlider
In [ ]:
(new IntSlider)
In [ ]:
%unimport com.twosigma.beakerx.widget.IntSlider
In [ ]:
(new IntSlider)

IPyVolume visualization widget

ipyvolume works with Clojure, and the other 3D widgets probably work too. Note, the widget JS needs to be installed in advance of starting the notebook:

conda install -c conda-forge ipyvolume

See the source of this example.

In [ ]:
%classpath add mvn com.github.twosigma ipyvolume master-SNAPSHOT
In [ ]:
(import ipyvolume.PyLab)

(defn ball 
    [size radius]
    (let [data           (make-array Float/TYPE size size size)
          square         #(* % %)
          center         #(- % (/ size 2))
          sum            (partial reduce +)
          sum-of-squares #(sum (map square %))]
        (doseq [i (range size)
                j (range size)
                k (range size)
                :let [[x y z] (map center [i j k])] 
                :when (> (square radius) 
                         (sum-of-squares [x y z]))]
             (aset data i j k (float 1)))
        data))
(PyLab/volShow (ball 32 12))