Skip to content

navicore/patch-seq

Repository files navigation

CI - Linux

seq-compiler seq-repl seq-lsp

seq-compiler docs seq-runtime docs vim-line docs

Seq - Concatenative Language

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 ;

Project Status

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.


Why Seq?

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.


Installation

Prerequisitesclang 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-lsp

This installs seqc (compiler), seqr (REPL), and seq-lsp (language server).

Build from source:

cargo build --release

Virtual Environments — Create isolated environments to manage multiple Seq versions or pin a specific version for a project:

seqc venv myenv
source myenv/bin/activate

This 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 PATH

Supports bash, zsh, fish (activate.fish), and csh/tcsh (activate.csh).


Quick Start

Compile and run a program:

seqc build examples/basics/hello-world.seq
./hello-world

Script mode (run directly):

seqc examples/basics/hello-world.seq          # Compile and run in one step

Scripts 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 automatically

Script 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 --version

Run tests:

cargo test --all

Learn Seq

New 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.


Interactive REPL

The seqr REPL provides an interactive environment for exploring Seq:

seqr

Stack 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)


Language Features

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

Sample Programs

See the Examples chapter for complete programs organized by category (basics, language features, paradigms, data formats, I/O, projects, FFI).


Editor Support

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.


Configuration

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 exit

Compile 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 counts

License

MIT

About

a compiled and strongly typed contactinative computer programming language

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages