Python-syntax AffineScript. Write code that looks like Python, get affine resource guarantees and typed-wasm output.
RattleScript is AffineScript with its rattle face pre-selected. If you write Python, you already know most of the syntax. The compiler checks that your resources (files, sockets, tokens, handles) are used exactly as many times as you declare — and proves it at compile time. No null pointer exceptions. No use-after-free. No silent data races. No GC overhead.
This repo is a brand surface only. The compiler, type checker, borrow checker, and codegen all live in affinescript. This repo carries:
-
Examples idiomatic to Python developers
-
Documentation aimed at the Python community
-
A
rattleshim CLI that aliasesaffinescript --face rattle -
Tutorial and migration guides for moving Python code into a strongly-typed, affine-typed, WASM-targeting world
examples/hello.affine:
# face: rattlescript
effect IO:
fn println(s: String) -> ();
def main() -{IO}-> ():
let greeting = "Hello, RattleScript!"
println(greeting)Same logical program, written in Python style. Compiles to the same canonical AST and the same typed-wasm output as every other face.
opam install affinescript
git clone https://github.com/hyperpolymath/rattlescript
cd rattlescriptThe affinescript binary does the work. The bin/rattle shim in this repo just defaults the --face flag.
# Direct, via affinescript:
affinescript eval --face rattle examples/hello.affine
affinescript compile --face rattle examples/hello.affine -o hello.wasm
# Or via the rattle shim (same thing):
./bin/rattle eval examples/hello.affine
./bin/rattle compile examples/hello.affine -o hello.wasm
# Or via the justfile:
just run examples/hello.affine
just preview examples/hello.affine # show the canonical loweringSource files use the canonical .affine extension. The face is selected by the # face: rattlescript pragma on the first comment line, or by the --face rattle flag.
RattleScript is one of six established faces over the AffineScript core:
-
AffineScript — the canonical face
-
RattleScript — Python-style (this repo)
-
JaffaScript — JavaScript / TypeScript-style
-
LucidScript — PureScript / Haskell-style
-
CafeScripto — CoffeeScript-style
-
PseudoScript — pseudocode-style
All six share the canonical .affine extension and lower to the same AST. Errors are reported in face-appropriate vocabulary.
Python is the most popular programming language and has the largest scientific / data / web community on Earth. It also has well-documented limits: dynamic typing, packaging hell, the GIL, performance ceiling for browser deployment, no ownership semantics. RattleScript is a Python-shaped on-ramp to a language that fixes those limits without making you learn an alien syntax first.
For a Python developer, the migration path looks like:
-
Rename your
.pyfiles to.affineand add# face: rattlescriptat the top. -
Type-annotate your function signatures (Python’s optional type hints become required, but you can usually copy them over).
-
Add
letto bare variable assignments. -
Replace
import a.bwith explicit imports. -
Compile to typed-wasm, ship to browsers / WASI runtimes / native via the same build.
Alpha. The face transformer is implemented in affinescript/lib/python_face.ml. Known limitations are tracked in the affinescript faces README under "Known transformer gaps".