Skip to content

Repository files navigation

gleamunison

Content-addressed language runtime on the BEAM, built in Gleam.

A running prototype of a Unison-style content-addressed programming language that compiles to BEAM bytecode and loads dynamically into the Erlang VM.

Rationale & Gap Analysis

Why Gleamunison?

Gleamunison combines the type-safe concurrency of the BEAM (via Gleam) with Unison's content-addressed codebase and algebraic effects, enabling zero-downtime hot upgrades and dynamic sandboxing.

Feature Set Differences (Gleamunison vs Unison)

Feature Unison Gleamunison Trade-off / Benefit
Identity SHA3-512 (Term+Type) SHA256 (Term+Type) SHA256 is native on BEAM; less hash size overhead.
Primitives ## Prefix Namespace Genesis Block (Hash space) Genesis eliminates dual-identity complexity.
Effect Model Explicit continuation k Implicit stack-based frame Stack-based is simpler; lacks explicit k resume.
Codebase Store SQLite / Event Log DETS / ETS Storage DETS is native and lightweight on BEAM.
Namespaces Hierarchical Projects Flat namespace mapping Flat is simpler; hierarchy can be layered.

Complexity vs. Utility

Element Complexity Utility Recommendation
Genesis Primitives Low High Adopted: Kept hash-space uniform.
Stack-based Effects Medium High Adopted: Simpler runtime implementation.
Unique Type GUIDs Low Medium Adopted: Prevents structural hash collisions.
Remote Ability High Low Out-of-Scope: Rely on BEAM distribution instead.

How Hashes Act as Executables

In gleamunison, a program is not a monolithic binary file. It is a Merkle Directed Acyclic Graph (Merkle DAG) of content-addressed AST definitions stored in a database.

The Merkle DAG Code Structure

Each function definition is parsed into an AST and hashed based on its structure, stripping variable names to ensure α-equivalence. If a function references other functions, it references them strictly by their hashes (RefTo AST node).

                  ┌───────────────────────┐
                  │   start-server Hash   │  ◄─── This single Root Hash IS the executable
                  │       [#ff45e8]       │
                  └───────────┬───────────┘
                              │
             ┌────────────────┴────────────────┐
             ▼                                 ▼
 ┌───────────────────────┐         ┌───────────────────────┐
 │  page-template Hash   │         │    query-db Hash      │
 │       [#ac88b2]       │         │       [#3b12ef]       │
 └───────────────────────┘         └───────────┬───────────┘
                                               │
                                               ▼
                                   ┌───────────────────────┐
                                   │  Datalog-Transact Jet │
                                   │  [#00000064] (Builtin)│
                                   └───────────────────────┘

The entire application (CMS, database, or GUI) is represented by a single root hash (e.g. #ff45e8).

Step-by-Step Execution

When running a program by its hash:

  1. DAG Resolution: The runtime looks up the root hash in its database, transitively walks the dependency graph, and fetches any missing dependency hashes from peers via the Pull Sync Protocol.
  2. On-the-Fly Compilation: The compiler translates the resolved AST nodes into Erlang BEAM bytecode binary arrays named after their hashes (e.g. m_ff45e8.beam).
  3. Dynamic Loading & Run: The VM dynamically loads the bytecode (code:load_binary/3) and calls the module's entrypoint function 'm_ff45e8':'$eval'().

This enables zero-downtime hot upgrades (running new logic by swapping to a new root hash) and conflict-free dependency resolution.

Unique Usecases (Impossible on Gleam or Unison Alone)

Gleamunison combines the scheduling, distribution, and runtime efficiency of the BEAM with the content-addressing and algebraic effects constraints of Unison:

Hot-Upgrades & Evolution

  1. Zero-Downtime Stateful Actor Upgrades: Hot-swapping active actor code on-the-fly without state loss. Standard Gleam module updates clash on name collisions; Gleamunison addresses this by compiling into hash-named modules.
  2. Stateful Chatbot Hot-Upgrades: Preserve active user conversation states in Erlang actors. Swaps the actor message-handling loop to a new hash definition on the fly without state or connection loss.
  3. IoT Firmware Hot-Patching: IoT devices download modular function hashes instead of heavy firmware images, updating local logic dynamically without device resets.
  4. Dynamic API Gateways: Route HTTP requests based on endpoint definition hashes, dynamically compiling and loading handlers on demand.

Secure Sandboxing & Multitenancy

  1. Decoupled Multi-tenant Sandboxing: Run untrusted plugins concurrently. Process boundaries isolate resource usage, while algebraic effects intercept and sandbox system actions (file, network).
  2. Zero-Trust Serverless Executions: Execute third-party thunks securely. The host caps execution time via process CPU schedulers and restricts access using custom effect handlers.
  3. Capabilities-as-Code: Database and network handles are represented strictly as abilities. User code only typechecks if the required abilities match their group access privileges.
  4. Sandbox Game Modding: Run game modding scripts in isolated BEAM processes. Mod APIs are exposed as abilities, preventing malicious access to the host filesystem.

Distributed Compute & Edge topographies

  1. Resilient P2P Job Stealing: Edge nodes dynamically pull, structurally verify, locally compile, and run job definitions by hash.
  2. Live Process Migration: Serialize a running actor's continuation closure, ship it to a remote node, sync missing code dependencies via pull protocol, and resume execution.
  3. Zero-Config Clustered Map-Reduce: Parallelize map-reduce workflows. Code dependencies are automatically resolved and shipped by the runtime on target locations using Merkle sync.
  4. Edge-Cloud Compute Offloading: IoT devices offload heavy compute thunks to BEAM cloud nodes, verifying code integrity by hash to prevent remote exploits.
  5. Content-Addressable CDN Handlers: CDNs compile custom request handlers, push them to edge nodes by hash, and process CDN requests concurrently on edge processes.
  6. P2P Software Distribution: Sync codebases incrementally. Nodes exchange root hashes and request only missing modules, reducing patching bandwidth.

Determinism, Auditing & Tools

  1. Time-Traveling Replay Debugging: Capture trace logs of execution. Replay the exact execution path deterministically using mock clock/random effect handlers.
  2. Distributed Event Sourcing with Code Auditing: Event stores record event payloads alongside the handler's hash, allowing historic events to be replayed with the exact code version.
  3. Smart Contract Workflows: Execute decentralized workflows. All state mutations and payments are modeled as abilities, sandboxed by host-defined contract handlers.
  4. Multi-Tenant Concurrent Parsers: Compile user-provided parser grammar thunks. Preemptive BEAM scheduling prevents a single bad parsing loop from blocking others.
  5. Self-Documenting Code Registries: Code definitions are hashed and immutable. Documentation and tests are linked directly to hashes; renaming never breaks documentation.
  6. Immutable Cloud Shell: Run interactive REPL sessions where every expression is compiled and stored. Keeps old module versions in memory for historic comparisons.
  7. Content-Addressable Microservices: Services call others by passing function hashes over RPC. The runtime resolves, syncs, and loads the code dynamically.
  8. Decentralized Knowledge Graph: A wiki-like graph where nodes are content-addressed definitions and links are type-safe references forming a Merkle DAG.
  9. Reproducible Monte Carlo Simulations: Replay complex stochastic simulations by mock-handling random generator and timer abilities using fixed seeds.

Project State

Production-grade runtime (Phases 0–14 complete). All components are implemented and verified. The runtime is fully playbook-certified, passing all 5696 playbook conformance levels and 54 unit test suites (all passed). v3.11.0 includes native content-addressed Datalog database engine with temporal indexing, graph algorithms, BM25, and vector search, alongside safe FFI deserialization, localhost endpoint restrictions, Ranch port monitoring safeguards, modular genesis builtin extraction, and a data-driven test runner framework.

Step Status
AST → Hash (SHA256) ✓ Content-addressed identity
Codebase insert with hash verification ✓ DETS/ETS persistence, dedup
Compile to BEAM binary (all Term variants) ✓ Int/Float/Text/List/Lambda/Apply/Let/Match
Load into VM (code:load_binary/3) ✓ OTP 29 compatible
Type inference (Int/Float/Text/List) ✓ Hindley-Milner style
Elaboration (Surface → Core) ✓ Two-phase with name resolution
Effects runtime (process dict stack) ✓ do_/handle_/push_frame/pop_frame
Sync protocol (pull-based) ✓ Types + Erlang distribution FFI + TCP sync
Native Datalog Engine ✓ Pure S-expression EAVT/AVET, temporal, rules, BM25, vector
escript standalone binary ✓ ~1.2 MB, no Gleam dependency at runtime

Conformance Tests

To execute the unit and integration test suites:

gleam test                          # Runs all 54 unit test suites including native Datalog
bb scripts/run_playbook_tests.clj   # Runs playbook conformance suite

Why the escript is only 1.2 MB

The standalone binary (gleamunison_escript) contains the full content-addressed runtime — parser, elaborator, typechecker, compiler, loader, codebase, effects system, web server, REPL, 52 genesis modules, and all stdlib dependencies. At ~1.2 MB, it's compact because:

BEAM bytecode is dense. The compiled .beam files are ~2.4 MB uncompressed; zip compression brings that to ~1.2 MB.

No VM bundled. Unlike Go or Rust binaries that statically link a runtime, the escript relies on the system's Erlang/OTP installation (~150 MB, installed once). The escript itself is just a zip archive with a 50-byte launcher header.

Format Size Dependencies
gleamunison escript 1.2 MB Erlang/OTP
Go binary 10–20 MB None
Rust binary 5–15 MB None
Node.js app + deps 100–500 MB Node.js

If you already have Erlang installed, this is as close to a zero-install language runtime as it gets.

Modules (44 Gleam source modules, Erlang FFI, 52 genesis modules, 13 Datalog engine modules)

Module Concern Status
gleamunison/identity Opaque Hash, DefinitionRef, LocalVar Real
gleamunison/ast Core AST: Term (15 variants), Type, Definition, Unit Real
gleamunison/types Core type definitions Real
gleamunison/typecheck Type checker Real
gleamunison/inference Type inference engine (Hindley-Milner) Real
gleamunison/infer_helper Type inference helpers (alpha-equivalence, substitution) Real
gleamunison/codebase Content-addressed Merkle store Real
gleamunison/elaborate Surface → Core elaboration orchestration Real
gleamunison/elab_def Definition elaboration (term, type, ability) Real
gleamunison/elab_pat Pattern elaboration Real
gleamunison/elab_term Term elaboration Real
gleamunison/elab_types Type elaboration Real
gleamunison/elab_ctx Elaboration context Real
gleamunison/lower AST lowering / IR transformations Real
gleamunison/parser S-expression parser & tokenizer Real
gleamunison/lexer Lexer / tokenizer Real
gleamunison/type_pretty Pretty-printer for types Real
gleamunison/compile AST → Erlang source → BEAM binary Real
gleamunison/loader Dynamic module loading into VM Real
gleamunison/effects Algebraic effect types + Erlang runtime Real
gleamunison/storage ETS, DETS, Partitioned DETS, and Mnesia storage adapters Real
gleamunison/repl REPL entry point and loop orchestrator Real
gleamunison/repl_eval REPL evaluation and definition compiler pipeline Real
gleamunison/repl_io REPL bracket counter and line accumulator Real
gleamunison/sync Pull-based sync protocol Real
gleamunison/sync_types Sync protocol type definitions Real
gleamunison/http Web server entry point Real
gleamunison/http_client Typed HTTP client (get/post/put/delete) Real
gleamunison/json JSON encode/decode Real
gleamunison/datetime Opaque DateTime, ISO 8601, arithmetic Real
gleamunison/filepath Opaque Path manipulation Real
gleamunison/crypto Hash, HMAC, random bytes Real
gleamunison/template {{var}} string interpolation Real
gleamunison/log Structured logging (debug/info/warn/error) Real
gleamunison/config Configuration management (env/TOML/CLI) Real
gleamunison/health Health checks and readiness probes Real
gleamunison/metrics Counter/gauge/histogram with telemetry Real
gleamunison/pipeline Factored pipeline phases (parse_only, elaborate_only, compile_only, load_and_eval) Real
gleamunison/jets FFI Jet compiler interception registry Real
gleamunison/bootstraps Cycle-free genesis bootstrap definitions Real
gleamunison/genesis Genesis block constants and hashes Real
gleamunison/util Shared utilities (e.g. range helper) Real
gleamunison/verify Interactive and file-based verification runner Real
gleamunison/dogfood_runner Data-driven dynamic VM test runner Real
gleamunison_datalog/src/ 13-module S-expression Datalog database engine Real
gleamunison_ffi.erl FFI: hashing, compilation, loading, process dict Real
gleamunison_effets.erl Effects runtime: push/pop/find_frame, do_op/handle_comp Real
gleamunison_storage.erl ETS/DETS/Mnesia storage backend with SHA256 atom safety Real
gleamunison_tcp_sync.erl TCP sync server with safe deserialization & length limit Real
gleamunison_http.erl HTTP server with trace capture, SSE, and health routes Real
gleamunison_http_routes.erl Route handlers: eval, define, browse, traces, logs, modules Real
gleamunison_http_util.erl HTTP utilities: JSON, MIME, URL decode, SSE broadcast Real
gleamunison_sup.erl OTP Supervisor tree Real
gleamunison_repl_ffi.erl REPL FFI bridge Real
gleamunison_trace.erl Request trace capture (DETS) for Darklang-style development Real
gleamunison_adapters.erl Lazy CAS type adapters for schema migration Real
gleamunison_log.erl Structured log ETS backend Real
gleamunison_config.erl Environment variable config loader Real
gleamunison_health.erl Node health status (memory, modules) Real
gleamunison_metrics.erl Counter/gauge/histogram with telemetry Real
gleamunison_crypto.erl SHA256/512, HMAC, random bytes backend Real
gleamunison_datetime.erl ISO 8601 parse/format backend Real
gleamunison_template.erl String interpolation with HTML escaping Real
gleamunison_json.erl JSON encode/decode backend Real
gleamunison_http_client.erl HTTP client wrapping httpc Real
gleamunison_property.erl Property-based testing framework Real
m_*.erl (52 files) Content-addressed genesis modules Real

Quick start

cd ~/Desktop/gleamunison_dogfood/gleamunison_repo
gleam run -- all             # Run all dogfooding levels via dynamic VM runner
gleam test                  # Run unit tests (54 test suites)
./gleamunison_escript repl   # Start interactive REPL via standalone escript (after ./build_escript.sh)

Documentation

Runtime output

=== Gleamunison ===
Int(42)           ✓ Hash → Compile → Load
Lambda(id)        ✓ Hash → Compile → Load
Apply(id, 99)     ✓ Hash → Compile → Load
Let(V0=42, V0)    ✓ Hash → Compile → Load
Text(hello)       ✓ Hash → Compile → Load
List([1,2,3])     ✓ Hash → Compile → Load
Match(42, cases)  ✓ Hash → Compile → Load
Type Inference    ✓ Int/Float/Text/List
Elaboration       ✓ Surface → typed
Effects           ✓ RuntimeConfig
Sync              ✓ PeerId/SyncState

License

MIT

About

Gleamunison combines the type-safe concurrency of the BEAM (via Gleam) with Unison's content-addressed codebase and algebraic effects, enabling zero-downtime hot upgrades and dynamic sandboxing.

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages