functional-php/CHANGELOG.md
2026-10-28 10:05:43 +01:00

2.2 KiB

Changelog

1.0.1

Changed

  • sort() without a comparator and sortBy() sort natively, comparing like <=>. Enums used directly as the sort key (or as the values for sort()), which <=> can't order, are now grouped by case, in an unspecified order, and placed after the other values (before them in descending order). Enums nested inside arrays are unaffected.

Fixed

  • sortBy() and sort() are several times faster: they use PHP's native sort instead of usort() with a userland comparator.
  • compile() of a closure of a curried function ($curried(...)), alone or in a pipeline, keeps currying instead of throwing ArgumentCountError.
  • filter() on arrays with a callback taking its value by reference (fn (&$value) => ...) no longer emits "must be passed by reference" warnings.

1.0.0

Breaking

  • PHP 8.2 or newer is required.
  • Contributors need PHPUnit 11 to run the test suite.

Added

  • compile() and Compilable: partials, curried and fixed functions, pipes and predicates flatten into plain closures once, so hot loops don't go through their __invoke(). Compiled internal functions drop extra arguments.
  • Collections in Kadet\Functional\Collections: transforms (map, filter and friends), queries, and collectors with grouping. The transforms also come lazy, returning generators, in Kadet\Functional\Collections\Lazy; queries and collectors accept lazy input and end a lazy chain.
  • Collection callbacks get ($value, $key), except internal functions and callables declaring one parameter, which get only the value. Wrappers (partial(), memoize(), predicates, pipe()) are seen through to the function they call.
  • php-ds is suggested for the collections. DsUnavailableException is thrown when it is needed but not installed.
  • EmptyCollectionException is thrown by queries that need an element when the collection has none (or none matching).
  • Docblock types and generics, so static analysis understands collection contents.

Fixed

  • not() and Predicate::not() predicates return the negated predicate from getDecorated() instead of null.
  • closure() and ref() accept static method callables like [Foo::class, 'method'].