Python-syntax AffineScript. Write code that looks like Python. Get affine resource guarantees, algebraic effects, and typed WASM out.
RattleScript is AffineScript with its Python face pre-selected. If you write Python, you already know most of the syntax. The compiler checks that your resources (files, sockets, tokens) are used exactly as many times as you say — and proves it at compile time.
def greet(name: String) -> String:
"Hello, " + name + "!"
def main() -> ():
let msg = greet("world")
IO.println(msg)That’s a valid .rattle file. Run it:
rattle eval hello.rattleBecause Python programmers deserve a sound type system. RattleScript is Python’s more dangerous cousin — same comfortable whitespace- delimited blocks, but with teeth: no null pointer exceptions, no use-after-free, no data races, and no runtime surprises that the type checker already knows about.
The mascot is a rattlesnake. Python’s more dangerous cousin.
| Python surface | AffineScript equivalent |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
See rattle preview-python-transform <file> to inspect the full transform
for any file.
# From nextgen-languages/affinescript root — build affinescript first:
dune build
# Then build the rattle wrapper:
cd distributions/rattlescript
just build
# Binary at: target/debug/rattleThe standalone hyperpolymath/rattlescript repo contains a pre-configured distribution with affinescript as a git submodule. Use that for a self-contained checkout.
# Type-check a file
rattle check hello.rattle
# Evaluate
rattle eval hello.rattle
# Compile to WASM
rattle compile hello.rattle
# See the canonical AffineScript generated by the preprocessor
rattle preview-python-transform hello.rattle
# All affinescript subcommands work — --face python is pre-injected
rattle lint hello.rattle
rattle fmt hello.rattleRattleScript is AffineScript — same compiler, same type system, same WASM
output. The only difference is --face python is the default.
The Python face lives in
lib/python_face.ml and the error vocabulary
in lib/face.ml. No compiler internals change when
the face changes.
This directory (distributions/rattlescript/) lives inside the affinescript
monorepo. The standalone rattlescript
GitHub repo uses affinescript as a git submodule and contains only:
-
This
distributions/rattlescript/content (copied at release time) -
Branding assets
-
CI workflows
just update-affinescript advances the submodule pointer after each
affinescript release. All language changes, face changes, and bug fixes
come through that single submodule bump — no duplication.