Core and Portable Libraries
Relevant source files
The following files were used as context for generating this wiki page:
- architecture/16-base-libraries.md
- architecture/22.6-standard-library-implementation-plan.md
- architecture/decisions/0030-native-public-standard-library.md
- architecture/decisions/0031-public-library-tiers-and-names.md
- architecture/decisions/0032-concise-apis-and-cost-contracts.md
- crates/libraries/README.md
- crates/tools/architecture-tests/src/tests.rs
- README.md
The foundational library model of Pop Lang consists of two reserved library Bubbles: Pop.Internal and Pop.Standard. These libraries provide the necessary primitives, portable values, and protocols required for general-purpose software development while maintaining a strict dependency direction and clear visibility boundaries. Core libraries prioritize data-first design, emphasizing functions, immutable records, and typed protocols over complex object-oriented structures.
The libraries are designed to be backend-neutral, ensuring consistent behavior across different execution strategies, including native machine code, interpreters, and future virtual machines. Pop.Standard serves as the public-facing portable foundation, while Pop.Internal acts as the trusted interface between the compiler/runtime and the language's high-level abstractions.
Sources: architecture/16-base-libraries.md:3-15, architecture/decisions/0030-native-public-standard-library.md:10-15, README.md:204-210
Foundational Architecture
The library system is structured into layers that isolate trusted runtime operations from public portable APIs.
Layered Structure
The following diagram illustrates the relationship between user applications, the standard library, internal primitives, and the runtime interface.
The layered model ensures that higher-level code only interacts with stable, portable APIs.
Sources: architecture/16-base-libraries.md:12-23
The Core Bubbles
| Bubble | Visibility | Primary Purpose |
|---|---|---|
Pop.Internal | Compiler/Runtime only | Manages intrinsics, GC/runtime bridges, and low-level primitives. |
Pop.Standard | Public | Provides portable values, protocols (e.g., Sequence), and the fixed prelude. |
Pop.Internal is never directly referenced by user code. It owns trusted mechanisms such as precise GC allocation, safe points, and PLRI adapters for system services like I/O and networking.
Sources: architecture/16-base-libraries.md:6-15, architecture/16-base-libraries.md:46-60
Pop.Standard depends on Pop.Internal, but the inverse is strictly forbidden. It is the only library automatically referenced in a standard Pop project.
Sources: architecture/16-base-libraries.md:12-15, crates/tools/architecture-tests/src/tests.rs:565-570
Design Principles and Cost Contracts
Pop Lang libraries adhere to a "data-first" philosophy, rejecting common OOP patterns such as "Manager" or "Factory" classes in favor of concise, functional APIs.
Concise APIs
Public APIs are designed to minimize ceremony. Common operations should typically require a single call (e.g., Json.decode(text, Schema)) rather than extensive builder chains or service objects.
Sources: architecture/decisions/0032-concise-apis-and-cost-contracts.md:10-15, architecture/decisions/0032-concise-apis-and-cost-contracts.md:25-35
Explicit Cost Contracts
Every public operation must document its "cost class" to ensure performance predictability. This includes:
- Allocation: Documentation must state if a function allocates or uses caller-supplied buffers.
- Complexity: Asymptotic costs (e.g., $O(n \log n)$) must be identified.
- Lifecycle: View or slice lifetimes must not outlive their owners.
- Native Transitions: batched crossings between the runtime and native code are documented to minimize transition costs.
Sources: architecture/decisions/0032-concise-apis-and-cost-contracts.md:16-23, architecture/decisions/0032-concise-apis-and-cost-contracts.md:42-55
Library Tiers and Namespaces
The library system uses a hierarchical naming convention starting with the root Pop namespace.
Naming Conventions
- PascalCase: Used for namespaces (e.g.,
Math,Json), types, and attributes. - camelCase: Used for functions and modules.
- UPPER_SNAKE_CASE: Reserved for constants.
Sources: architecture/decisions/0031-public-library-tiers-and-names.md:10-25, README.md:155-165
Distribution Tiers
Libraries are organized into tiers based on their scope and dependency requirements:
| Root | Tier | Description |
|---|---|---|
Math, Sequence, Text | Standard (Portable) | Core values available in the fixed prelude. |
Json, Yaml, Time | Formats / Locale | Portable data exchange and time handling. |
Io, File, Process | I/O and Host | System-specific operations with portable protocols. |
Pop.Data, Pop.Ai | Extensions | Separately versioned packages (not in Pop.Standard). |
Sources: architecture/22.6-standard-library-implementation-plan.md:10-40, architecture/decisions/0031-public-library-tiers-and-names.md:15-25, crates/tools/architecture-tests/src/tests.rs:35-120
Implementation and Lifecycle
The implementation of core libraries follows a phased migration plan to ensure architectural conformance before APIs are stabilized.
Implementation Phases
The project defines nine phases (0 through 8) for library delivery, starting with "Baselines" (Phase 0) and "Core Values" (Phase 1).
- Phase 0 (Baselines): Establishes the
Resulttype, documentation metadata, and the Bubble artifact format. - Phase 1 (Core Values): Implements
Math,Random,Sequence, andUnicode. - Phase 2 (Formats): Delivers
Json,Toml, andRegex. - Phase 3+: Progresses through I/O, Concurrency, Networking, and Specialist ecosystems (AI, Graphics).
Sources: architecture/22.6-standard-library-implementation-plan.md:10-45
Native Adapters
When a library function requires a native transition (e.g., calling an OS primitive), it uses a typed bridge module. These are annotated with #[poplib] to generate host ABI descriptors.
#[poplib(
bubble = Standard,
namespace = "Pop",
name = "print",
parameters(Int),
results(),
effects(AmbientIo),
)]
pub extern "C" fn pop_std_print_int(value: i64) {
// Native implementation
}
Sources: crates/libraries/README.md:105-120
Initialization Flow
The process of loading a library Bubble and executing its initializers follows a strict transactional sequence.
Conclusion
Core and Portable Libraries in Pop Lang provide a structured, high-performance foundation that enforces static typing and explicit resource management. By strictly separating trusted internal mechanisms from public portable APIs and mandating explicit cost contracts, the architecture ensures that the language remains efficient and predictable across diverse hardware and software targets.
Sources: architecture/16-base-libraries.md:3-10, architecture/decisions/0030-native-public-standard-library.md:35-45