A concatenative, stack-based programming language that compiles to native executables. Seq combines the elegance of stack-based programming with a sophisticated type system, guaranteed tail call optimization, and CSP-style concurrency.
Resources: Documentation | GitHub Repository
: factorial ( Int -- Int )
dup 1 i.<= if
drop 1
else
dup 1 i.- factorial i.*
then
;
: main ( -- ) 10 factorial int->string io.write-line ;
Stable as of 4.0. The language and standard library are stable and used by the creators for their own projects. That said, Seq is a niche experimental language - adopt it with eyes open. Future versions follow strict semantic versioning: major version increments indicate breaking changes to the language or standard library. Minor and patch versions add features and fixes without breaking existing code.
Stack-based simplicity. No variable declarations, no argument lists - values flow through the stack. Code reads left-to-right as a pipeline of transformations.
Strongly typed with effect tracking. Stack effects aren't just comments - they're enforced by the compiler. The type system tracks not only what goes on and off the stack, but also side effects like yielding from generators:
: counter ( Ctx Int -- | Yield Int ) # Yields integers, takes a context
tuck yield # yield current count, receive resume value
drop swap 1 i.+ counter
;
Guaranteed tail call optimization. Recursive functions run in constant stack space via LLVM's musttail. Write elegant recursive algorithms without stack overflow concerns.
CSP-style concurrency. Lightweight strands (green threads) communicate through channels. No shared memory, no locks - just message passing.
No implicit numeric conversions. Operations like i.+ and f.+ make types explicit. No silent coercion, no precision loss, no "wat" moments - when you need to mix types, you convert explicitly with int->float or float->int.
Prerequisites — clang is required to compile Seq programs (used to compile LLVM IR to native executables):
- macOS:
xcode-select --install - Ubuntu/Debian:
apt install clang - Fedora:
dnf install clang
Install from crates.io:
cargo install seq-compiler
cargo install seq-repl
cargo install seq-lspThis installs seqc (compiler), seqr (REPL), and seq-lsp (language server).
Build from source:
cargo build --releaseVirtual Environments — Create isolated environments to manage multiple Seq versions or pin a specific version for a project:
seqc venv myenv
source myenv/bin/activateThis copies the seqc, seqr, and seq-lsp binaries into myenv/bin/, completely isolated from your system installation. Unlike Python's venv (which uses symlinks), Seq copies binaries so your project won't break if the system Seq is updated.
Activate/deactivate:
source myenv/bin/activate # Prepends myenv/bin to PATH, shows (myenv) in prompt
deactivate # Restores original PATHSupports bash, zsh, fish (activate.fish), and csh/tcsh (activate.csh).
Compile and run a program:
seqc build examples/basics/hello-world.seq
./hello-worldScript mode (run directly):
seqc examples/basics/hello-world.seq # Compile and run in one stepScripts can use shebangs for direct execution:
#!/usr/bin/env seqc
: main ( -- Int ) "Hello from script!" io.write-line 0 ;
chmod +x myscript.seq
./myscript.seq arg1 arg2 # Shebang invokes seqc automaticallyScript mode compiles with -O0 for fast startup and caches binaries in ~/.cache/seq/ (or $XDG_CACHE_HOME/seq/). Cache keys include the source and all includes, so scripts recompile automatically when dependencies change.
Check version:
seqc --versionRun tests:
cargo test --allNew to concatenative programming? Start with the Glossary - it explains concepts like stack effects, quotations, row polymorphism, and CSP in plain terms.
Learn by doing: Work through seqlings - hands-on exercises that teach the language step by step, covering stack operations, arithmetic, control flow, quotations, and more. Each exercise includes hints and automatic verification.
The seqr REPL provides an interactive environment for exploring Seq:
seqrStack persists across lines:
seqr> 1 2
stack: 1 2
seqr> i.+
stack: 3
seqr> 5
stack: 3 5
seqr> : square ( Int -- Int ) dup i.* ;
Defined.
seqr> square
stack: 3 25
Commands: :clear (reset), :edit (open in $EDITOR), :pop (undo), :quit (exit), :show (show file), :stack (show stack)
Editing: Vi-mode (Esc for normal, i for insert), Shift+Enter (newline), Tab (completions), F1/F2/F3 (toggle IR views)
Stack Operations & Arithmetic:
dup drop swap over rot nip tuck pick 2dup 3drop # Stack manipulation
i.+ i.- i.* i./ i.% # Integer arithmetic
f.+ f.- f.* f./ # Float arithmetic
i.= i.< i.> i.<= i.>= i.<> # Comparisons
band bor bxor bnot shl shr popcount # Bitwise operations
Numeric literals support decimal, hex (0xFF), and binary (0b1010).
Algebraic Data Types — Define sum types with union and pattern match with match:
union Option { None, Some { value: Int } }
: unwrap-or ( Option Int -- Int )
swap match
None ->
Some { >value } -> nip
end
;
Quotations & Higher-Order Programming — Quotations are first-class anonymous functions:
[ dup i.* ] 5 swap call # Square 5 → 25
my-list [ 2 i.* ] list.map # Double each element
Concurrency — Strands (green threads) communicate through channels:
chan.make
dup [ 42 swap chan.send drop ] strand.spawn drop
chan.receive drop # Receives 42
Weaves provide generator-style coroutines with bidirectional communication:
[ my-generator ] strand.weave
initial-value strand.resume # Yields values back and forth
Standard Library — Import modules with include std:module:
| Module | Purpose |
|---|---|
std:json |
JSON parsing and serialization |
std:yaml |
YAML parsing and serialization |
std:http |
HTTP request/response utilities |
std:math |
Mathematical functions |
std:stack-utils |
Stack manipulation utilities |
See the Examples chapter for complete programs organized by category (basics, language features, paradigms, data formats, I/O, projects, FFI).
The seq-lsp language server provides IDE features in your editor.
Install: cargo install seq-lsp
Neovim: Use patch-seq.nvim with Lazy:
{ "navicore/patch-seq.nvim", ft = "seq", opts = {} }Features: Real-time diagnostics, autocompletion for builtins/local words/modules, context-aware completions, syntax highlighting.
Environment Variables:
| Variable | Default | Description |
|---|---|---|
SEQ_STACK_SIZE |
131072 (128KB) | Coroutine stack size in bytes |
SEQ_YIELD_INTERVAL |
0 (disabled) | Yield to scheduler every N tail calls |
SEQ_WATCHDOG_SECS |
0 (disabled) | Detect strands running longer than N seconds |
SEQ_REPORT |
unset (disabled) | At-exit KPI report: 1 (human to stderr), json (JSON to stderr), json:/path (JSON to file) |
SEQ_STACK_SIZE=262144 ./my-program # 256KB stacks
SEQ_YIELD_INTERVAL=10000 ./my-program # Yield every 10K tail calls
SEQ_WATCHDOG_SECS=30 ./my-program # Warn if strand runs >30s
SEQ_REPORT=1 ./my-program # Print KPI report on exitCompile with --instrument for per-word call counts in the report:
seqc build --instrument my-program.seq
SEQ_REPORT=1 ./my-program # Report includes word call countsMIT