# The Loup Books

**Loup** — the *Language of Unusual Portability | Power* — is one strongly typed language for quick scripts, programs compiled to native code or WebAssembly, and bare-metal firmware. The language is the same everywhere; what changes from one environment to the next is the **mode** a file declares, which decides the features it may use, how it is compiled, and how it starts.

There are four books, one for each family of modes. Each is self-contained, practical and example-first. This edition describes **Loup 1.25.1**: every runnable example was checked with that toolchain, and features the specification describes but the toolchain does not implement yet are marked **⚠ Planned**.

The books are also published at <https://code-craft.ai/references/loup>, where every page is available as Markdown by adding `.md` to its address.

## The four books

| Book | Modes (`@mode(...)`) | Files | Build and run | Status in 1.25.1 |
|---|---|---|---|---|
| [**The Loup Scripting Book**](loup-scripting/README.md) | `host.scripted` | `.lpscr` | `loup run tool.lpscr` | Works on Linux, macOS and Windows |
| [**The Loup Native Book**](loup-native/README.md) | `host.native`, `host.dual` | `.lphc`, `.loup` | `loup build --target native` | Native builds on Linux x86-64; macOS is a preview; `loup run` everywhere |
| [**The Loup Web Book**](loup-web/README.md) | `web.compiled`, `web.scripted` | `.lpweb` | `loup-bootstrap build --target browser` | The language works; the browser runtime is ⚠ planned |
| [**The Loup Freestanding Book**](loup-freestanding/README.md) | `freestanding` | `.lpfree` | `loup build --target freestanding --arch …` | Builds on Linux with `ld.lld`; QEMU-verified on x86_64, aarch64, riscv64, armv7 and Cortex-M |

Every source file declares its mode on its first line (ruling MODE-2), and the file extension follows the mode (ruling MODE-3):

```loup
@mode(host.scripted)

let name = "world"
println(i"hello, {$ name $}")
```

The v1.16 names `@mode(scripted)`, `@mode(compiled)` and `@mode(native)` were retired in v1.17. The compiler does not reject them — it quietly treats the file as a script — so if a program's `main()` never seems to run, check the mode line first.

## Which book should you read?

Start with the book that matches what you are building. If you are new to Loup, start with **[The Loup Scripting Book](loup-scripting/README.md)**: scripts need no project and no build step, so you can try every language feature with `loup run`. Its later chapters show when to turn a script into a `host.dual` program with a `main()`, which is where the Native Book picks up.

The books cross-reference each other where a concept differs between modes.

## How the modes differ

| Feature | Scripting | Native and dual | Web | Freestanding |
|---|---|---|---|---|
| Memory model | ARC semantics | ARC | ARC semantics | No runtime: compile-time ownership only |
| Ownership verbs (`reads` / `edits` / `takes` / `shares`) | ✓ | ✓ | ✓ | ✓ |
| `modifier` methods and `safe { }` | ✓ | ✓ | ✓ | ✓ |
| `unique let` | ✓ | ✓ | ✓ | ✓ |
| `unique class` | ✗ | `host.native` only | ✗ | ✓ |
| `throw` / `try` / `catch` | ✓ | ✓ | ✓ | ✗ — `attempt` with `catch Err(e)` |
| Growable collections (`list`, `dict`) | ✓ | ✓ | ✓ | ✗ — fixed `buffer[T, N]` |
| `async` / `await` | ✓ (runs eagerly)¹ | Interpreter only; native builds refuse it | ✓ on Wasm | ✗ |
| Template fences (`html`, `css`, `sql`) | ✓ | Interpreter only; not in native builds | ✓ | ✗ |
| `asm { }` | ✗ | `host.native` only | ✗ | ✓ |
| `@entry`, `@interrupt`, `@naked`, `Volatile[T]` | ✗ | ✗ | ✗ | ✓ |
| `arc let`, reactive UI, DOM, `core.reflect` | ⚠ Planned | ⚠ Planned | ⚠ Planned | ✗ |

¹ The interpreter runs an `async func` to completion when it is called; a real scheduler is planned.

**Memory safety.** Every mode presents ARC semantics: classes are reference-counted, and structs, enums, tuples and collections are copied. There is no garbage collector in any mode. The ownership verbs say what a function may do with each argument, and the compiler checks them in every mode. Freestanding has no runtime at all, so it relies entirely on these compile-time checks.

## Reading the examples

The books teach the way *The Rust Programming Language* does: they show working code, then the mistake you would naturally make, the toolchain's actual message, and the fix. Problem code is always labelled:

| Label on the website | Fence in the Markdown | Meaning |
|---|---|---|
| *This code does not compile* | ```` ```loup,does_not_compile ```` | The compiler rejects it; the block after it shows the diagnostic |
| *This code throws at run time* | ```` ```loup,throws ```` | It compiles, then stops with an uncaught exception |
| *This code panics* | ```` ```loup,panics ```` | It compiles, then panics |
| *This code does not do what it should* | ```` ```loup,not_desired_behavior ```` | It runs, with a bug the text explains |
| *Fragment — not a complete program* | ```` ```loup,ignore ```` | A sketch, or a ⚠ Planned feature |

Unlabelled ```` ```loup ```` listings compile and run. Some listings need a line of setup that would distract from the point — an import, a `main()` wrapper. Those lines start with `#~` in the Markdown, are hidden on the website, and are still compiled when the examples are checked. Since `#` starts a comment in Loup, a `#~` line is harmless if you copy it.

Diagnostics are shown the way `loup run` prints them:

```text
main.lpscr:3:4: error[E0001]: E_CONDITION_PARENS: the condition of `if` must be in parentheses; add them: `if (...) {`
```

## Installing Loup

Official builds are published for Linux (x86-64, arm64), macOS (Apple silicon, Intel) and Windows (x86-64).

```sh
# Linux and macOS
curl -fsSL https://github.com/code-craft-ai-company/loup-releases/releases/latest/download/loup-install.sh | sh
```

```powershell
# Windows (PowerShell)
irm https://github.com/code-craft-ai-company/loup-releases/releases/latest/download/loup-install.ps1 | iex
```

The installer puts the toolchain in `~/.loup` (or `%LOCALAPPDATA%\Programs\Loup`) and adds its `bin` directory to your `PATH`; no administrator rights are needed. To install a particular version, pass `--version 1.25.1` (`sh -s -- --version 1.25.1`) or set `LOUP_VERSION`.

On Linux x86-64, `loup` is the self-hosted toolchain. On macOS, Windows and Linux arm64, `loup` is the bootstrap compiler, `loup-bootstrap`; the two accept the same commands for everything in these books, and the books note the few differences.

## Running the examples

```sh
loup run hello.lpscr                      # run a script — no project, no build step
loup-bootstrap init demo                  # create a project: demo/demo.lppkg, demo/src/main.loup
loup-bootstrap check                      # type-check the project in the current directory
loup build --target native -o app         # native binary (Linux x86-64; macOS preview)
loup-bootstrap build --target browser     # WebAssembly for the browser (bare .wasm today)
loup build --target freestanding --arch x86_64   # bare-metal image (Linux, needs ld.lld)
loup test                                 # run *_test.lpscr / *_test.loup files
```

## The language reference

The books are guides, not the specification. The normative reference is the four-volume Loup Language Reference in [`specs/`](../specs/SPEC-INDEX.md), cited in the books as `§V-N.M` — volume 1 core, 2 runtime, 3 compilation, 4 data:

- **Core** — [`loup-language-core-v1_20.md`](../specs/loup-language-core-v1_20.md): syntax, types, modes (§1-2), the feature matrix (§1-2.6), modules and packages (§1-13).
- **Runtime** — [`loup-language-runtime-v1_20.md`](../specs/loup-language-runtime-v1_20.md): concurrency, shared memory, FFI, UI.
- **Compilation** — [`loup-language-compilation-v1_20.md`](../specs/loup-language-compilation-v1_20.md): Wasm, native, ownership (§3-2.4), freestanding (§3-3), hardware back ends.
- **Data** — [`loup-language-data-v1_20.md`](../specs/loup-language-data-v1_20.md): serialization and interchange.

The volumes keep their `v1_20` file names but are amended in place as the language changes; rulings made since are cited by name (MODE-3, RESWORD-1, PANIC-1, …). The companion references are the [Standard Library Reference](../specs/loup-stdlib-reference-v1_20.md) (§21.1–§21.27), the [Packages Reference](../specs/loup-packages-reference-v1_12.md), and the [Testing Reference](../specs/loup-testing-reference-v1_10.md) (a draft that describes more than ships). What actually ships in the standard library is tracked in [`docs/stdlib-status.md`](../docs/stdlib-status.md).

When a book and the reference disagree about the design, the reference wins. When a book shows code, that code was checked against the toolchain.

## Checking the examples

`tools/verify-listings.py` checks every Loup listing in the books against its label: plain listings must compile and run, `does_not_compile` listings must be rejected, and `throws` listings must fail at run time. Run it after editing a chapter:

```sh
cd loup-books
python3 tools/verify-listings.py --loup "$(command -v loup)" --only-failures loup-scripting/*.md
```

Each listing runs under its own `@mode(...)`: hosted and web listings with `loup run`, freestanding listings with `loup check` in a throwaway project.
