goforge.dev/expr is the /goals/06-expr semantic rewrite of
expr-lang/expr, authored in Go+ and
distributed as ordinary generated Go. It is pinned to upstream v1.17.8
(21f4f0575591d7097e576edd7983daf23c1e4afe), and the upstream MIT licence
travels with the source.
Dynamic expression evaluation is the strongest forcing case in the portfolio
for GADTs and existential types, because the thing a caller most wants to know
— what type does this expression produce, and what can it do? — is exactly
what a map[string]any engine throws away.
What the types carry
The Go+-authored core replaces the usual any-typed pipeline with an indexed
one:
Expr[T]— an expression’s result type is part of its type, so the checked evaluation path contains noany.SomeExpr— a finite existential, which is what parsing a string at runtime honestly returns: some expression, whose type you must then scrutinise rather than assume.Instruction[input, output]andStack[n]— bytecode instructions carry their stack effect, and the stack carries its depth. Composition is checked, not asserted.Eq[n, m]— depth transport, so a jump that must land on a stack of the same shape has to prove it.- Explicit compile-time versus run-time failures, and controlled effects, rather than a single error channel that conflates them.
Imported cross-module fixtures prove bytecode composition and reject stack underflow, wrong instruction effects, and false equality witnesses — the negative half that keeps the indices honest across a package boundary.
Compatibility
The reproducible inventory records all 617 exported upstream declarations,
and the language matrix bounds the checked tier explicitly rather than
implying total coverage. A map[string]any migration facade is provided for
callers moving over incrementally.
Performance
Across the recorded five-run gate, against upstream v1.17.8:
| Path | Speedup | Allocations |
|---|---|---|
| Compilation | ≥ 4.72× | 59.4% fewer |
| Typed scalar VM | ≥ 2.81× | 0, versus 3 |
map[string]any facade | — | 0 |
Differential, rejection, fuzz, race, generation, and allocation gates pass.
Status
Version 0.1.0 is the current release:
go get goforge.dev/expr@v0.1.0.
Browse the Go package documentation.
/goals/06-expr is not yet marked complete in
GOALS.md: the
portfolio’s own completion rule asks for a named production consumer, and this
release does not have one yet.