Building a Lisp in hica

Version 0.29.3 of hica is out and the core is getting pretty stable. I wanted to explore whether hica could be used to write a small Lisp, as a way to stress-test the hica compiler: closures, recursive data structures, lexical scoping, higher-order functions.

HiLisp is now live and ready for tinkering.

Why a Lisp?

Many developers write a Lisp at some point. Same thing here really.

The useful part is that maintaining HiLisp is hica development. Every script and example exercises the compiler and provides feedback. I ended up fixing several bugs in hica while building HiLisp.

The main inspiration was Carp, a Lisp with ML/Rust-like semantics. HiLisp borrows its vocabulary of special forms: defn, def, fn, let, do, cond, quote.

Also, there is objective beauty in parentheses.

What it looks like

(defn factorial (n)
  (if (<= n 1) 1 (* n (factorial (- n 1)))))

(println (factorial 10))   ; 3628800

Closures work:

(defn make_adder (n) (fn (x) (+ x n)))
(def add10 (make_adder 10))
(println (add10 32))   ; 42

And higher-order functions:

(defn map (f lst)
  (if (= lst '()) '()
    (cons (f (car lst)) (map f (cdr lst)))))

(println (map (fn (x) (* x x)) '(1 2 3 4 5)))
; (1 4 9 16 25)

The pipeline

HiLisp is a classic tree-walker interpreter:

source text → tokenise → parse → eval

Each phase lives in its own hica module: tokeniser.hc, parser.hc, eval.hc. The AST is a recursive LVal enum representing numbers, booleans, strings, symbols, lists, lambdas, and nil. Pattern matching over that enum drives the evaluator.

The interesting bit was environments. Each lambda captures a reference to its defining environment for proper lexical scoping. I expected that to need some gymnastics, but structs and recursive types in hica made it pretty straightforward.

Try it

./hilisp                         # REPL
./hilisp examples/recursion.hl   # run a file

# Build from source (needs hica ≥ 0.29.3 and Koka 3.2.3)
hica build -o hilisp

The examples/ folder contains runnable .hl files covering arithmetic, closures, recursion, lists, and sorting. There’s also a lib/prelude.hl with helpers like map, filter, and fold.

Going forward, I’ll definitely be using HiLisp as part of hica development itself, both as a playground and as a way to continuously exercise the compiler with real code.