Skip to content

Compile lexically scoped source bodies once - #95

Merged
robertvansteen merged 3 commits into
0.xfrom
STRAT-733-subprogram
Aug 18, 2026
Merged

Compile lexically scoped source bodies once#95
robertvansteen merged 3 commits into
0.xfrom
STRAT-733-subprogram

Conversation

@robertvansteen

@robertvansteen robertvansteen commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add a persistable ScopedExpression with explicit parameter names and no reserved item convention
  • compile scoped bodies once through SourceCompilation::scope(), with local parameters shadowing equal outer names and every other symbol resolving lexically
  • invoke compiled scopes repeatedly with exact local bindings while sharing enclosing inputs, memoized definitions, failures, and execution observation
  • use opaque scope identities so nested scopes and outer definition dependencies cannot be confused by equal symbol names
  • document the extension interface with a short-circuiting host-owned any example

Why

Host sources such as existential list predicates need to run one ordinary Axiom expression against several values without recompiling it for every item. The body should compose like the rest of the language: names explicitly bound by its owner are local, while free inputs and definitions retain their normal enclosing meaning.

This provides that scoped evaluation mechanism without callbacks, a magical parameter name, a first-class function type, or a generic lambda value in the persisted language.

Impact

Extension authors can persist a ScopedExpression, supply its parameter types from certified sibling sources, and invoke the resulting CompiledScopedExpression from SourceEvaluation. Bound parameters stay out of public input, definition, and Program::$references analysis; genuinely free symbols remain ordinary enclosing inputs and program references.

The supplied local values skip a redundant public-boundary admission because the owning source compiler obtained them from certified compiled parents. Host-specific portability policies remain the host's responsibility.

The branch is rebased onto current 0.x (v0.6.14). Scoped compilation composes with the compiler-owned reference analysis from #90 and the demanded-binding boundary from #92: local parameters are excluded from public references, while captured outer symbols are retained.

Validation

  • composer test:types
  • composer test:unit — 1,219 tests, 4,701 assertions, 100% line coverage
  • composer test:infection — 2,333 mutants, 100% MSI and mutation coverage
  • Pint on every changed PHP file
  • GitHub matrix green on PHP 8.4 and 8.5, prefer-lowest and prefer-stable
  • git diff --check

@robertvansteen robertvansteen changed the title Compile separately-bound source bodies once Compile lexically scoped source bodies once Aug 17, 2026
@robertvansteen
robertvansteen force-pushed the STRAT-733-subprogram branch 2 times, most recently from 11ef5dd to b8138de Compare August 17, 2026 09:39
@robertvansteen
robertvansteen changed the base branch from demanded-inputs to 0.x August 17, 2026 09:40
@robertvansteen
robertvansteen force-pushed the STRAT-733-subprogram branch 3 times, most recently from c1e95b3 to 1f9ec08 Compare August 17, 2026 13:15
@robertvansteen
robertvansteen marked this pull request as ready for review August 18, 2026 10:34
@robertvansteen
robertvansteen merged commit 92a845a into 0.x Aug 18, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant