Feature Comparison
How does Sema stack up against other Lisps and Lisp-adjacent languages as a practical tool? This isn't about benchmarks (see Lisp Dialect Benchmark for that) — it's about what you can actually do out of the box.
Languages Compared
| Language | Implementation | Primary Use Case |
|---|---|---|
| Sema | Rust (bytecode VM) | LLM-native scripting, AI tooling |
| Janet | C (bytecode VM) | Embeddable scripting, system tools |
| Racket | Chez Scheme backend | Teaching, DSLs, research |
| Clojure | JVM | Production backend systems |
| Fennel | Lua transpiler | Game dev, Lua ecosystem |
| Guile | C (bytecode VM) | GNU extension language |
| Common Lisp (SBCL) | Native compiler | Production systems, HPC |
Platform & Distribution
| Feature | Sema | Janet | Racket | Clojure | Fennel | Guile | SBCL |
|---|---|---|---|---|---|---|---|
| Standalone executables | ✅ sema build | ✅ jpm | ✅ raco exe | ⚠️ GraalVM only | ⚠️ --compile-binary | ❌ | ✅ save-lisp-and-die |
| Bytecode compilation | ✅ .semac | ✅ images | ✅ .zo | ✅ .class | ❌ | ✅ .go | ✅ FASL |
| WASM / browser | ✅ sema.run | ⚠️ community | ⚠️ WebRacket (subset) | ✅ ClojureScript | ⚠️ via Fengari | ⚠️ Hoot (R7RS subset) | ⚠️ ECL/Emscripten |
| Web playground | ✅ 20+ examples | ⚠️ community | ⚠️ Try Racket | ⚠️ community | ✅ on fennel-lang.org | ❌ | ❌ |
| Shebang scripts | ✅ | ✅ | ✅ | ⚠️ clojure CLI | ✅ | ✅ | ✅ --script |
| Homebrew install | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Windows support | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ | ⚠️ |
| Install script (curl) | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ |
Embedding
| Feature | Sema | Janet | Racket | Clojure | Fennel | Guile | SBCL |
|---|---|---|---|---|---|---|---|
| Embed in Rust | ✅ crate API | ⚠️ via FFI | ❌ | ❌ | ❌ | ⚠️ via FFI | ❌ |
| Embed in C/C++ | ⚠️ via FFI | ✅ single .c+.h | ✅ | ❌ | ✅ single file | ✅ libguile | ❌ |
| Runs in JS/browser | ✅ WASM module | ⚠️ community WASM | ❌ | ⚠️ via ClojureScript | ⚠️ via Fengari | ❌ | ❌ |
| Sandbox mode | ✅ --sandbox | ✅ sandbox | ✅ | ❌ | ❌ | ✅ ice-9 sandbox | ❌ |
Built-in Standard Library
| Feature | Sema | Janet | Racket | Clojure | Fennel | Guile | SBCL |
|---|---|---|---|---|---|---|---|
| Stdlib functions | 700+ | 600+ | 1000+ | 700+ | ~50 (+ Lua) | 500+ | 900+ |
| HTTP client | ✅ built-in | ⚠️ via library | ✅ built-in | ⚠️ via library | ⚠️ via Lua | ✅ (web client) | ⚠️ via library |
| JSON | ✅ built-in | ⚠️ via spork | ✅ built-in | ⚠️ via library | ❌ | ⚠️ via library | ⚠️ via library |
| Regex | ✅ built-in | ✅ PEGs | ✅ built-in | ✅ built-in | ✅ Lua patterns | ✅ built-in | ⚠️ via library |
| CSV | ✅ built-in | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Crypto (SHA, HMAC) | ✅ built-in | ⚠️ via library | ⚠️ SHA-1/MD5 only | ⚠️ via library | ❌ | ⚠️ via library | ⚠️ via library |
| PDF extraction | ✅ built-in | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| File I/O | ✅ built-in | ✅ built-in | ✅ built-in | ✅ via Java | ✅ via Lua | ✅ built-in | ✅ built-in |
| Date/time | ✅ built-in | ✅ built-in | ✅ built-in | ✅ via Java | ✅ via Lua | ✅ built-in | ⚠️ via library |
| Shell execution | ✅ built-in | ✅ built-in | ✅ built-in | ✅ built-in | ✅ via Lua | ✅ built-in | ✅ built-in |
| KV store | ✅ built-in | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| SQLite | ✅ built-in | ⚠️ via library | ✅ db collection | ⚠️ via JDBC | ⚠️ via Lua | ⚠️ via library | ⚠️ via library |
| TOML | ✅ built-in | ⚠️ via library | ❌ | ⚠️ via library | ❌ | ❌ | ⚠️ via library |
| Web server | ✅ built-in (axum) | ⚠️ via library | ✅ built-in | ⚠️ Ring/Jetty | ⚠️ via Lua | ✅ (web server) | ⚠️ via library |
| Terminal styling | ✅ built-in | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
LLM & AI
Sema provides these features in its standard runtime. Other Lisps can provide similar behavior through libraries; this table compares the default language distributions and commonly documented tooling listed here.
| Feature | Sema | Janet | Racket | Clojure | Fennel | Guile | SBCL |
|---|---|---|---|---|---|---|---|
| LLM chat/completion | ✅ built-in | ❌ | ❌ | ⚠️ via library | ❌ | ❌ | ❌ |
| Multi-provider (8+) | ✅ | — | — | — | — | — | — |
| Streaming | ✅ built-in | — | — | — | — | — | — |
| Tool use / agents | ✅ deftool defagent | — | — | — | — | — | — |
| Structured extraction | ✅ llm/extract | — | — | — | — | — | — |
| Vision / images | ✅ built-in | — | — | — | — | — | — |
| Embeddings | ✅ 3 providers | — | — | — | — | — | — |
| Vector store (RAG) | ✅ built-in | — | — | — | — | — | — |
| Cost tracking | ✅ llm/budget | — | — | — | — | — | — |
| Response caching | ✅ llm/with-cache | — | — | — | — | — | — |
| Conversations | ✅ immutable data | — | — | — | — | — | — |
| Provider fallback | ✅ llm/with-fallback | — | — | — | — | — | — |
| Prompt templates | ✅ built-in | — | — | — | — | — | — |
Language Features
| Feature | Sema | Janet | Racket | Clojure | Fennel | Guile | SBCL |
|---|---|---|---|---|---|---|---|
| Tail-call optimization | ✅ | ✅ | ✅ | ⚠️ recur only | ✅ via Lua | ✅ | ⚠️ not guaranteed |
| Macros | ✅ defmacro | ✅ | ✅ hygienic | ✅ | ✅ | ✅ both | ✅ |
| Pattern matching | ✅ match | ✅ | ✅ | ⚠️ via core.match | ✅ | ✅ | ⚠️ via library |
| Modules | ✅ | ✅ | ✅ | ✅ namespaces | ✅ via Lua require | ✅ | ✅ packages |
| Continuations | ❌ | ⚠️ fibers | ✅ call/cc | ❌ | ❌ | ✅ call/cc | ❌ |
| Async/Channels | ✅ cooperative | ❌ | ❌ | ✅ core.async | ❌ | ❌ | ⚠️ via library |
| Multithreading | ❌ | ✅ | ✅ | ✅ | ✅ via Lua | ✅ | ✅ |
| Persistent data structures | ⚠️ COW maps | ❌ | ❌ | ✅ core design | ❌ | ❌ | ❌ |
| Keywords | ✅ :foo | ✅ :foo | ✅ #:foo | ✅ :foo | ✅ :foo | ✅ #:foo | ✅ :foo |
| Map literals | ✅ {:a 1} | ✅ {:a 1} | ✅ #hash(...) | ✅ {:a 1} | ✅ {:a 1} | ❌ | ❌ |
| Vector literals | ✅ [1 2] | ✅ [1 2] | ✅ #(1 2) | ✅ [1 2] | ✅ [1 2] | ✅ #(1 2) | ✅ #(1 2) |
| F-strings | ✅ f"${x}" | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Short lambdas | ✅ #(+ % 1) | ✅ ` | (+ $ 1)` | ❌ | ✅ #(+ % 1) | ✅ #(+ $1 1) | ❌ |
| Threading macros | ✅ -> ->> | ✅ -> ->> | ⚠️ via library | ✅ -> ->> | ✅ -> ->> | ❌ | ⚠️ via library |
Developer Experience
| Feature | Sema | Janet | Racket | Clojure | Fennel | Guile | SBCL |
|---|---|---|---|---|---|---|---|
| REPL | ✅ | ✅ | ✅ DrRacket | ✅ nREPL | ✅ | ✅ | ✅ SLIME/Sly |
| Tab completion | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ | ✅ |
| Editor support | VS Code, IntelliJ, Zed, Vim, Emacs, Helix | VS Code, Vim, Emacs | DrRacket, Emacs, VS Code | Emacs, VS Code, IntelliJ | Emacs, Vim, VS Code | Emacs (Geiser) | Emacs (SLIME/Sly) |
| Package manager | ⚠️ git-based | ✅ jpm | ✅ raco | ✅ deps.edn/Lein | ❌ (uses Lua) | ⚠️ Guix | ✅ Quicklisp |
| Code formatter | ✅ sema fmt | ❌ | ✅ raco fmt | ✅ cljfmt | ❌ | ❌ | ❌ |
| Debugger | ✅ sema dap (DAP) | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| LSP server | ✅ sema lsp | ⚠️ community | ✅ racket-langserver | ✅ clojure-lsp | ⚠️ fennel-ls | ⚠️ community | ⚠️ community |
| Notebook | ✅ sema notebook | ❌ | ⚠️ Jupyter kernel | ✅ Clerk | ❌ | ⚠️ Jupyter kernel | ⚠️ Jupyter kernel |
| Documentation site | ✅ sema-lang.com | ✅ janet-lang.org | ✅ docs.racket-lang.org | ✅ clojure.org | ✅ fennel-lang.org | ✅ gnu.org/guile | ✅ cliki.net |
| Startup time | ~5ms | ~5ms | ~200ms | ~1–2s | ~5ms | ~50ms | ~50ms |
Summary
Sema is not trying to be the fastest Lisp or the most theoretically pure. It is designed for practical scripting with an integrated LLM runtime. deftool, defagent, llm/extract, provider translation, budgets, replay, and tracing ship together and use the same value model.
If you need the fastest execution, use SBCL or Chez Scheme. If you need the JVM ecosystem, use Clojure. If you need academic rigor and DSL tooling, use Racket. If you need a tiny embeddable C scripting engine, use Janet.
Choose Sema when you want to build agents, extract structured data from model output, or prototype LLM tools with those facilities in the standard runtime. Choose an existing Lisp plus libraries when its ecosystem and compatibility are more important than Sema's integrated toolchain.