A pure, practical functional language that's easy to learn with simple and familiar syntax.
- Static Types with Inference: Full type inference including ability (effect) inference
- Algebraic Effects: Unison-style abilities with delimited, one-shot continuations
- Familiar Syntax: ML semantics with C/Rust-style syntax
(
fn,{},;,struct/enum) - Multiple Targets: Cranelift (native) and WasmGC
Current implementation support is narrower than the language design. See the compiler capability matrix for audited frontend, native, and WasmGC status. Compilation alone is not execution evidence.
use std::abilities::Throw
use std::io::{Io, print_line}
fn fail() ->{Throw(String)} String {
Throw::throw("the failure was handled")
}
fn recover() -> String {
handle fail() {
do value { value }
op Throw::throw(message) { "Recovered: " <> message }
}
}
fn main() ->{Io} Nil {
print_line(recover())
}
After cloning the repository, set up the git hooks:
git config core.hooksPath .ci/githooksFor Tree-sitter grammar development, install the Tree-sitter CLI:
npm install -g tree-sitter-cliThe commands below use these external tools:
- cargo-nextest to run the test suite
- cargo-insta to review snapshot changes
- Wasmtime to run Wasm examples
The repository does not pin cargo-nextest. CI installs Wasmtime as a prebuilt binary. For local Wasm runtime tests, install the prebuilt Wasmtime 45.0.1 CLI without a source-build fallback:
Install cargo-binstall first, then run:
cargo binstall --strategies crate-meta-data,quick-install wasmtime-cli@45.0.1Keep that version until a replacement has been verified with the
-Wgc=y,function-references=y and -Wtail-call=y options used by the runtime
tests and CI.
# Build the native runtime into the development sysroot (target/sysroot).
# Rerun after changing crates/tribute-runtime.
cargo xtask runtime
# Build the entire workspace
cargo build
# Run all tests
cargo nextest run --workspace -j num-cpus
# Compile one source file to a native executable
cargo run -- compile lang-examples/native_effects.trb \
-o target/native-effects-example
# Run the resulting executable
./target/native-effects-exampleThe tribute CLI compiles one source file at a time; file-module and package
compilation are not implemented. There is no run subcommand. compile
defaults to --target native and accepts these targets:
nativewrites a linked executable.wasmwrites a WasmGC module. Execute it with a compatible external runtime.nonevalidates the frontend and shared pipeline without writing an artifact.
Use -o or --output to choose the artifact path. Without it, native removes
the .trb extension and Wasm replaces it with .wasm.
Native linking uses the runtime library from a sysroot. The compiler takes
--sysroot, then the TRIBUTE_SYSROOT environment variable, then the parent
of its own executable's directory. Inside this repository, .cargo/config.toml
points TRIBUTE_SYSROOT at the target/sysroot that cargo xtask runtime
populates. See the linking design.
See lang-examples/README.md for exact native, Wasm,
and invalid-example commands. It also classifies historical files as regression
fixtures, design-only examples, or legacy samples.
The pre-commit hook checks staged changes for whitespace errors and conflict markers, then runs Rust formatting and Markdown lint across the workspace. It does not run Clippy or tests. Formatting and Markdown lint inspect the working tree, including unstaged changes, and do not modify files.
# Fast lint (also used by the pre-commit hook)
.ci/lint.sh --quick
# Focused package tests
cargo nextest run -p tribute
cargo nextest run -p tribute-passes
# Full local validation: formatting, Clippy, Markdown lint, then all tests
.ci/check.sh
# Review snapshot changes when a snapshot test fails
cargo insta reviewRun relevant regression and package tests while developing. Use .ci/check.sh
for full local validation, especially for changes spanning compiler stages.
Codex and Claude stop hooks continue to run .ci/lint.sh: formatting, Clippy,
and Markdown lint, without tests. CI retains full tests, strict Clippy,
coverage, and platform checks; require successful CI before merging.
The new-plans/ directory contains the authoritative language and compiler
design. new-plans/capabilities.md separately
records what the current implementation has demonstrated; design intent alone
is not a support claim.
Tribute started as a testbed for practicing language implementation before building a "real" language. It originally had a Lisp-like S-expression syntax with a simple interpreter. The name comes from the Tenacious D song — this isn't the greatest language in the world, it's just a tribute to one.