Skip to content

Latest commit

 

History

History
179 lines (135 loc) · 6.2 KB

File metadata and controls

179 lines (135 loc) · 6.2 KB

Getting Started with Capa

A 5-minute guide to writing your first Capa program.

1. Prerequisites

You need either a Python 3.10+ install or one of the pre-built binaries. Pick one of the three paths:

Path 1, pre-built binary (no Python required)

Download capa-linux-x86_64, capa-macos-arm64, or capa-windows-x86_64.exe from the latest release and put it on your PATH. The binary bundles Python and the runtime; nothing else to install. After that, capa <args> works from any directory.

Path 2, install the source package

Clone the repository, then from the project root:

pip install -e .

This puts a capa command on your PATH and registers the package with the Python import system, so both capa <args> and python -m capa <args> work from any directory.

Path 3, run in place (no install)

You can also run python -m capa <args> directly, but only while your current directory is the repository root. Python resolves capa by walking the cwd-relative capa/ folder. From any other directory you get No module named capa. Use Path 1 or Path 2 if you want to scaffold projects on your Desktop, in ~/code/, etc.

The examples below assume capa is on your PATH (Path 1 or Path 2). Substitute python -m capa if you went with Path 3 and are running them from the repo root.

2. Verify it works

From the project root:

capa --run examples/hello.capa

Expected output: Hello, world!

3. Two ways to start

Path A, scaffold a project

The fastest way to get a working starter:

capa init my-project
cd my-project
capa --run main.capa

capa init creates four files: main.capa (a runnable starter that uses Stdio, so the capability discipline shows up on line one), README.md, .gitignore, and .capa-version.

Path B, A .capa file by hand

Create my_first.capa:

fun main(stdio: Stdio)
    stdio.println("Hello!")
    let xs = [1, 2, 3, 4, 5]
    let total = xs.fold(0, fun (a: Int, x: Int) -> Int => a + x)
    stdio.println("total = ${total}")

Run it:

capa --run my_first.capa

Path C, Tutorial

For a progressive 10-chapter introduction to the language, open docs/tutorial.md.

Prefer an interactive session? capa repl starts a REPL with incremental state and readline history; .capa files remain the primary execution mode.

4. CLI

Command What it does
capa init [name] Scaffold a new project (subcommand).
capa --run file.capa Compile and execute.
capa --check file.capa Type-check only (do not run).
capa --transpile file.capa Print the generated Python code.
`capa --ir [--run --transpile] file.capa`
capa --wasm --run file.capa Compile via CIR -> WAT -> binary .wasm and execute on wasmtime with a Python host bridge. Requires wasm-tools and wasmtime on PATH. The Wasm backend has full generics and trait parity with the Python reference; the main remaining limits are a few stdlib surface gaps and a loud error if a trait is used as a Map key / Set element. See examples/wasm/.
capa --wasm --transpile file.capa Print the WAT (WebAssembly text format) the Wasm backend would compile.
capa --wasm -o X.wasm file.capa Save the assembled core module to X.wasm. Add --component to wrap it in a Component Model component (via wasm-tools component new).
capa --wit file.capa Emit the WIT spec describing the program's capability imports. Useful for inspecting what a Wasm component would request from its host.
capa --parse file.capa Print the AST (for debugging).
capa --fmt file.capa Rewrite the file in canonical Capa style (line-level).
capa --fmt-check file.capa Verify canonical style without rewriting.
capa --doc file.capa Emit a self-contained HTML doc page from /// and /** */ doc comments.
capa --manifest file.capa Emit a JSON capability manifest.
capa --cyclonedx file.capa Emit a CycloneDX 1.5 SBOM with the manifest embedded.
capa lsp Start the language server on stdio (requires pip install -e '.[lsp]').
--no-color Disable ANSI colors in the output.
--stdin Read from stdin instead of a file.

Every command above also works as python -m capa <args> if the capa shim is not on your PATH.

5. Minimum program structure

fun main(stdio: Stdio)
    // your code here

The stdio parameter is a capability, only functions that receive it can perform I/O. Other available capabilities: fs (filesystem), env (environment variables), clock (time), random (random numbers).

6. A recommended first "real" program

fun classify(n: Int) -> String
    return match n
        0 -> "zero"
        n if n > 0 -> "positive"
        _ -> "negative"

fun main(stdio: Stdio)
    let nums = [-3, 0, 7, -1, 42]
    for n in nums
        stdio.println("${n}: ${classify(n)}")

Output:

-3: negative
0: zero
7: positive
-1: negative
42: positive

7. Where to learn more

  • docs/tutorial.md, guided 10-chapter tutorial
  • docs/reference.md, full language specification
  • docs/stdlib.md, standard library reference
  • examples/, 25 real programs to inspect (hello, tasks, grades, generics, closures, io, patterns, interactive, json, python_interop, documented_demo, demo_event_stream, the *_attenuation files for each capability, the stdlib_* files for each builtin API, and a few more)

8. When something goes wrong

Symptom Likely cause
expected top-level declaration You forgot the surrounding fun main(stdio: Stdio) around your statements
capability parameter not used You declared stdio: Stdio but didn't use it, prefix with _stdio or remove it
expects Bool, got Int You wrote if 1 then ... instead of if x > 0 then ...
non-exhaustive match A match on a sum type is missing cases, add _ -> ...

Errors are reported with precise positions and explanatory messages.