The Loup Native Book
Writing Loup programs that compile to native executables. This edition describes Loup 1.25.1.
What this book covers
Native Loup is Loup compiled ahead of time to a platform executable: an ELF binary on Linux, a Mach-O binary on macOS. The program carries its runtime with it (reference counting, strings, collections, exceptions), so nothing else needs to be installed on the machine that runs it. Memory is managed by automatic reference counting rather than a garbage collector, and an ownership system checked at compile time (reads, edits, takes and shares parameters, modifier methods, safe blocks, unique values) says who may change what.
The book is for people writing command-line tools, services and systems code who want a statically typed language with predictable memory behaviour. It assumes you can program; it does not assume you know Loup.
Every runnable example in the book was checked with the Loup 1.25.1 toolchain. Where the Language Reference specifies something the toolchain does not do yet, the book says so and marks it ⚠ Planned, and where the toolchain behaves differently from the specification, the text states the actual behaviour.
The two native modes
Every Loup file declares its mode on its first line. This book uses two:
@mode(host.native)
func main(): void {
println("hello, native world");
}
@mode(host.native), in.lphcfiles, is for code whose deliverable is a native binary. It allows the features that only make sense in machine code, such asunique classand inlineasm { }.@mode(host.dual), in.loupfiles, is for code that should also run on the interpreter (loup run) or as WebAssembly. Everyhost.dualfile is also a validhost.nativefile.
Both start at main(), which takes no parameters and returns void or int; arguments come from runtime.args(). Statements outside functions are an error (E_TOPLEVEL_CONTROL_AOT). The names @mode(native) and @mode(compiled) from earlier editions were retired in v1.17; the compiler does not reject them, but silently treats the file as a script whose main() is never called. Chapter 2 explains the modes in full.
What works in Loup 1.25.1
| Status | |
|---|---|
| Native binaries on Linux x86-64 | Supported (loup build --target native; needs clang) |
| Native binaries on macOS 11+ | Preview: LLVM backend only; needs the Xcode Command Line Tools |
| Native binaries on Windows and Linux arm64 | Not yet |
loup run of host.native and host.dual files |
Every platform (the interpreter runs the program and calls main()) |
Native builds of async, template fences, for concurrent |
Refused with E-BUILD-NATIVE; they run under loup run and in WebAssembly |
weak references in native binaries |
Accepted, but stored as strong references, so cycles leak |
native.ffi, native.simd, native.gpu, ui.desktop, sync.* |
⚠ Planned |
Installing Loup
Official builds come from the code-craft-ai-company/loup-releases GitHub releases:
# Linux and macOS
curl -fsSL https://github.com/code-craft-ai-company/loup-releases/releases/latest/download/loup-install.sh | sh
# 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. Pass --version 1.25.1 (sh -s -- --version 1.25.1) or set LOUP_VERSION to pin a version. Chapter 1 continues from there.
How to read the examples
Listings without a label compile and run; the output that follows them is what loup run printed. Listings that show a mistake are labelled, and the block after them is the toolchain's real message:
| Label | Meaning |
|---|---|
| This code does not compile | The compiler rejects it; the diagnostic follows |
| This code throws at run time | It compiles, then stops with an uncaught exception |
| This code does not do what it should | It runs, with a bug the text explains |
| Fragment | Not checked: a multi-file example run as a project, or a ⚠ planned feature |
Some listings hide setup lines (an import, a main() wrapper) on the website; in the Markdown they start with #~. Diagnostics are shown as loup run prints them, with the file named main.lphc or main.loup.
loup run executes native-mode programs on an interpreter. A few runtime behaviours differ from a native binary today, notably integer overflow (chapter 3), when finalize() runs (chapter 9), and the format of an uncaught exception (chapter 12); the chapters point these out.
Reading order
Chapters 1 to 8 cover the setup and the core language: modes, numbers, functions, control flow, collections, structs and enums. Chapter 9 introduces classes and reference counting, and chapters 10 to 14 cover interfaces, generics, errors, modules and template fences. Chapters 15 to 18 are the ownership chapters and build on each other: read them in order. Chapters 19 to 25 cover interop, concurrency, the planned UI and SIMD/GPU support, building and distribution, and a summary of memory-safety patterns.
If you already know Loup scripts, skim chapters 1 to 8 (chapter 3 on overflow is worth reading), then read from chapter 9 on.
Contents
- Getting started
- Native mode overview
- Variables and numerics
- Functions
- Control flow
- Collections
- Structs
- Enums and pattern matching
- Classes and ARC
- Interfaces
- Generics
- Error handling
- Modules and packages
- Template fences
- Ownership verbs
borrowandnoescapeuniqueownership- Lifetimes and regions
@unsafeand FFI- Concurrency and OS threads
- Async on native (⚠ planned for native builds; runs under
loup runand in WebAssembly) - Desktop UI (⚠ planned: design preview)
- SIMD and GPU (⚠ planned: design preview)
- Building and distributing
- Memory safety patterns
The language reference
This book is a guide, not the specification. The normative reference is the four-volume Loup Language Reference in the repository's specs/ directory, cited here as "Language Reference §V-N.M": volume 1 is the core language (for example §1-2.4 on modes), 2 the runtime (§2-1 concurrency), 3 compilation (§3-2 native compilation and ownership), 4 data formats. Rulings made since the volumes were last revised are cited by name, such as ruling MODE-3. When this book and the reference disagree about the design, the reference wins; when the book shows code, that code was checked against the toolchain.
Companion books
- The Loup Scripting Book covers
host.scriptedscripts: nomain(), no build step, the quickest way to learn the language. - The Loup Web Book covers
web.scriptedandweb.compiledcode for the browser. - The Loup Freestanding Book covers
freestandingcode for kernels and firmware: the same ownership keywords, no runtime, no exceptions, no growable collections.