Release: 0.30.0 - Many Forms

Released

Multimethods + walk/pprint modules + keyword interning + 15+ perf optimizations across core, data structures & REPL

🎉 Added

  • Add subset? predicate for sets: (subset? (hash-set 1 2) (hash-set 1 2 3)) => true
  • Add superset? predicate for sets: (superset? (hash-set 1 2 3) (hash-set 1 2)) => true
  • Add cond-> macro for conditional thread-first: (cond-> 1 true inc false (* 42)) ; => 2
  • Add cond->> macro for conditional thread-last: (cond->> [1 2 3] true (map inc)) ; => [2 3 4]
  • Add vec function to coerce collections to vectors: (vec '(1 2 3)) => [1 2 3]
  • Add hash-set function to create sets from arguments (like Clojure's hash-set)
  • Add phel\walk module with walk, postwalk, prewalk, postwalk-replace, prewalk-replace, keywordize-keys, and stringify-keys
  • Add phel\pprint module with pprint and pprint-str for pretty-printing nested data structures with configurable width
  • Add tap>, add-tap, remove-tap, and reset-taps! to phel\debug for a global tap handler system
  • Add dir, apropos, and search-doc to phel\repl for namespace exploration and documentation search
  • Add defmulti and defmethod macros for runtime polymorphism via dispatch functions
  • Add --fail-fast option to phel test to stop on first failure or error

⚖️ Changed

  • Optimize str/blank?: single regex pass instead of character-by-character loop
  • Optimize str/escape: array_map + implode instead of O(n²) string concatenation
  • Optimize str/last-index-of: native mb_strrpos instead of O(n²) loop
  • Optimize core/reverse: native array_reverse instead of element-by-element conj
  • Optimize core/interleave: reduce + conj instead of repeated concat
  • Eliminate redundant iterations in walk, keywordize-keys, and stringify-keys
  • Cache print-value result in pprint to avoid redundant calls
  • Extract as-pattern helper to deduplicate str/replace and str/replace-first
  • Add identity fast-path (===) in Equalizer::equals() to skip instanceof for identical values
  • Optimize NodeEnvironment::hasLocal() — direct name comparison instead of Symbol::create() + in_array
  • Optimize PersistentList::get() — early bounds check, loop only to target index
  • Eliminate double hash lookup in PersistentHashSet::add()/remove()
  • Optimize PersistentVector::cons() — use TransientVector instead of full array rebuild
  • Deduplicate GlobalEnvironment::getAllDefinitions() via hash keys instead of array_unique
  • Optimize NodeEnvironment::withMergedLocals() — avoid array_unique on Symbol objects
  • Use 2-level nested cache in NodeEmitterFactory to avoid string concatenation per node
  • Cache indentation strings in OutputEmitter
  • REPL now gracefully falls back to fgets(STDIN) when the readline extension is unavailable (Docker, CI)
  • Inline truthy checks at emit time — eliminates Truthy::isTruthy() static method call overhead on every conditional
  • REPL and eval now use in-memory evaluation (eval()) instead of writing temp files, significantly reducing I/O overhead and startup time
  • assoc now accepts multiple key-value pairs in a single call (Clojure alignment): (assoc m :a 1 :b 2 :c 3)
  • BREAKING: set now coerces a collection to a set (Clojure alignment): (set [1 2 3]) => #{1 2 3}
  • Use hash-set for creating sets from arguments: (hash-set 1 2 3) => #{1 2 3}
  • Keywords are now interned (flyweight pattern) — same name/namespace returns the same instance, enabling === identity checks and reducing GC pressure

🐛 Fixed

  • Restore GlobalEnvironment refers/aliases when loading from compiled code cache
  • Functions used in string concatenation (e.g. (str "Hello, " name "!")) no longer crash with a PHP error; they now render as <function:name>
  • Fix zipmap causing out-of-memory error when used with infinite lazy sequences (e.g. (zipmap keys (repeat val)))
  • Fix peek crashing when used on lazy sequences (e.g. from filter or map)
  • Fix excessive blank lines in test output between test dots and summary
  • Fix REPL catch-all error handler showing raw PHP traces instead of source-mapped Phel stack traces

👥 Contributors

@Chemaclass @JesusValeraDev

Full Changelog: v0.29.0...v0.30.0

Downloads


View release on GitHub