Skip to main content

Release: 0.37 - Type Inference

Latest update

0.37.0 - Type Inference

Released 2026-05-12 · GitHub release

Type tags + tag inference + 3.66x recursion speedup + agent-install workflow + .phel/ consolidation.

🎉 Added

Core

  • defn metadata: ^:memoize, ^{:memoize-lru N} wrap body in memoize / memoize-lru (#1915); ^:async wraps in async returning Amp\Future (#1924)

Compiler

  • :tag metadata emits PHP type declarations; reader shorthands ^int, ^"?int", ^"\\Foo\\Bar", ^{:tag "..."} (#1916)
  • Tag inference: return types from tail primitive ops and tail calls to tagged globals / pure PHP built-ins (#1932, #1941); param types from primitive body uses (#1944); inferred tags persist in def meta and graft onto compiled PHP signatures for single-arity defn (#1941, #1949)
  • Static checker reports :tag mismatches at compile time (#1933)
  • php/Foo.Bar/baz and php/Foo.Bar.baz accepted as backslash-free aliases for php/Foo\Bar\baz (#1952)
  • composer bench-jit-baseline / bench-jit-tracing for typed-vs-untyped JIT kernels (#1931)

Profile

  • phel profile <path>: per-fn timings and compile-phase costs (--format, --output)

Test

  • Unified diff on (is (= a b)) collection failures
  • phel test --repeat=N, --seed=<int>, --random-order

REPL

  • Eval-error rendering: headline, optional hint, trace with internal frames hidden

⚖️ Changed

Compiler

  • Recursive self-calls emit $this(...): ~3.66x faster (#1914)

DX

  • phel agent-install stamps installed skill files with <!-- phel-agents vX.Y.Z --> from VERSION; idempotent on re-install
  • Slimmer Claude skill (89 → 36 lines); shared syntax cheatsheet moved to resources/agents/quick-syntax.md; aider/codex/gemini/copilot/cursor pointers unified
  • phel agent-install --check reports installed vs current skill version per platform; exits 1 on drift
  • phel agent-install --list enumerates platforms, source templates, install targets, and current state
  • phel agent-install --uninstall removes skill file(s) and restores .pre-phel.bak if present; --with-docs also drops .agents/
  • phel agent-install --auto installs skills only for agents already used in the project (detects .claude/, .cursor/, AGENTS.md, GEMINI.md, etc.)
  • phel doctor now reports installed agent skills and surfaces stale versions in one place
  • New agent task recipes: tasks/async.md, tasks/memoize.md, tasks/write-macros.md; common-gotchas trimmed to non-duplicative items; module table cross-links to tasks
  • Runtime state (cache, REPL history, error log) consolidated under .phel/; relocate via withPhelDir() or PHEL_DIR env (#1954)
  • Module boundary tightening: Munge, CompileOptions, PhelProjectDirectory, VersionFinder moved to Phel\Shared; GlobalEnvironment, DebugLineTap exposed via CompilerFacade (#1963, #1964)
  • PhelConfig immutable via withX() chain; build/export fields flat on root; old setX() shims deprecated
  • Breaking: PhelConfig::forProject(ProjectLayout $layout = Flat, string $mainNamespace = ''): layout first, Flat default
  • Breaking: Cross-module exceptions + CodeSnippet moved from Phel\Compiler\Domain\Exceptions / Phel\Compiler\Domain\Evaluator\Exceptions / Phel\Compiler\Domain\Parser\ReadModel to Phel\Shared\Exceptions / Phel\Shared\Parser\ReadModel (#1975)
  • Breaking: Phel\Printer moved to Phel\Shared\Printer. Phel sources should now (:use Phel.Shared.Printer.Printer); old path no longer resolves
  • Upgrade note: clear compiled caches after upgrading (./vendor/bin/phel cache:clear, or delete .phel/cache/). Cached PHP from earlier installs references the old FQNs and will fail to load otherwise. Both Phel sources and compiled fixtures in this repo are regenerated; downstream projects must rebuild theirs.

🐛 Fixed

Compiler

  • Return-type inference skips loops whose recur rebinds to a different/unknown type

Core

  • memoize / memoize-lru retain entries from recursive calls within a single invocation (#1915)

Test

  • Default reporter wraps dot output at 80 columns under with-output-buffer

Api

  • phel analyze preloads namespaces required by the analyzed file (#1919)

Nrepl

  • lookup / info / eldoc resolve session-defined defns, honoring request ns param or session namespace (#1963)

Build

  • Entry-point main.php require_once resolves dotted main namespaces to nested paths (#1956)
  • PhpNamespaceCache evicts always-excluded segments at load time; policy changes take effect without manual cache wipe (#1962)

Run

  • phel run <file> resolves (:require ...) from configured srcDirs/vendor first; sibling files resolve only as name-matched fallback (#1962)
  • REPL startup.phel lives at resources/repl/startup.phel, outside default srcDirs (#1962)

👥 Contributors

@Chemaclass @JesusValeraDev

Full Changelog: v0.36.0...v0.37.0

Downloads

v0.37.0


View release on GitHub