DEV Community

Prog. Kanishk Raj
Prog. Kanishk Raj

Posted on

ProXPL v1.5.0: The "Type Fortress" Release

🌟 Overview

ProXPL v1.5.0 hardens the type system with Traits/Interfaces v2, Result/Option types, Type Aliases, and Const Generics. This release also delivers a Generational Garbage Collector for dramatically improved latency and the first version of the ProXPL Debugger via DAP (Debug Adapter Protocol).


âœĻ New Features

1. Traits (Interface v2)

Composable behavioral contracts with default implementations.

trait Printable {
    func toString(): string;

    // Default implementation
    func display() {
        print(this.toString());
    }
}

trait Comparable {
    func compareTo(other): int;
}

class Point : Printable, Comparable {
    let x: int;
    let y: int;

    func init(x, y) {
        this.x = x;
        this.y = y;
    }

    func toString(): string {
        return "(" + to_string(this.x) + ", " + to_string(this.y) + ")";
    }

    func compareTo(other): int {
        let thisDist = this.x * this.x + this.y * this.y;
        let otherDist = other.x * other.x + other.y * other.y;
        return thisDist - otherDist;
    }
}
Enter fullscreen mode Exit fullscreen mode

Implementation Details:

  • trait keyword for defining behavioral contracts
  • Default method implementations in traits
  • Multiple trait implementation per class
  • Trait bounds for generics: func sort<T: Comparable>(list: List<T>)
  • Compile-time vtable generation for trait dispatch
  • New AST nodes: DECL_TRAIT, IMPL_TRAIT

2. Result & Option Types

Explicit error handling without exceptions.

enum Option<T> {
    Some(T),
    None
}

enum Result<T, E> {
    Ok(T),
    Err(E)
}

func divide(a: float, b: float): Result<float, string> {
    if (b == 0) {
        return Result.Err("Division by zero");
    }
    return Result.Ok(a / b);
}

func findUser(id: int): Option<User> {
    let user = db.query("SELECT * FROM users WHERE id = ?", id);
    if (user == null) return Option.None;
    return Option.Some(user);
}

// Usage with pattern matching
match (divide(10, 0)) {
    case Result.Ok(val) => print("Result: " + to_string(val));
    case Result.Err(msg) => print("Error: " + msg);
}

// Chaining with ? operator
func processUser(id: int): Result<string, string> {
    let user = findUser(id)?;   // Early return on None/Err
    let profile = loadProfile(user)?;
    return Result.Ok(profile.name);
}
Enter fullscreen mode Exit fullscreen mode

Implementation Details:

  • Built on top of v1.3.0 Enums and Generics
  • ? operator for early error propagation
  • Standard library Option and Result types
  • Compiler enforces exhaustive handling

3. Type Aliases

Simplify complex type signatures.

type UserID = int;
type Callback = func(int, string): bool;
type Matrix<T> = List<List<T>>;
type StringMap<V> = Dict<string, V>;

func processUsers(ids: List<UserID>, callback: Callback) {
    for (let id in ids) {
        callback(id, "processing");
    }
}
Enter fullscreen mode Exit fullscreen mode

4. Generational Garbage Collector

Dramatically improved GC latency and throughput.

Architecture:
| Generation | Allocation | Collection Strategy |
|------------|------------|---------------------|
| Nursery (Gen 0) | Bump allocator (fast) | Copy collection — frequent, fast (~100ξs) |
| Young (Gen 1) | Free-list | Mark-compact — moderate frequency (~1ms) |
| Old (Gen 2) | Free-list | Mark-sweep — infrequent (~10ms) |

Key Improvements:

  • 10–50x reduction in GC pause times
  • Write barrier for inter-generational references
  • Concurrent marking for Gen 2 (background thread)
  • GC tuning API: gc.set_threshold(), gc.stats()

5. Debugger (DAP Support)

Debug ProXPL programs in VS Code.

Features:

  • Breakpoints (line, conditional, hit count)
  • Step Into / Step Over / Step Out
  • Variable inspection and watch expressions
  • Call stack display with source mapping
  • Evaluate expressions in debug console
  • Source maps for LLVM AOT binaries

Integration:

  • VS Code extension updated with debugger launch configurations
  • DAP server embedded in ProXPL runtime
  • Configuration via launch.json:
{
    "type": "proxpl",
    "request": "launch",
    "program": "${workspaceFolder}/src/main.prox",
    "stopOnEntry": false
}
Enter fullscreen mode Exit fullscreen mode

6. Const Generics

Generic parameters that are compile-time constants.

class FixedArray<T, const N: int> {
    let data: T[N];

    func get(index: int): T {
        if (index >= N) throw "Index out of bounds";
        return this.data[index];
    }
}

let arr = new FixedArray<int, 10>();
Enter fullscreen mode Exit fullscreen mode

🐛 Bug Fixes

ID Description Component
BUG-301 Fix GC not collecting circular references in closures GC
BUG-302 Fix trait method resolution order with diamond inheritance Type Checker
BUG-303 Fix debugger source mapping off-by-one for multi-line expressions DAP
BUG-304 Fix type alias expansion in generic contexts Type Checker

📈 Performance Goals

  • GC pause (Gen 0): < 200Ξs
  • GC pause (Gen 1): < 2ms
  • GC pause (Gen 2): < 15ms
  • Debugger overhead: < 5% when breakpoints inactive

🔧 Breaking Changes

  • trait keyword now reserved
  • type keyword now reserved for type aliases
  • Old interface keyword deprecated — use trait instead (compatibility shim provided for 1 release)

ProXPL v1.5.0 — Types that protect, a GC that respects your time.

Top comments (0)