|
| 1 | +# ProXPL Ecosystem Design Specification |
| 2 | + |
| 3 | +## 1. Executive Summary |
| 4 | + |
| 5 | +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. |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## 2. Standard Library Architecture |
| 10 | + |
| 11 | +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. |
| 12 | + |
| 13 | +### 2.1 Directory Structure & Naming |
| 14 | + |
| 15 | +The library assumes a hierarchical module system rooted at `std`. |
| 16 | + |
| 17 | +```text |
| 18 | +lib/ |
| 19 | +└── std/ |
| 20 | + ├── core/ # Built-in types, basic memory, primitives |
| 21 | + │ ├── types.prox # Int, Float, Bool extensions |
| 22 | + │ └── mem.prox # Manual memory helpers (unsafe) |
| 23 | + ├── io/ # Input/Output streams |
| 24 | + │ ├── console.prox |
| 25 | + │ └── stream.prox |
| 26 | + ├── fs/ # Filesystem operations |
| 27 | + │ ├── path.prox |
| 28 | + │ └── file.prox |
| 29 | + ├── net/ # Networking (Sockets, HTTP client) |
| 30 | + ├── math/ # Advanced math & Complex numbers |
| 31 | + ├── time/ # High-precision clocks & Date |
| 32 | + ├── sys/ # OS interactions (Env, Exit, PID) |
| 33 | + ├── collection/ # Advanced data structures (Queue, Stack, BST) |
| 34 | + └── text/ # String manipulation, Regex, Encodings |
| 35 | +``` |
| 36 | + |
| 37 | +**Naming Conventions:** |
| 38 | +- **Modules**: `snake_case` (e.g., `std.http_client`) |
| 39 | +- **Functions/Methods**: `camelCase` (e.g., `readFile`, `toString`) |
| 40 | +- **Types/Classes**: `PascalCase` (e.g., `FileStream`, `TcpSocket`) |
| 41 | +- **Constants**: `SCREAMING_SNAKE_CASE` (e.g., `MAX_BUFFER_SIZE`) |
| 42 | + |
| 43 | +### 2.2 Import System Semantics |
| 44 | + |
| 45 | +ProXPL uses a path-based import system with support for aliasing. |
| 46 | + |
| 47 | +- **Absolute Imports**: `import std.io;` resolves to `lib/std/io.prox` (or native equivalent). |
| 48 | +- **Relative Imports**: `import .utils;` resolves to `./utils.prox` relative to current file. |
| 49 | +- **Aliasing**: `import std.collection as coll;` |
| 50 | +- **Selective Import**: `from std.math import (sin, cos, PI);` |
| 51 | + |
| 52 | +**Resolution Logic**: |
| 53 | +1. Is it a core module (e.g., `std`)? -> Load from internal registry/stdlib path. |
| 54 | +2. Is it a local path (starts with `.`)? -> Load relative to current file. |
| 55 | +3. Is it a package (e.g., `import requests`)? -> Look in `prox_modules/` or global cache. |
| 56 | + |
| 57 | +### 2.3 Core Modules & APIs |
| 58 | + |
| 59 | +#### `std.core` |
| 60 | +Essential runtime utilities. Auto-imported in most contexts. |
| 61 | +```prox |
| 62 | +// Assertions with clear messages |
| 63 | +func assert(condition, message) |
| 64 | +
|
| 65 | +// Type checking |
| 66 | +func typeOf(value) -> String |
| 67 | +
|
| 68 | +// Memory safety (Panic if null dereference happens) |
| 69 | +func unwrap(optionalValue) -> Value |
| 70 | +``` |
| 71 | + |
| 72 | +#### `std.io` & `std.fs` |
| 73 | +Explicit separation between stream I/O and Filesystem manipulations. |
| 74 | +```prox |
| 75 | +// std.fs |
| 76 | +module std.fs { |
| 77 | + class File { |
| 78 | + static func open(path, mode) -> Result<File> |
| 79 | + func readAll() -> String |
| 80 | + func close() |
| 81 | + } |
| 82 | + |
| 83 | + func exists(path) -> Bool |
| 84 | +} |
| 85 | +
|
| 86 | +// std.io |
| 87 | +module std.io { |
| 88 | + func print(msg) // Buffered STDOUT |
| 89 | + func eprint(msg) // Unbuffered STDERR |
| 90 | + func scanln() -> String |
| 91 | +} |
| 92 | +``` |
| 93 | + |
| 94 | +#### `std.sys` |
| 95 | +System-level operations. |
| 96 | +```prox |
| 97 | +module std.sys { |
| 98 | + const OS_NAME: String |
| 99 | + const ARCH: String |
| 100 | + |
| 101 | + func exit(code) |
| 102 | + func env(key) -> Option<String> |
| 103 | + func args() -> List<String> |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +### 2.4 Native vs Pure Implementation Split |
| 108 | + |
| 109 | +| Module | Implementation | Rationale | |
| 110 | +| :--- | :--- | :--- | |
| 111 | +| `std.core` | **Intrinsic/Native** | Basic types require VM-level access. | |
| 112 | +| `std.math` | **Native (C)** | Performance critical; maps to `<math.h>`. | |
| 113 | +| `std.io` | **Native (C)** | Direct syscalls needed. | |
| 114 | +| `std.fs` | **Native (C)** | Platform specific syscalls. | |
| 115 | +| `std.net` | **Native (C)** | Platform specific sockets. | |
| 116 | +| `std.string` | **Mixed** | Basic ops native; formatting/templating pure. | |
| 117 | +| `std.collection` | **Pure ProXPL** | Built on top of core arrays/maps. | |
| 118 | +| `std.test` | **Pure ProXPL** | Test runner logic doesn't need C. | |
| 119 | + |
| 120 | +### 2.5 Design Principles |
| 121 | +1. **Zero Hidden Allocations**: APIs that return new objects should be obvious. Prefer explicitly passing generic buffers for I/O. |
| 122 | +2. **Result Types over Exceptions**: Most I/O and System calls should return a `Result<T, E>` or `Option<T>` equivalent to force error handling (mimicking Rust/Go patterns). |
| 123 | +3. **Immutable Default**: Strings are immutable. Collections passed by reference but should have clear `clone()` methods. |
| 124 | + |
| 125 | +--- |
| 126 | + |
| 127 | +## 3. ProX Resource Manager (PRM) |
| 128 | + |
| 129 | +PRM is the official CLI toolchain for ProXPL, handling dependency management, building, testing, and publishing. |
| 130 | + |
| 131 | +### 3.1 Package Format (`prox.toml`) |
| 132 | +Every project is defined by a TOML manifest. |
| 133 | + |
| 134 | +```toml |
| 135 | +[package] |
| 136 | +name = "my-web-server" |
| 137 | +version = "1.0.0" |
| 138 | +authors = ["Jane Doe <jane@example.com>"] |
| 139 | +edition = "2025" |
| 140 | +description = "A fast web server for ProXPL" |
| 141 | +license = "MIT" |
| 142 | + |
| 143 | +[dependencies] |
| 144 | +std = "0.1.0" # Core stdlib is versioned too! |
| 145 | +http_parser = { git = "https://github.com/...", tag = "v1.2" } |
| 146 | +json = "2.1.0" |
| 147 | + |
| 148 | +[build] |
| 149 | +target = "native" # or "bytecode" |
| 150 | +optimize = true |
| 151 | +``` |
| 152 | + |
| 153 | +### 3.2 Command Suite |
| 154 | + |
| 155 | +| Command | Description | |
| 156 | +| :--- | :--- | |
| 157 | +| `prm init <name>` | Scaffolds a new project with `prox.toml` and `src/main.prox`. | |
| 158 | +| `prm build` | Compiles the project. Supports `--dev` (fast, debug info) and `--release` (opt, stripped). | |
| 159 | +| `prm run` | Builds and runs the binary (or interprets in dev mode). | |
| 160 | +| `prm test` | Discovers and runs tests in `tests/` or files ending in `_test.prox`. | |
| 161 | +| `prm add <pkg>` | Adds a dependency to `prox.toml` and updates lockfile. | |
| 162 | +| `prm update` | Updates dependencies within semantic versioning bounds. | |
| 163 | +| `prm install` | Downloads dependencies defined in `prox.lock`. | |
| 164 | + |
| 165 | +### 3.3 Dependency Resolution & Cache |
| 166 | +- **Lockfile (`prox.lock`)**: Pin exact versions of entire dependency tree. Checked into git. |
| 167 | +- **Global Cache**: `~/.prox/cache/registry` stores downloaded packages to avoid re-downloading. |
| 168 | +- **Structure**: |
| 169 | + - `~/.prox/bin/`: Installed global binaries. |
| 170 | + - `~/.prox/registry/`: Source code of packages. |
| 171 | + |
| 172 | +--- |
| 173 | + |
| 174 | +## 4. Runtime Services & Tooling |
| 175 | + |
| 176 | +To be production-ready, the runtime needs observability and robust error reporting. |
| 177 | + |
| 178 | +### 4.1 Error System |
| 179 | +ProXPL moves away from generic "Runtime Error" to structured errors. |
| 180 | + |
| 181 | +**Proposed Error Structure (C-Side):** |
| 182 | +```c |
| 183 | +typedef struct { |
| 184 | + ErrorType type; // FATAL, LOGIC, IO, FORMAT |
| 185 | + const char* message; |
| 186 | + const char* file; |
| 187 | + int line; |
| 188 | + CallFrame* stackTrace; // Captured at error creation |
| 189 | +} RuntimeError; |
| 190 | +``` |
| 191 | +**User-Facing Panic:** |
| 192 | +When a panic occurs, the VM prints: |
| 193 | +1. Error Type & Message. |
| 194 | +2. Formatted Stack Trace (File:Line Function). |
| 195 | +3. Hint (if available). |
| 196 | + |
| 197 | +### 4.2 Logging & Diagnostics |
| 198 | +- **`std.log`**: A structured logging interface. |
| 199 | + - Levels: `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL`. |
| 200 | + - Output: Defaults to stderr, but configurable to file or JSON stream. |
| 201 | +- **Trace Hooks**: The VM will expose hooks for function entry/exit, allowing for flamegraph generation and profiling in the future. |
| 202 | + |
| 203 | +### 4.3 Testing Framework (`std.test`) |
| 204 | +Built-in support for unit testing without external dependencies. |
| 205 | +```prox |
| 206 | +import std.test; |
| 207 | +
|
| 208 | +test "addition works" { |
| 209 | + assert(1 + 1 == 2, "Math is broken"); |
| 210 | +} |
| 211 | +
|
| 212 | +test "failure case" { |
| 213 | + // Expect panic |
| 214 | + test.should_panic(func() { 1 / 0 }); |
| 215 | +} |
| 216 | +``` |
| 217 | +**`prm test`** runner will: |
| 218 | +1. Recursively find test files. |
| 219 | +2. Execute them in a sandbox. |
| 220 | +3. Report Pass/Fail statistics and timing. |
| 221 | + |
| 222 | +--- |
| 223 | + |
| 224 | +## 5. Ecosystem Roadmap |
| 225 | + |
| 226 | +### Phase 1: Foundation (Weeks 1-4) |
| 227 | +*Goal: Minimum usable Standard Library and Build System.* |
| 228 | +- [ ] **Stdlib v0.1**: Implement `std.core`, `std.io`, `std.fs`, `std.sys` (Native bindings). |
| 229 | +- [ ] **PRM v0.1**: Basic `prox.toml` parsing and `prm build` (local files only). |
| 230 | +- [ ] **Docs**: Initial `stdlib` API reference. |
| 231 | + |
| 232 | +### Phase 2: Package Management (Weeks 5-8) |
| 233 | +*Goal: Allow sharing code.* |
| 234 | +- [ ] **PRM v0.5**: Git dependency support. `prm install` & `prox.lock`. |
| 235 | +- [ ] **Stdlib v0.2**: Add `std.net` (basic sockets) and `std.json`. |
| 236 | + |
| 237 | +### Phase 3: Tooling & Stability (Weeks 9-12) |
| 238 | +*Goal: Developer Experience.* |
| 239 | +- [ ] **Testing**: Implement `std.test` and `prm test` harness. |
| 240 | +- [ ] **LSP**: Language Server Protocol basic implementation (Jump to def, simple completion). |
| 241 | +- [ ] **Debugger**: Source-map support for LLVM backend debugging. |
| 242 | + |
| 243 | +### Phase 4: Expansion (4 Months+) |
| 244 | +*Goal: Enterprise Readiness.* |
| 245 | +- [ ] **Registry**: Centralized package registry (web service). |
| 246 | +- [ ] **Concurrency**: Go-style coroutines or Actor model in `std.task`. |
| 247 | +- [ ] **Sandboxing**: Wasm target or capabilities-based security. |
| 248 | + |
| 249 | +--- |
| 250 | + |
| 251 | +## 6. Language Ergonomics (Developer Experience) |
| 252 | + |
| 253 | +- **Formatting**: `prox fmt` is the single source of truth. Style is K&R braces, 4-space indent (or tab, configurable but standard is spaces). |
| 254 | +- **Documentation**: Markdown support in doc-comments `///`. `prox doc` generates HTML. |
| 255 | +- **Visibility**: |
| 256 | + - `pub func` explicitly exports symbols. |
| 257 | + - Default visibility is module-private. |
| 258 | +- **FFI**: Simple C-interop. |
| 259 | + ```prox |
| 260 | + foreign func MessageBoxA(hwnd, text, caption, type); |
| 261 | + ``` |
| 262 | +
|
| 263 | +--- |
| 264 | +
|
| 265 | +## 7. Trade-offs & Rejected Alternatives |
| 266 | +
|
| 267 | +1. **Running `npm` / `pip` for packages**: |
| 268 | + - *Rejected*: ProXPL needs deterministic, domain-specific build logic (AOT vs JIT switch). Relying on Python/Node logic introduces bloat and dependency hell. |
| 269 | +2. **Classes for everything (Java style)**: |
| 270 | + - *Rejected*: `std.core` uses functions acting on data for primitives suitable for SSA optimization. Classes reserved for complex state (Files, Sockets). |
| 271 | +3. **Exceptions**: |
| 272 | + - *Rejected*: Silent control flow makes systems programming hard. Result/Option types are explicit and force handling. |
0 commit comments