Taking programming to another planet 🚀
Pluto is a compiled language that combines the clarity of scripting languages with the type-safety, performance, and determinism of systems languages.
Functions in Pluto are templates defined in .pt files. Call a template with different argument types and Pluto generates specialized native code for each — no generics syntax, no runtime dispatch. Write concise programs that compile into efficient, fully specialized executables.
Design highlights:
Purity: Functions have read-only inputs and writable outputs; structs are raw data with no hidden pointers.
Range-driven auto-vectorization, safe arrays and slices.
Scope-based memory (no nulls, no out-of-bounds, no GC), and concurrency by construction.
- Go front-end, LLVM back-end; emits native binaries
- Template functions in
.pt: specialized per argument types (generics by use) - Range literals with auto-vectorized execution
- First-class arrays (safe slicing) and link semantics
- Scope-based memory: no nulls, no out-of-bounds, no garbage collector
- printf-style formatting; arrays/ranges printable
- Cross-platform (Linux/macOS/Windows)
Hello world (tests/helloworld.spt):
"hello world"
x = "hello 🙏"
x, "👍"
No main(), no print(), no imports. Values on a line get printed.
Compile and run:
./pluto tests/helloworld.spt
./tests/helloworld
Output:
hello world
hello 🙏 👍
Pluto can compile a single .spt file or an entire directory — each .spt produces a native executable.
Pluto separates reusable templates from executable scripts:
| Extension | Purpose |
|---|---|
.pt |
Template files — functions, operators, structs, constants (act as libraries) |
.spt |
Script files — executable programs that compile to native binaries |
A directory is the unit of compilation:
math/
├── math.pt # defines Square, etc.
└── func.spt # uses them → compiles to ./math/func
Compile and run:
./pluto math
./math/func
Templates are defined once with a clear input/output contract. The first line declares the output and input — the indented body describes the transformation.
Think of a template as a black box: data flows in through inputs, gets transformed, and flows out through outputs. Outputs work by reference — calling a template directly modifies the output variable in the caller's scope.
math.pt
# y is the output (writable), x is the input (read-only)
y = Square(x)
y = x * x
Inputs are read-only — they flow in. Outputs are writable — they flow out. Every function is a transformation.
Call Square with different types — Pluto compiles a specialized version for each:
func.spt
a = Square(2) # int specialization
b = Square(5.6) # float specialization
arr = [1 2 3 4 5]
c = Square(arr) # squares every element
d = Square(arr > 2) # squares only elements where arr > 2
e = Square(1:5) # range — executes Square over each value
a, b, c, d, e
No generics syntax, no type parameters. Write the template once — call it with a scalar, an array, or a filtered view. arr > 2 filters the array to elements greater than 2 and passes that subset through.
Generated code is equivalent to handwritten specialized code. There is no runtime overhead.
Ranges are first-class values:
Square(1:5)
Passing a range to a template executes it across all values. The compiler can map these operations to SIMD instructions — this is range-driven auto-vectorization.
Data-parallel execution without explicit loop syntax.
Arrays use bracket syntax with no commas:
x = [1 2 3 4 5]
y = [1.1 2.2 3.3]
Arrays are safe by construction — out-of-bounds access is not possible. Comparisons like arr > 2 produce filtered views that work anywhere an array does.
Functions are pure transformations:
- Inputs are read-only
- Outputs are writable
- Global constants allowed
- No hidden mutation
This keeps behavior predictable and easier to parallelize.
Pluto uses deterministic, scope-based memory:
- No garbage collector
- No null values
- No out-of-bounds access
- Memory freed when scope ends
Predictable performance with minimal runtime overhead.
Pluto is designed so that:
- Structs are pure data
- Functions are transformations
- Inputs are read-only
This enables strong guarantees around race-free execution. The concurrency model is evolving but built around deterministic behavior.
Build the compiler:
go build -o plutoCompile a directory:
./pluto tests # Compiles all .spt files in tests/
./tests/helloworld # Run the compiled executableRun tests:
python3 test.py # Full E2E suite
python3 test.py --leak-check # Full suite + memory leak detection
go test -race ./lexer ./parser ./compiler # Unit tests onlyNew project setup:
Add a pt.mod file at your project root to define the module path:
module github.com/you/yourproject
Pluto walks up from the working directory to find pt.mod and treats that directory as the project root.
Other commands:
./pluto --version(or-v) — show version./pluto --clean(or-c) — clear cache for current version
- Go 1.25+
- LLVM 21 tools on PATH:
clang,opt,llc,ld.lld - Python 3.x (for running tests)
- Leak check tools (only for
python3 test.py --leak-check):- Linux:
valgrind - macOS:
leaks
- Linux:
Linux
Install LLVM 21 from apt.llvm.org:
wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && sudo ./llvm.sh 21
sudo apt install lld-21
export PATH=/usr/lib/llvm-21/bin:$PATHBuild and test:
go build -o pluto
python3 test.pymacOS (Homebrew)
brew install llvmSet PATH for your architecture:
# Apple Silicon
export PATH=/opt/homebrew/opt/llvm/bin:$PATH
# Intel
export PATH=/usr/local/opt/llvm/bin:$PATHBuild and test:
go build -o pluto
python3 test.pyWindows (MSYS2 UCRT64)
Install MSYS2 and use the "MSYS2 UCRT64" shell.
Install packages:
pacman -S --needed mingw-w64-ucrt-x86_64-{go,llvm,clang,lld,python}Quick build:
python scripts/msys2_build.pyOr manual build with required environment:
export CGO_ENABLED=1
export CC=clang CXX=clang++
export GOFLAGS='-tags=byollvm'
export CGO_CPPFLAGS="$(llvm-config --cflags) -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"
export CGO_CXXFLAGS="-std=c++17 $(llvm-config --cxxflags)"
export CGO_LDFLAGS="$(llvm-config --ldflags --libs all --system-libs)"
go build -o pluto.exeRun tests:
python test.pyNotes:
- On Windows the produced binary is
pluto.exe. - The runtime enables
%non UCRT to match POSIXprintfbehavior.
Pluto is under active development.
Working today:
- 🎯 Template specialization
- 📊 Arrays and ranges
- 🖥️ Native binaries
- 🧞♂️ Cross-platform builds
In progress:
- 🧵 Concurrency model
- 🧰 Tooling
- 📘 Documentation
- 💎 Purity by design — functions have read-only inputs and writable outputs; structs contain raw data with no hidden pointers
- ✨ The simplicity of scripting
- ⚡ The type safety and speed of low-level languages
- 🧠 Deterministic memory
- 🔧 Automatic specialization
- 🔒 Predictable concurrency
Intended for performance-sensitive scripting, numerical work, simulation, and systems tools.
| Path | Description |
|---|---|
main.go |
CLI entry point |
ast/ |
Abstract syntax tree definitions |
lexer/ |
Tokenizer with indentation-based syntax |
parser/ |
Recursive descent parser |
compiler/ |
Type solving, IR generation, LLVM emission |
runtime/ |
Embedded C runtime linked into executables |
tests/ |
End-to-end tests (.spt inputs, .exp expected outputs) |
- Two phases: CodeCompiler parses
.ptfiles and saves function templates and constants; ScriptCompiler compiles specialized versions for each usage in.sptfiles (if not already cached). - Automatic pipeline: generate IR → optimize
-O3viaopt→ object viallc→ link with runtime viaclang/lld— all handled transparently. - Module resolution: walks up from CWD to find
pt.modand derives module path. - Cache layout (versioned to isolate different compiler versions):
<PTCACHE>/<version>/runtime/<hash>/for compiled runtime objects<PTCACHE>/<version>/<module-path>/{code,script}for IR/objects
Common issues
undefined: run_build_sh during build (Windows):
- Ensure
GOFLAGS='-tags=byollvm'and CGO flags are set (see Windows installation above)
Missing LLVM tools:
- Verify
opt,llc,clang,ld.lldfrom LLVM 21 are on PATH
Stale cache behavior:
- Clear current version:
./pluto --clean - Clear all versions:
- macOS:
rm -rf "$HOME/Library/Caches/pluto" - Linux:
rm -rf "$HOME/.cache/pluto" - Windows:
rd /s /q %LocalAppData%\pluto
- macOS:
- Override cache location with
PTCACHEenvironment variable
Encoding issues on Windows:
- Run from the MSYS2 UCRT64 shell; the runner decodes output as UTF-8
- Commit style: Conventional Commits (e.g.,
feat(parser): ...,fix(compiler): ...) - PRs: include a clear description, linked issues, and tests for changes
- Go formatting:
go fmt ./... - Run tests before submitting:
python3 test.py
Pluto is licensed under the MIT License. See LICENSE.
Vendored third-party code:
runtime/third_party/klib/(klib by Attractive Chaos) — MIT License, seeruntime/third_party/klib/LICENSE.txt