Here are some projects I'm working on, actively or passively, which I felt didn't fit into the other sections on teaching, or creative works, or details about myself.


mulligan is a stepping debugger for the Standard ML language, aimed at making it easy to trace through the execution of simple Standard ML expressions, at a finer level of granularity than is possible through the SML/NJ REPL, which will not display the intermediary steps it takes to compute a value.

Floating Image
While mulligan works fine on simple examples, it is currently in a beta state which is likely to have bugs. In addition, the standard library is not currently implemented in it, meaning that definitions must be supplied for most all functions for mulligan to know about it. Regardless, for teaching purposes, mulligan is useful for programmatically generating traces, as well as for clarifying to beginners how SML's execution model really works.


deriving-sml is a code generation tool that aims to limitedly mimic the functionality of its more popular OCaml cousin, ppx-deriving, but for the Standard ML language.

deriving-sml supports four "plugins", those being eq, compare, show, and map. deriving-sml parses a "meta-SML" dialect which includes "deriving metadata" attached to type declarations, which signals to deriving-sml to produce code for each of the four functionalities, in a type-directed way.

For instance, the following code:

structure Foo =
    type t = int * string [.deriving show, eq]

    datatype t2 =
      | Two [.deriving show, compare]

produces the following code, when fed into deriving-sml:

structure Foo =
    type t = (int * string) (* [.deriving show,eq] *)
    fun show_t (t1, t2) =
        (op^ ( ((op^ ( ("(",
                        (op^ ( ((Int.toString ( t1 )),
                                (op^ ( (", ",
                                        (op^ ( ((op^ ( ("\"", t2) )),
                                                "\"") ))) ))) ))) )),
                ")") ))
    and t_show x = (show_t ( x ))
    fun eq_t ((t5, t7), (t6, t8)) =
        ((op= ( (t5, t6) )) andalso (op= ( (t7, t8) )))
    and t_eq x = (eq_t ( x ))
    datatype t2 = One | Two (* [.deriving show,compare] *)
    fun show_t2 t9 = (case t9 of One => "One" | Two => "Two")
    and t2_show x = (show_t2 ( x ))
    fun cmp_t2 (t10, t11) =
        (case (t10, t11) of
           (One, One) => EQUAL
         | (Two, Two) => EQUAL
         | (x, y) =>
             ( ( (((fn x =>
                                    (case x of
                                       One => 0
                                     | Two => 1)) ( x )),
                             ((fn x =>
                                    (case x of
                                       One => 0
                                     | Two => 1)) ( y ))) )))
    and t2_cmp x = (cmp_t2 ( x ))
    and t2_compare x = (cmp_t2 ( x ))
    and compare_t2 x = (cmp_t2 ( x ))