Portfolio


I write small libraries. If a project implements something that may potentially be useful somewhere else, I’ll factor it out.

My long term goal is to make Common Lisp a viable language for web development, and most of the code you’ll see here reflects this.

Thankfully, other people have done a lot of good work in this area: Eitaro Fukamachi, Nicolas Hafner, and Andrew Lyon. This portfolio wouldn’t be what it is without them.

Open Source Work

Crane

Crane is an ORM for Common Lisp. It uses CLOS’s amazing MetaObject Protocol to map Common Lisp objects to SQL records and back, and provides a Django-inspired simple interface and automatic migrations.

Internally, Crane is very similar in structure to SQLAlchemy, only most of the components SQLAlchemy implements internally are external libraries that Crane depends on. Crane is built mostly on top of fukamachiware: cl-dbi is used to provide a backend-agnostic database abstraction, and SxQL is used as the DSL for generating SQL.

            
(deftable ship ()
  (name :type text :indexp t)
  (flag :type text :nullp nil)
  (tonnage :type double :nullp nil)
  (length :type integer :nullp nil))

(create 'ship
        :name "Mærsk Mc-Kinney Møller"
        :flag "Denmark"
        :tonnage 194849
        :length 400)

            
          
cmacro

cmacro is like sweet.js for C. It implements a simple, pattern-matching based macro language that can be used to extend C.

cmacro is written in Common Lisp, and is compiled to a native binary, so you can drop it right into your Makefile between a file and clang without changing anything.

One of the project’s goals is to show how much can be added to a language with nothing more than a few simple macros, and in this I’ve succeeded.

            
/* The anonymous function macro is defined like this */

macro lambda {
  case {
    match {
      $(args) -> $(ret) $(body)
    }
    template {
      $(@getsym lambda 0)
    }
    toplevel {
      $(ret) $(@gensym lambda) $(args) $(body)
    }
  }
}

/* Now you can use it */

int main() {
  int array[] = {423, 61, 957, 133, 969,
                 829, 821, 390, 704, 596};

  qsort(array, 10, sizeof(int),
        lambda (const void* a, const void* b) -> int
        { return *(int*)a - *(int*)b; });
  for(size_t i = 0; i < 10; i++){
    printf("%i ", array[i]);
  }
  return 0;
}

            
          
Magma
            
/* Algebraic data types */
data Token {
  Integer { int i; };
  String  { char* str; };
}

/* Automatic resource management */
with_open_file(file, "companies.csv", "w+") {
  fwrite("IBM,1911,Public", 1, 15, file);
  /* The file pointer is closed here */
}

/* Lazy evaluation and type inference, too */
var future = delay 10;
/* 'future' is a lambda that takes no arguments,
   and evaluates to 10 */
var value = force future;
/* 'value' is the integer 10 */

            
          
Corona

Corona is basically a Vagrant clone. You define virtual machines (Their name, a base system to build from, amount of RAM, IP address, etc.) and Corona sets it up. It uses VirtualBox to run the machines and Vagrant Cloud as a source of base images to build machines from.

The advantage it has over Vagrant is simply that it’s pure Lisp, so it can be used as a dependency in a Common Lisp system, without the user having to set up the Ruby ecosystem to install Vagrant. It’s also pretty nice to use.

            
(defmachine my-machine
  :system (:ubuntu :14.04 :64)
  :memory 1024
  :cpu-count 5
  :ip "192.128.65.20")

;; Bring it up to do some work
(start my-machine)

;; Connect to it using the trivial-ssh library and run a command
(ssh:with-connection (conn "192.128.65.20" (ssh:agent "vagrant"))
  (ssh:with-command (conn iostream "whoami")))

;; Shut it down
(stop my-machine)

            
          
Rock

Rock is an asset manager for Common Lisp, basically a combination of Bower plus an asset pipeline. It automatically downloads web development libraries (JavaScript libraries like jQuery, JS/CSS libraries like Bootstrap, etc.), manages their versions, and allows you to merge their files together so you only serve a single CSS file and a single JS one.

            
;; We define an environment for the 'rock' ASDF system
(defenv :rock
  ;; These are our dependencies
  :assets ((:jquery :2.1.1)
           (:bootstrap :3.2.0)
           (:highlight-lisp :0.1))
  :bundles ((:js
             ;; This is a JS bundle. It compiles the JS files
             ;; of the dependencies below:
             :assets ((:jquery :2.1.1)
                      (:bootstrap :3.2.0)
                      (:highlight-lisp :0.1))
             ;; Our custom JS: assets/js/scripts.js
             :files (list #p"js/scripts.js")
             ;; Combined JS file: assets/build/js/scripts.js
             :destination #p"js/scripts.js")
            (:css
             ;; This is a CSS bundle. Note that we don't
             ;; include jQuery
             :assets ((:bootstrap :3.2.0)
                      (:highlight-lisp :0.1))
             :files (list #p"css/style.css")
             :destination #p"css/style.css")))

;; Download the assets and compile the bundles for this
;; environment. Dependencies are only downloaded when we need them
(build :rock)

            
          

Other Libraries

These are smaller projects, usually dependencies of other larger libraries (Like cl-virtualbox, which is what Corona is built on) or parts of bigger libraries I factored out so they'd be accessible to others (Like cl-pass, which grew out of hermetic).

cl-virtualbox

A few functions that map to vboxmanage commands.

trivial-ssh

A simple abstraction layer over cl-libssh2, a binding to the libssh2 library.

trivial-extract

For extracting .tar, .tar.gz and .zip files simply.

trivial-download

It downloads files.

cl-base58

An implementation of Bitcoin’s base58 encoding and decoding.

eco

A fast and designer-friendly template engine, inspired by the syntax of eRuby.

cl-pass

Password hashing and verification with reasonable, secure defaults.

hermetic

An authentication library for Clack web applications.

clack-errors

A clone of better_errors for Clack.

asdf-linguist

A collection of extensions to ASDF, the de-facto build system for Common Lisp.