Skip to content

xphp-lang/collections

Repository files navigation

xphp-lang/collections

Generic, immutable, variance-aware collections for PHP, built on xphp monomorphization — real generics with declaration-site variance, compiled to concrete PHP classes.

Types

Read-only interfaces (covariant in their element type, contravariant for Comparator):

Interface Description
Collection<out E> A read-only collection (extends IteratorAggregate, Countable).
OrderedCollection<out E> A Collection with positional order and index access.
Set<out E> A Collection with no duplicate elements.
Map<K, out V> A read-only key/value mapping (invariant key, covariant value).
Entry<K, out V> A read-only key/value pair — the element of a Map.
Tuple<out A, out B> A fully-covariant positional 2-tuple (first()/second()); returned by partition and produced element-wise by zip.
Comparator<in T> A comparison strategy (contravariant).

Immutable concrete classes (readonly):

Class Implements
ImmutableList<out E> OrderedCollection<E>
ImmutableSet<out E> Set<E> (identity de-duplication)
ImmutableMap<K, out V> Map<K, V> (int|string keys)
Pair<K, out V> Entry<K, V>
Couple<out A, out B> Tuple<A, B> (readonly; component1()/component2() destructuring)

Types are grouped by concept under XPHP\Collections: the root Collection/Comparator, then Lists\ (including the static ImmutableGrouping/ImmutableZipping/ImmutableReducing helpers), Sets\, Maps\ (which holds Map/Entry/ImmutableMap/Pair), and Tuples\ (Tuple/Couple), plus Support\ for the internal base. The layout is frozen and additive-only — new tiers and data structures are added, never relocated (see ADR-0006). A mutable, invariant tier (MutableList, …) is planned but not part of this release.

Variance

The point of the library is sound variance:

// Covariance: an ImmutableList<Book> is usable where a Collection<Product> is expected.
function total(Collection::<Product> $items): int { return $items->count(); }
$books = new ImmutableList::<Book>(new Book('PHP'), new Book('Generics'));
total($books);

// Contravariance: a Comparator<Product> is usable where a Comparator<Book> is expected.
$sorted = $books->sortedWith(new ByName()); // ByName implements Comparator<Product>, usable here

Using it

The library ships .xphp templates. Concrete classes are generated when you compile your own code (which supplies the concrete type arguments) together with the library, via an xphp.json manifest. See the example in examples/Demo.xphp. Locally:

make build        # compile the library templates
make demo         # compile + run the example
make test/unit    # behaviour tests
make ci           # check + build + tests + PHPStan (level 9) + mutation (100% MSI)

Caveats

Covariance imposes real constraints on the API (no add/remove; element-consuming operations keep the element type via a method-level <S : E> turbofish or a fluent Comparator<E> member, not mixed), and a few behaviours follow from PHP and from monomorphization. Higher-order operations (map, filter, fold, …) take typed Closure(E $x): … callbacks — a wrong closure literal is caught at xphp check, while a plain untyped fn ($x) stays accepted. See docs/caveats.md. Design decisions are recorded under docs/adr/.

License

MIT.

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors