Nitpick Module & FFI System Specification

This specification documents the current behavior, syntax, and semantics of the Nitpick module system, visibility rules, function declarations, and the C Foreign Function Interface (FFI). It addresses historical syntax discrepancies and establishes the canonical usage for the compiler version >= 0.8.4.

1. Modules (mod)

Modules allow organization of code into hierarchical namespaces.

1.1 Defining Modules

Modules can be defined inline or exist in external files.

2. Imports (use)

The use keyword brings symbols from other modules into the current scope. Nitpick guarantees type identity across multiple paths without duplicate type definition errors (Diamond Import Behavior).

2.1 File-Based Imports (Canonical)

The canonical syntax imports directly from an .npk file path:

2.2 Logical Path Imports (Legacy/Alternative)

The legacy logical path syntax is still supported by the compiler:

use std.math.*;
use std.collections.{HashMap, HashSet};

2.3 Search Paths & Transitivity

3. Visibility (pub)

Nitpick uses a strict binary visibility model: Public or Private.

4. Functions (func / func:)

4.1 Syntax

4.2 Calling Nitpick Functions

All native user-defined functions return a Result<T> wrapper (the only exception is extern functions). * Safe Unwrap: int32:res = add(1, 2) ? 0; * Raw Unwrap: int32:res = raw add(1, 2); (Asserts success) * Drop: drop side_effect_fn(); (Discards the Result)

5. Foreign Function Interface (extern)

extern blocks are used for C FFI bindings. Crucially, extern functions return bare values, not Result<T>.

5.1 Extern Syntax

5.2 ABI & Pointers

5.3 Calling Extern Functions

Because they do not return Result<T>, you do not use raw.

int32:n = printf("Hello\0"); // Direct assignment