Skip to main content

Release: 0.47 - Clear Signals

Latest update

0.47.0 - Clear Signals

Released 2026-07-01 · GitHub release

LSP/nREPL editor smarts + clearer test diffs & error locations + parallel-test race fix + ~30% faster startup via OPcache re-exec.

🎉 Added

  • LSP signature help now covers plain Phel calls like (map f xs), arity, parameter names, docstring, not just php/... interop (#2643)
  • nREPL eval responses carry per-session *1/*2/*3 value history, so Calva/Conjure show the last three results (#2644)

⚖️ Changed

  • REPL (doc sym) now prints the function's :example under an Example: heading (#2645)
  • phel test shows a +/-/~ structural diff for any same-shape collection that differs (previously only >3 entries); scalars/mixed shapes keep the summary line
  • phel compile prints the folded value to stderr when a snippet emits no PHP (e.g. (+ 1 2)3) (#2624)
  • phel init scaffolds phel-config.php at ->withOptimizationLevel(2); the runtime default stays 0 (#2631)

🐛 Fixed

  • phel test --parallel no longer intermittently fails from the distributed PHAR: a namespace whose worker hits a transient load error is re-run on a fresh worker (up to twice) before the error surfaces, so a rare race can't red the whole run; genuine test failures are never retried, and serial runs were always unaffected (#2672)
  • Re-evaluating an already-loaded bundled namespace (a precompiled .php sibling shipped in the PHAR) no longer nulls its forward-declared defs (map/seq/nil?): the primary is loaded with require_once, so a second load can't reset them to null and crash a later call with __invoke() on null (#2673)
  • Global/PHAR phel resolves the project root from the working directory (nearest phel-config.php or vendor/), not the binary location, so phel config/doctor read the local config from anywhere (#2640)
  • phel-config.php returning null is now rejected with a clear error, not silently treated as empty config (#2642)
  • phel.router/compiled-router now compiles routes carrying a :handler function (#2663)
  • phel build always ships the (load ...) secondaries; a >0 optimization level or disabled compiled-code cache no longer fatals on first load (#2631, #2648)
  • defn/defmacro with a non-symbol name (e.g. (defn 123 …)) now fail with a clean compile error, not a leaked-internals crash (#2639)
  • Invoking a non-function value (e.g. (x 1 2) after (def x 5)) shows the .phel location and a hint:, not the compiled temp path (#2638)
  • "Did you mean" suggestions rank by relevance, so prn suggests print/printf/println, not or/pop/put (#2637)
  • Requiring a missing namespace fails fast at require time, not as a later generic resolve error (#2636)
  • phel run/test/build/profile/export show the .phel location and stack trace for stdlib runtime errors (e.g. (/ 1 0)), matching the REPL (#2635)
  • phel doc (and REPL/LSP completion) writes doc.phel to a unique temp dir, not a fixed package path, fixing intermittent failures under concurrency and on read-only installs (#2630)

Performance

  • Emitter skips generated-column bookkeeping when source maps are disabled, ~6% off the emit phase; output byte-identical (#2634)
  • phel run/eval/repl re-exec once into a warm child with a persistent OPcache file cache (~30% faster startup; opt out with PHEL_NO_OPCACHE_REEXEC=1); phel test --parallel workers share the cache, evaluating each dependency once per worker, fixing --parallel being slower than serial (#2628, #2632)

👥 Contributors

@Chemaclass @JesusValeraDev @MehediHasanJanny

Full Changelog: v0.46.0...v0.47.0

Downloads

v0.47.0


View release on GitHub