HiLisp is a tree-walking Lisp interpreter built entirely in hica, a language that compiles to Koka. It serves as a proof of concept that hica is expressive enough to implement a real language, including closures, recursion, and higher-order functions.
Inspiration: Carp (special form vocabulary) and Jank (loop/recur tail-recursive iteration).
# Run the REPL
./hilisp
# Run a .hl file
./hilisp examples/recursion.hl
# Build from source (requires hica ≥ 0.29.3 and Koka 3.2.3)
hica build -o hilispNew to Lisp? Start with docs/lisp-primer.md.
HiLisp is dynamically typed. Values are numbers, booleans, strings, lists, functions, or nil. All code is an s-expression.
| Form | Description |
|---|---|
(def name val) |
Bind a value |
(defn name (p1 p2) body) |
Define a named function (supports recursion) |
(fn (p1 p2) body) |
Anonymous lambda |
(if cond then else) |
Conditional — all three branches required |
(cond p1 e1 p2 e2 …) |
Multi-branch; use true as final predicate for default |
(let (x 1 y 2) body) |
Local bindings |
(do e1 e2 …) |
Sequence; returns last value |
(quote x) / 'x |
Quote — return unevaluated |
(loop [x init …] body) |
Tail-recursive loop with named bindings |
(recur v1 v2 …) |
Restart the enclosing loop with new values — no stack growth |
+ - * / = < > <= >= not and or null? empty?
car cdr cons list length
println str
(defn factorial (n)
(if (<= n 1) 1 (* n (factorial (- n 1)))))
(println (factorial 10)) ; 3628800(defn make_adder (n) (fn (x) (+ x n)))
(def add10 (make_adder 10))
(println (add10 32)) ; 42(defn mod (a b) (- a (* b (/ a b))))
(defn fizzbuzz (n)
(cond
(= (mod n 15) 0) "fizzbuzz"
(= (mod n 3) 0) "fizz"
(= (mod n 5) 0) "buzz"
true n))
(loop [i 1]
(if (<= i 20)
(do (println (fizzbuzz i)) (recur (+ i 1)))
nil)); Sum 1..100 without recursion or stack growth
(def total
(loop [i 1 acc 0]
(if (> i 100)
acc
(recur (+ i 1) (+ acc i)))))
(println total) ; 5050The examples/ directory contains runnable .hl files:
| File | What it shows |
|---|---|
arithmetic.hl |
Basic operators, def, expressions |
functions.hl |
Higher-order functions, closures |
recursion.hl |
Factorial, Fibonacci, power |
lists.hl |
car/cdr/cons, map, filter |
closures.hl |
Closure factories, compose |
fizzbuzz.hl |
cond, loops, custom mod |
sorting.hl |
Merge sort and insertion sort |
statistics.hl |
Mean, median, variance, standard deviation |
higher_order.hl |
scan, windows, flat_map, partition, enumerate |
loop.hl |
loop/recur — countdown, accumulator sum, O(n) Fibonacci |
src/
ast.hc - LVal and Env types
types.hc - env_get / env_set
tokeniser.hc - source text → token list
parser.hc - token list → LVal AST
display.hc - lval_show
builtins.hc - built-in functions + make_env()
eval.hc - tree-walking evaluator
lisp.hc - barrel re-export
main.hc - CLI, REPL, file runner
Load lib/prelude.hl as the first argument to get a full set of list, math, and
string utilities:
./hilisp lib/prelude.hl examples/sorting.hlSee docs/hilisp-hica-guide.md for the full function reference.
printlnuseslval_show, so strings display with quotes.- Recursive
defnfunctions withoutloop/recurwill stack-overflow on deep input — useloop/recurfor iteration.