This document defines the architecture for the next evolutionary phase of ProXPL. Moving beyond the core compiler and VM, this phase focuses on making the language "batteries-included," operationally robust, and developer-friendly. The design prioritizes determinism, explicit error handling, and clean abstractions over raw feature bloat.
The ProXPL Standard Library (std) serves as the foundation for all applications. It avoids the "kitchen sink" problem by providing high-quality, essential building blocks rather than niche implementations.
The library assumes a hierarchical module system rooted at std.
lib/
└── std/
├── core/ # Built-in types, basic memory, primitives
│ ├── types.prox # Int, Float, Bool extensions
│ └── mem.prox # Manual memory helpers (unsafe)
├── io/ # Input/Output streams
│ ├── console.prox
│ └── stream.prox
├── fs/ # Filesystem operations
│ ├── path.prox
│ └── file.prox
├── net/ # Networking (Sockets, HTTP client)
├── math/ # Advanced math & Complex numbers
├── time/ # High-precision clocks & Date
├── sys/ # OS interactions (Env, Exit, PID)
├── collection/ # Advanced data structures (Queue, Stack, BST)
└── text/ # String manipulation, Regex, Encodings
Naming Conventions:
- Modules:
snake_case(e.g.,std.http_client) - Functions/Methods:
camelCase(e.g.,readFile,toString) - Types/Classes:
PascalCase(e.g.,FileStream,TcpSocket) - Constants:
SCREAMING_SNAKE_CASE(e.g.,MAX_BUFFER_SIZE)
ProXPL uses a path-based import system with support for aliasing.
- Absolute Imports:
import std.io;resolves tolib/std/io.prox(or native equivalent). - Relative Imports:
import .utils;resolves to./utils.proxrelative to current file. - Aliasing:
import std.collection as coll; - Selective Import:
from std.math import (sin, cos, PI);
Resolution Logic:
- Is it a core module (e.g.,
std)? -> Load from internal registry/stdlib path. - Is it a local path (starts with
.)? -> Load relative to current file. - Is it a package (e.g.,
import requests)? -> Look inprox_modules/or global cache.
Essential runtime utilities. Auto-imported in most contexts.
// Assertions with clear messages
func assert(condition, message)
// Type checking
func typeOf(value) -> String
// Memory safety (Panic if null dereference happens)
func unwrap(optionalValue) -> Value
Explicit separation between stream I/O and Filesystem manipulations.
// std.fs
module std.fs {
class File {
static func open(path, mode) -> Result<File>
func readAll() -> String
func close()
}
func exists(path) -> Bool
}
// std.io
module std.io {
func print(msg) // Buffered STDOUT
func eprint(msg) // Unbuffered STDERR
func scanln() -> String
}
System-level operations.
module std.sys {
const OS_NAME: String
const ARCH: String
func exit(code)
func env(key) -> Option<String>
func args() -> List<String>
}
| Module | Implementation | Rationale |
|---|---|---|
std.core |
Intrinsic/Native | Basic types require VM-level access. |
std.math |
Native (C) | Performance critical; maps to <math.h>. |
std.io |
Native (C) | Direct syscalls needed. |
std.fs |
Native (C) | Platform specific syscalls. |
std.net |
Native (C) | Platform specific sockets. |
std.string |
Mixed | Basic ops native; formatting/templating pure. |
std.collection |
Pure ProXPL | Built on top of core arrays/maps. |
std.test |
Pure ProXPL | Test runner logic doesn't need C. |
- Zero Hidden Allocations: APIs that return new objects should be obvious. Prefer explicitly passing generic buffers for I/O.
- Result Types over Exceptions: Most I/O and System calls should return a
Result<T, E>orOption<T>equivalent to force error handling (mimicking Rust/Go patterns). - Immutable Default: Strings are immutable. Collections passed by reference but should have clear
clone()methods.
PRM is the official CLI toolchain for ProXPL, handling dependency management, building, testing, and publishing.
Every project is defined by a .pxcf manifest.
// project.pxcf
project {
name: "my-web-server"
version: "1.0.0"
author: "Jane Doe <jane@example.com>"
license: "MIT"
}
dependencies {
std: "0.1.0"
http_parser: "1.2.0"
json: "2.1.0"
}
compiler {
target: "native"
optimize: true
}| Command | Description |
|---|---|
prm init <name> |
Scaffolds a new project with project.pxcf and src/main.prox. |
prm build |
Compiles the project. Supports --dev (fast, debug info) and --release (opt, stripped). |
prm run |
Builds and runs the binary (or interprets in dev mode). |
prm test |
Discovers and runs tests in tests/ or files ending in _test.prox. |
prm add <pkg> |
Adds a dependency to project.pxcf and updates lockfile. |
prm update |
Updates dependencies within semantic versioning bounds. |
prm install |
Downloads dependencies defined in project-lock.pxcf. |
- Lockfile (
project-lock.pxcf): Pin exact versions of entire dependency tree. Checked into git. - Global Cache:
~/.prox/cache/registrystores downloaded packages to avoid re-downloading. - Structure:
~/.prox/bin/: Installed global binaries.~/.prox/registry/: Source code of packages.
To be production-ready, the runtime needs observability and robust error reporting.
ProXPL moves away from generic "Runtime Error" to structured errors.
Proposed Error Structure (C-Side):
typedef struct {
ErrorType type; // FATAL, LOGIC, IO, FORMAT
const char* message;
const char* file;
int line;
CallFrame* stackTrace; // Captured at error creation
} RuntimeError;User-Facing Panic: When a panic occurs, the VM prints:
- Error Type & Message.
- Formatted Stack Trace (File:Line Function).
- Hint (if available).
std.log: A structured logging interface.- Levels:
DEBUG,INFO,WARN,ERROR,FATAL. - Output: Defaults to stderr, but configurable to file or JSON stream.
- Levels:
- Trace Hooks: The VM will expose hooks for function entry/exit, allowing for flamegraph generation and profiling in the future.
Built-in support for unit testing without external dependencies.
import std.test;
test "addition works" {
assert(1 + 1 == 2, "Math is broken");
}
test "failure case" {
// Expect panic
test.should_panic(func() { 1 / 0 });
}
prm test runner will:
- Recursively find test files.
- Execute them in a sandbox.
- Report Pass/Fail statistics and timing.
Goal: Minimum usable Standard Library and Build System.
- Stdlib v0.1: Implement
std.core,std.io,std.fs,std.sys(Native bindings). - PRM v0.1: Basic
project.pxcfparsing andprm build(local files only). - Docs: Initial
stdlibAPI reference.
Goal: Allow sharing code.
- PRM v0.5: Git dependency support.
prm install&project-lock.pxcf. - Stdlib v0.2: Add
std.net(basic sockets) andstd.json.
Goal: Developer Experience.
- Testing: Implement
std.testandprm testharness. - LSP: Language Server Protocol basic implementation (Jump to def, simple completion).
- Debugger: Source-map support for LLVM backend debugging.
Goal: Enterprise Readiness.
- Registry: Centralized package registry (web service).
- Concurrency: Go-style coroutines or Actor model in
std.task. - Sandboxing: Wasm target or capabilities-based security.
- Formatting:
prox fmtis the single source of truth. Style is K&R braces, 4-space indent (or tab, configurable but standard is spaces). - Documentation: Markdown support in doc-comments
///.prox docgenerates HTML. - Visibility:
pub funcexplicitly exports symbols.- Default visibility is module-private.
- FFI: Simple C-interop.
foreign func MessageBoxA(hwnd, text, caption, type);
- Running
npm/pipfor packages:- Rejected: ProXPL needs deterministic, domain-specific build logic (AOT vs JIT switch). Relying on Python/Node logic introduces bloat and dependency hell.
- Classes for everything (Java style):
- Rejected:
std.coreuses functions acting on data for primitives suitable for SSA optimization. Classes reserved for complex state (Files, Sockets).
- Rejected:
- Exceptions:
- Rejected: Silent control flow makes systems programming hard. Result/Option types are explicit and force handling.