Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Quick start

This walks you through your first xpile transpile.

Prerequisite

cargo install xpile

See Installation for alternatives.

1. A Python file

Save the following as factorial.py:

def factorial(n: int) -> int:
    return 1 if n <= 1 else n * factorial(n - 1)

2. Transpile to Rust

$ xpile transpile factorial.py
// xpile-generated from Python module factorial

// xpile-contract: C-PY-INT-ARITH
pub fn factorial(n: i64) -> i64 {
    if (n <= 1i64) { 1i64 } else {
        (n).checked_mul(factorial(
            (n).checked_sub(1i64).expect("xpile: i64 subtraction overflow; bigint promotion (contract C-PY-INT-ARITH slow path) not yet implemented")
        )).expect("xpile: i64 multiplication overflow; bigint promotion (contract C-PY-INT-ARITH slow path) not yet implemented")
    }
}

Note the // xpile-contract: C-PY-INT-ARITH citation and the .checked_*().expect(...) wrappers. Every arithmetic operation preserves the C-PY-INT-ARITH contract: i64 overflow panics with a pointer to the unimplemented bigint slow path, rather than silently wrapping the way native i64 arithmetic would.

You can compile and run the output directly:

$ xpile transpile factorial.py --out factorial.rs
$ rustc -O factorial.rs --crate-type lib --emit=metadata -o /dev/null
$ # CI uses this exact path: rustc -O + assert_eq!(factorial(10), 3628800)

3. Same source, different backends

$ xpile transpile factorial.py --target ruchy
fun factorial(n: i64) -> i64 {
    if (n <= 1i64) { 1i64 } else {
        (n).checked_mul(factorial((n).checked_sub(1i64).expect("..."))).expect("...")
    }
}

$ xpile transpile factorial.py --target lean
def factorial (n : Int) : Int :=
  if (n <= (1: Int)) then (1: Int) else (n * (factorial (n - (1: Int))))

Three different targets, the same governing contract. Lean’s Int is unbounded, so C-PY-INT-ARITH is satisfied by construction — no overflow checks emitted, because there is no overflow.

4. Inspect the substrate

$ xpile info
$ xpile diamond     # if you're in a repo with contracts/
$ xpile quorum      # if you're in a repo with contracts/

See the CLI reference for everything xpile can do.

5. Runnable examples (library API)

The repository ships six runnable examples under crates/xpile/examples/ that use the library API instead of the CLI:

$ git clone https://github.com/paiml/xpile && cd xpile
$ cargo run --example 01_python_to_rust   -p xpile  # factorial → Rust
$ cargo run --example 02_python_to_lean   -p xpile  # factorial → Lean
$ cargo run --example 03_python_to_ruchy  -p xpile  # gcd → Ruchy (Python-floor `%`)
$ cargo run --example 04_shell_roundtrip  -p xpile  # POSIX shell in → POSIX shell out
$ cargo run --example 05_python_to_shell  -p xpile  # `subprocess.run([...])` → shell
$ cargo run --example 06_inspect_session  -p xpile  # what's registered?

Each one prints input + output + a “what this demonstrates” block.

Next steps