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.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 = struct type t = int * string [.deriving show, eq] datatype t2 = One | Two [.deriving show, compare] end
produces the following code, when fed into deriving-sml:
structure Foo = struct 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) => (Int.compare ( (((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 )) end