Quick notes on using CEPL on macOS

16 Aug 2016

Just jotting down some notes while trying to get CEPL working on my oldish MacBook Pro running El Capitan.

CEPL running on El Capitan

Repositories you’ll need to clone locally:

Actually running it in SLIME:

Again, I can’t get the examples to run directly, but you can run the triangle example below by:

(in-package :cl-user)
(defpackage :triangle
  (:use #:cl #:cepl #:livesupport))

(in-package :triangle)

(defparameter *array* nil)
(defparameter *stream* nil)
(defparameter *running* nil)

(defstruct-g pos-col
  (position :vec3 :accessor pos)
  (color :vec4 :accessor col))

(defun-g tri-vert ((vert pos-col))
  (values (v! (pos vert) 1.0)
          (col vert)))

(defun-g tri-frag ((color :vec4))

(def-g-> prog-1 ()
  tri-vert tri-frag)

(defun step-demo ()
  (map-g #'prog-1 *stream*)

(defun run-loop ()
  (setf *running* t
        *array* (make-gpu-array (list (list (v!  0.5 -0.36 0) (v! 0 1 0 1))
                                      (list (v!    0   0.5 0) (v! 1 0 0 1))
                                      (list (v! -0.5 -0.36 0) (v! 0 0 1 1)))
                                :element-type 'pos-col)
        *stream* (make-buffer-stream *array*))
  (loop :while (and *running* (not (shutting-down-p))) :do
     (continuable (step-demo))))

(defun stop-loop ()
  (setf *running* nil))

Quickie - Using SQLite4Java from Clojure

01 Aug 2016

We use SQLite4Java at work, and I’m playing around with our databases from Clojure at the moment and just wanted to quickly jot down how to do it.

First, native library management in SQLite4Java is a little hairy: it’s going to look for the libraries either in java.library.path, sqlite4java.library.path, alongside the SQLite4Java jar file, or you can explicitly tell it where to find things. The Maven config to do this automatically is suitably ugly, and as far as I know, there’s not a good way to do the same thing with Leiningen.

I opted to just explicitly tell it for now. I list the SQLite4Java dependency in my project.clj, copied the native libraries I’m interested in into ${project.dir}/natives, and then just added this at startup time:

(let [native-dir (clojure.java.io/file (System/getProperty "user.dir") "natives")]
  (com.almworks.sqlite4java.SQLite/setLibraryPath (str native-dir)))

(I’m leaving all of the namespace components in there to be explicit: I require/import them as normal in my code.)

Next issue: actually running queries against a database has to be done using a SQLiteConnection instance, and those instances are limited to being used from the thread that created them. That precludes using them from the REPL: you don’t have any control over what thread your expressions are going to be executed from. So, you need to use SQLiteQueue, which wraps a SQLiteConnection and ensures all calls come from a single thread.

SQLiteQueue works by taking SQLiteJob instances (basically just a function) and running them in first-in-first-out order. Unfortunately, SQLiteQueue can’t just take a Callable, so you can’t use Clojure functions directly. Wrapping a function up in a job is pretty easy though, and is the first time I’ve needed to use clojure.core/proxy:

(defn job
  "Returns a SQLiteJob proxy that calls the given function."
  (proxy [com.almworks.sqlite4java.SQLiteJob]
    (job [^SQLiteConnection conn]
      (job-fn conn))))

Then using those jobs is done by calling SQLiteQueue::execute, which returns the job again. Those jobs implement Future, so you can use them as normal, or they have a convenience method SQLiteJob::complete that deals with exceptions for you.

(def get-all-user-ids
    (fn [^SQLiteConnection conn]
      (let [query (.prepare conn "SELECT id FROM users")]
        (try (loop [ids []
                    continue (.step query)]
               (if-not continue
                 (recur (conj ids (.columnLong query 0)) (.step query))))
        (finally (.dipose query)))))))

(.complete (.execute queue get-all-user-ids))

So all bundled together, my little library for working with SQLite4Java looks like this right now:

(ns jfischer.db
  (:require [clojure.java.io :as io])
  (:import [com.almworks.sqlite4java SQLiteQueue

(defn open-db
  "Creates (and starts, because I'm forever forgetting to .start it at
  the REPL) a SQLiteQueue instance. The zero-argument version opens an
  in-memory database, otherwise give it a filename."
 ([] (open-db nil))
  (.start (SQLiteQueue. (io/file filename)))))

(defn job
  "Returns a SQLiteJob proxy that calls the given function."
  (proxy [SQLiteJob]
    (job [^SQLiteConnection conn]
      (job-fn conn))))

(defn exec-job
  "Runs the given job on the database queue and returns its result."
  [^SQLiteQueue db
   ^SQLiteJob job]
  (.complete (.execute db job)))

Boot as a sort-of Quicklisp

01 Feb 2016

Really quick: after dismissing Clojure for years (I have Common Lisp, I don’t care about the JVM, why do I need it?) I finally took the time to learn it about a year ago and OMG I love it and I want to use it for everything (much to the dismay of my team at work).

One of the pain points though is how project-based everything seems to be: if you want to pull in any sort of third party library, you have to build some sort of project, be it Maven, Leiningen, or something similar. List the libraries you want to pull in there and start (or restart) your REPL before you can use them.

Coming from Quicklisp, it’s super annoying, especially if you just want to give something a quick spin.

Enter Boot! It’s a relatively new way to handle building Clojure projects, but it allows you to easily name dependencies when you run it, like so:

$ boot -d com.google.code.gson/gson:2.5 repl

That gives me a REPL with Gson loaded and ready to use.

boot.user=> (import [com.google.gson Gson JsonObject])
boot.user=> (def o (JsonObject.))
boot.user=> (.addProperty o "hello" "world")
boot.user=> (.toJson (Gson.) o)

To make life a little easier, I have a task in my ~/.boot/profile.boot that pulls in the dependencies Cider needs:

(deftask cider
  "Switch up the default dependencies and middleware to support cider-nrepl."
  (require 'boot.repl)
  (swap! @(resolve 'boot.repl/*default-dependencies*)
         concat '[[org.clojure/tools.nrepl "0.2.12"]
                  [cider/cider-nrepl "0.10.1"]])
  (swap! @(resolve 'boot.repl/*default-middleware*)
         concat '[cider.nrepl/cider-middleware])

So when I want to tool around with something, I just run boot -d whatever:version cider repl, fire up Emacs, connect and go to work.

I haven’t take the time to get comfortable with Boot for full projects yet, so I’m still using Leiningen for most things, but I love it for quick one-off experiments. It’s not as good as being able to load whatever I want from the comfort of the REPL, but it makes things a lot less painful.

Do I really need that database?

23 Nov 2015

I’m pretty sure that every time I’ve built a web application of any sort in the last decade, I’ve reached for a database. Usually SQLite, at least to start, because it lets me get going fast without any infrastructure in place. It’s not even a question, really: if I’m building a web app, it needs a database of some kind behind it.

Actually, let me rewind just a smidge. I really dig Clojure lately, and my favorite thing about it are the immutable data structures: once you’ve created your map, or vector, or whatever, you can’t change it. Instead, you can derive new things from it. Now that I’m comfortable working with immutable by default things, working without them feels almost like I’m building on shaky foundations.


9 years and counting

14 Oct 2015

Today is my and Jackie’s 9 year anniversary.

It’s funny how things work out. Around when we got married, we had this vague plan to move away from Southern California, to try living other places, to travel a bit and see the world before we really settled down to have kids.

After a year or so it was pretty obvious we weren’t going to do it anytime soon, and we didn’t want to wait forever to have kids, so we had Kayla. Talk about turning our world upside down. Suddenly owning a house became critically important, even if it meant moving well away from work. Suddenly, even though we planned for Jackie to go back to work, we were going to have to get by on just my salary.

Suddenly we were responsible for a child. For a human being. The day Kayla was born, when I went down to the cafeteria alone to get a bite to eat, I cried at how overwhelming it all was.

Somehow, we’ve pulled it off so far. Bought a house 6 months after Kayla was born. 9 months after that we decided she shouldn’t grow up alone, and 9 months after that Colin showed up. The kids are 7 and 5 now, Jackie hasn’t had to go back to work, and we’re still making it. It’s been hard, and continues to be hard, but we’re making it.

Most important: we’re happy.

9 years and counting. We make a pretty good team, Jackie. I love you.

Here’s to many, many more.

Us at the Monterey Bay Aquarium

Kayla and Colin