Tulisp
Tulisp is an embeddable Lisp interpreter for Rust with Emacs Lisp-compatible syntax. It is designed as a configuration and scripting layer for Rust applications — zero external dependencies, low startup cost, and a clean API for exposing Rust functions to Lisp code.
Quick start
Requires Rust 1.88 or higher.
use process;
use ;
Exposing Rust functions
TulispContext::defun
is the primary way to register Rust functions.
Argument evaluation, arity checking, and type conversion are handled
automatically.
use ;
let mut ctx = new;
// Fixed arguments
ctx.defun;
// Optional arguments (Lisp &optional)
ctx.defun;
// Variadic arguments (Lisp &rest)
ctx.defun;
// Fallible function
ctx.defun;
Supported argument and return types include i64, f64, bool, String,
Number,
Vec<T>, and TulispObject.
Add &mut TulispContext as the first parameter to access the interpreter.
Any type can be made passable by implementing
TulispConvertible.
For advanced use cases — custom evaluation order, implementing control flow —
use defspecial
(raw argument list) or
defmacro
(code transformation before evaluation).
Keyword-argument functions with AsPlist!
When a function accepts many optional parameters, use a plist as the argument
list. The AsPlist!
macro derives the required
Plistable trait
for a struct, and
Plist<T> as a
parameter type wires it up automatically.
use ;
AsPlist!
}
let mut ctx = new;
ctx.defun;
// (connect :host "localhost") => "localhost:8080"
// (connect :host "example.com" :port 443) => "example.com:443"
Opaque Rust values
Any Clone + Display type can be stored in a
TulispObject
and passed between Rust and Lisp transparently via
Shared::new and
TulispObject::as_any.
use fmt;
use ;
let mut ctx = new;
ctx.defun;
ctx.defun;
// (point-x (make-point 3 4)) => 3
Built-in Lisp features
- Control flow:
if,cond,when,unless,while,progn - Binding:
let,let*,setq,set - Functions and macros:
defun,defmacro,lambda,funcall,eval,macroexpand - Lists:
cons,list,append,nth,nthcdr,last,length,mapcar,dolist,dotimes - Alists and plists:
assoc,alist-get,plist-get - Strings:
concat,format,prin1-to-string,princ,print - Arithmetic:
+,-,*,/,mod,1+,1-,abs,max,min,sqrt,expt,fround,ftruncate - Comparison:
=,/=,<,<=,>,>=(numbers);string<,string>,string=(strings);eq,equal - Logic:
and,or,not,xor - Conditionals:
if-let,if-let*,when-let,while-let - Symbols:
intern,make-symbol,gensym - Hash tables:
make-hash-table,gethash,puthash - Error handling:
error,catch,throw - Threading macros:
->/thread-first,->>/thread-last - Time:
current-time,time-add,time-subtract,time-less-p,time-equal-p,format-seconds - Quoting:
',`,,,,@(backquote/unquote/splice) - Tail-call optimisation (TCO) for recursive functions
- Lexical scoping and lexical binding
A full reference is available in the builtin module docs.
Cargo features
| Feature | Description |
|---|---|
sync |
Makes the interpreter thread-safe (Arc/RwLock instead of Rc/RefCell) |
big_functions |
Increases the maximum number of defun parameters from 5 to 10 |
etags |
Enables TAGS file generation for Lisp source files |
Next steps
TulispContext— interpreter state, evaluation methods, and function registrationTulispObject— the core Lisp value typeTulispConvertible— how Rust types map to Lisp valuesbuiltin— all built-in functions and macros