Release: 0.45 - Warm Boot
0.45.1
Released 2026-06-20 · GitHub release
🐛 Fixed
- The PHAR now ships Symfony's shell-completion scripts, so
phel completion bash|zsh|fishworks for PHAR installs again (the build excluded.bash/.zsh/.fishfiles, which silently dropped the completion templates) (#2522)
👥 Contributors
Full Changelog: v0.45.0...v0.45.1
0.45.0 - Warm Boot
Released 2026-06-20 · GitHub release
Phel 0.45: precompiled PHAR core (cold-start ~1.2s→0.2s), native-int arithmetic fast path (~1.8–8x), shell completion + CLI short aliases, plus REPL autocompletion and many round-trip/recur/protocol bug fixes.
🎉 Added
- The PHAR ships
phel.coreprecompiled, cutting cold-startrun/test/evalfrom ~1.2s to ~0.2s (#2443) phel doctorreports whether OPcache persists the compiled-code cache across CLI runs, with fixes (#2446)- Shell completion for
phel doc, option values, and project namespaces;bash/zsh/fishinstall docs (#2451) phel init/agent-installend with an optional shell-completion tip for your$SHELL(#2501)- Consistent CLI short aliases:
-f(format),-o(output),-s(sort) acrossdoc/lint/profile/test(#2502) - Every CLI command's
--helpnow includes a usage example (#2503) - REPL/nREPL autocompletion now completes special forms and native symbols (
def,fn,let,recur, ...) (#2505) - REPL Tab on a unique completion shows the symbol's inline doc (signature + summary) (#2515)
- Non-REPL command errors (
run/test/eval) now print the same actionable hints as the REPL (#2506) - Short aliases for high-frequency commands:
r(run),t(test),b(build),e(eval) (#2507) - New
docs/cli-reference.md: every command, the dev loop, and compile vs eval vs run vs build (#2508) - LSP PHP interop completion/hover/signature help (follow-up to #2431):
(:use ...)/(use ...)alias resolution (#2461), LSP 3.17 signature help (#2462), hover for properties/constants/enum cases/classes (#2463),php/->chain and union/intersection type resolution (#2464), suppression inside strings and comments (#2465), and refined class-name completion (#2466)
Performance
- Native-int fast path in
NumericOperationsfor+ - * / < =,quot/rem/mod; ~1.8–8x per op (#2458 #2459) - Core arithmetic and
bit-*ops drop the per-opapplyround-trip; ~26% on arithmetic-heavy workloads (#2460)
⚖️ Changed
- CLI flag renames with deprecated aliases kept:
index --output/-o(was--out),config --format=json(was--json); old flags warn on stderr (#2511) - Breaking: the runtime CLI-args var is now
*argv*(earmuffed), matching*program*and Clojure's*command-line-args*; the oldargvname was removed. Replaceargvwith*argv*in scripts that read command-line arguments (#2494)
🐛 Fixed
phel.edn:#inst(DateTimeInterface) values now write back as#inst "..."and round-trip (#2486)- Constant folding of overflowing int arithmetic (
+/-/*) now promotes toBigIntlike the runtime instead of folding tofloat(#2483) phel.transit: whole-number floats (1.0,-0.0,1.5e10) round-trip as floats, not ints (#2485)phel.router: passing a bare string (or a sequence of bare strings) now raises a clear error instead of silently iterating the string character-by-character into garbage routes (#2487)loop/fnrecurinside alet(or any inner binding) that shadows a loop binding / fn param now updates the loop variable instead of the shadowing binding, fixing a silent infinite loop (#2482)NANmap/set keys are now retrievable viaget/contains?/assoc, while(= NAN NAN)staysfalse(#2475)phel.json: floats encode as JSON numbers so values round-trip; empty maps encode to{}(#2477)- Keyword literals with multiple slashes (
:a/b/c) keep everything after the first/as the name, matching Clojure (#2478) - Consistent float printing across
str/print/REPL: integer floats keep.0, specials renderNaN/Infinity/-Infinity(#2479) - Protocol methods declared with multiple arities now dispatch on every arity, not just the last installed one (#2481)
phel.html: void elements (br,img, ...) are always self-closing and ignore childrenphel.transit: empty maps round-trip as maps, and numeric string keys stay strings- Reading a struct field with a non-keyword key no longer crashes; symbols/strings match by name, else
nil phel.string:pad-*with an empty pad string falls back to a single spacedefmacrodeclaring only one of&form/&envno longer fails withRedefinition of parameter- Printing
NANno longer leaks a PHP coercion warning phel buildfrom the PHAR harvests every(load ...)stdlib secondary so the output runs standalone (#2449)phel test/phel runwith a missing file path no longer leaks afile_get_contents()warning (#2442)- PHP 8.5 compatibility: guard
ReflectionClass::getConstantand mark deprecated-setter tests (#2455)
👥 Contributors
Full Changelog: v0.44.0...v0.45.0
Downloads
v0.45.1
- phel.phar (1.94 MB)
v0.45.0
- phel.phar (1.94 MB)