JAPL

Just Another Programming Language

A typed actor language for building reliable distributed systems and AI agents.

Pure by default, concurrent by design, resource-safe by construction. LLM calls are tracked effects, agent processes are supervised, and types generate structured I/O.

Core Principles

Seven design commitments that shape every decision in the language.

V

Values Are Primary

Data is immutable by default. Values flow through functions without hidden state, making programs deterministic and easy to reason about.

M

Mutation Is Local and Explicit

When mutation is needed, it is confined to explicit scopes with linear ownership. No action at a distance, no shared mutable state.

C

Concurrency Is Process-Based

Lightweight, supervised processes communicate through typed messages. No threads, no locks, no data races by construction.

F

Failures Are Normal and Typed

Errors are values. Recovery strategies are declared in types. Supervision trees handle the unexpected so your logic stays clean.

D

Distribution Is Native

Processes can span nodes. Location transparency, typed protocols, and built-in distribution make networked systems a first-class concern.

ƒ

Functions Are the Unit of Composition

Pipelines, higher-order functions, and algebraic effects compose cleanly. No inheritance hierarchies, no framework lock-in.

R

Runtime Simplicity = Type Power

The type system does the heavy lifting at compile time so the runtime can stay minimal, predictable, and fast.

See It in Action

Clean, expressive syntax that reads like specification and runs like production code.

server.japl
-- A typed web server with process-based concurrency

type Request =
  | Get(String)
  | Post(String, Body)

type Response =
  | Ok(Body)
  | NotFound
  | Error(String)

fn handle(req: Request) -> Response = match req with
  | Get("/health") -> Ok("ok")
  | Get(path)       -> lookup(path)
  | Post(path, body) -> store(path, body)

fn counter(count: Int) -> Int = receive
  | Increment(n) -> counter(count + n)
  | GetCount     -> count
  | Shutdown     -> count

fn main() -> Result[Unit, Error] =
  let pid = spawn(counter, 0)
  let server = listen(8080, handle)
  supervise([pid, server], OneForOne)
shapes.japl
-- Algebraic data types and pattern matching

type Shape =
  | Circle(Float)
  | Rectangle(Float, Float)
  | Triangle(Float, Float, Float)

fn area(shape: Shape) -> Float = match shape with
  | Circle(r)       -> 3.14159 * r * r
  | Rectangle(w, h) -> w * h
  | Triangle(a, b, c) ->
    let s = (a + b + c) / 2.0
    sqrt(s * (s - a) * (s - b) * (s - c))

fn pipeline(shapes: List[Shape]) -> Float =
  shapes |> map(area) |> filter(fn a -> a > 10.0) |> sum

Built for AI Agents

First-class language support for building reliable, auditable AI systems.

L

LLM as a Tracked Effect

LLM calls are effects in the type system. The compiler knows which functions touch an LLM, enabling static analysis of AI code paths.

S

Structured I/O from Types

JAPL types automatically generate JSON schemas, giving LLMs structured input/output contracts instead of free-form text.

T

Tool Contracts

The tool keyword declares typed functions that agents can invoke, with effects and schemas tracked at compile time.

A

Supervised Agent Processes

AI agents run as supervised processes. If an agent crashes, its supervisor restarts it automatically with the same fault-tolerance as any JAPL process.

B

Budget Tracking (Planned)

Linear types track token budgets as owned resources. The compiler ensures budgets are consumed, never dropped or duplicated.

R

Deterministic Replay (Planned)

Record nondeterministic LLM decisions and replay them for debugging, testing, and auditing agent behavior.

The JAPL Papers

Seven papers developing the theoretical and practical foundations of the language, from first principles to runtime implementation.

Part I

Values Are Primary

Immutable data, algebraic types, and pattern matching as the foundation for a value-oriented programming model.

~25 pages 50 references
Part II

Mutation Is Local and Explicit

Linear types, ownership semantics, and confined mutability for safe, predictable state transitions.

~25 pages 38 references
Part III

Process-Based Concurrency

Lightweight processes, typed message passing, and supervision trees as the concurrency primitive.

36 pages 40 references
Part IV

Typed Failures

Error values, result types, and recovery strategies that make failure handling explicit and composable.

23 pages 40 references
Part V

Native Distribution

Location-transparent processes, typed protocols, and network-aware semantics for distributed systems.

~25 pages 35 references
Part VI

Function Composition

Pipelines, higher-order functions, algebraic effects, and the function as the universal unit of abstraction.

~22 pages 40 references
Part VII

Runtime Simplicity

A minimal runtime enabled by maximum compile-time reasoning: type-directed erasure, monomorphization, and static dispatch.

23 pages 40 references

Language Design DNA

Four traditions, unified by a coherent type theory.

ML / OCaml / Gleam

Logic

Algebraic types, pattern matching, parametric polymorphism, and type inference form the reasoning backbone.

Rust

Resources

Ownership, borrowing, and linear types ensure memory safety and deterministic resource management without a GC.

Erlang / OTP

Liveness

Lightweight processes, message passing, supervision trees, and "let it crash" philosophy for fault-tolerant systems.

Go

Deployment

Fast compilation, static binaries, simple tooling, and a pragmatic approach to getting production systems running.

Compiler Architecture

A stage-0 bootstrap compiler written in Rust, implementing the full JAPL pipeline from source to execution.

Lexer

Tokenization

Parser

AST construction

Type Checker

Hindley-Milner

Effect System

Algebraic effects

Linearity

Ownership check

Runtime

Process scheduler

View Source