A Lisp evaluation environment for decision rules
(Lispex)
( parens are punctuation, recursion is rhyme )
Write refund policies and eligibility rules as short, independent programs and receive answers as transparent data. Run them in your browser, inside a Node.js project, or on your local machine.
Here is a refund policy, all of it.
A request arrives as a list of named fields. Every answer, refusals included, comes back as a clean list you can print, store, and compare against any other answer.
(define (review request)
(let ((days (cdr (assq 'days request)))
(opened (cdr (assq 'opened request)))
(cents (cdr (assq 'cents request))))
(cond ((>= days 15) '(deny outside-window))
(opened '(deny opened-item))
((> cents 50000) '(escalate manual-review))
(else '(allow within-policy)))))
(map review
'(((days . 14) (opened . #f) (cents . 12900))
((days . 14) (opened . #f) (cents . 82000))
((days . 15) (opened . #f) (cents . 12900))))
; => ((allow within-policy) (escalate manual-review) (deny outside-window))Four strict constraints that keep Lispex predictable
Every if form has an else arm. Built-in procedures form a fixed list of 205 names. Higher-order procedures like map and filter accept exactly one list at a time. The fixed grammar keeps every form readable with the same meaning.
The value of these limits is clear. A rule you open a year later reads exactly as written, and when a program fails, it fails in the exact same way every time.
See the complete syntax at a glanceRuns in three places, powered by a single reference implementation.
The Playground runs your code locally inside the browser. The npm package runs Lispex inside a Node.js project. The downloadable program runs locally on your machine with the widest set of commands.
All three environments share the same single reference implementation written in Rust. The browser and npm reach it through WebAssembly, while the downloadable program runs it directly. What differs is the command scope and memory or recursion limits, and every runtime clearly reports its execution limits.
Hand someone a decision they can independently verify.
The downloadable program can digitally sign a record of a run. The executed rule, the input data, and the resulting answer are sealed together in a single signed record.
The recipient supplies their own trusted copy of the rule and input data, runs it again on their own machine, and verifies that today’s answer reproduces the signed record. The recipient configures the verification key directly under their own trust policy.
Passing verification establishes exact execution agreement. The calling application evaluates this verified record and authorizes the business action under its own policy.
This image holds an entire rule in its pixels.

(let ((input '((days . 14) (opened . #f))))
(let ((days (cdr (car input)))
(opened (cdr (car (cdr input)))))
(if (< days 15)
(if opened "deny" "allow")
"deny")))The pixels carry the exact source code below byte for byte. You can recover it on your machine or in the Playground. The decoder accepts the canonical PNG or ordered page set created by the Lispex image codec.
The image preserves source bytes intact across systems, ready for direct decoding, inspection, or execution.
Keep the whole language within reach.
Start with the introduction, then move through the learning path, syntax, runtimes, images, and Vouch in one connected manual.
Read the introduction