Download the PHP package qaribou/immutable.php without Composer
On this page you can find all versions of the php package qaribou/immutable.php. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download qaribou/immutable.php
More information about qaribou/immutable.php
Files in qaribou/immutable.php
Package immutable.php
Short Description Immutable, highly-performant collections, well-suited for functional programming and memory-intensive applications.
License MIT
Homepage http://github.com/jkoudys/immutable.php
Informations about the package immutable.php
immutable.php
Immutable collections, well-suited for functional programming and memory-intensive applications. Runs especially fast in PHP7.
Basic Usage
Quickly load from a simple array
Map with a callback
Sort with a callback
Slice
Load big objects
Filter
Concat (aka merge)
Reduce
Find
Array accessible
Countable
Iterable
Load from any Traversable
object
Even serialize back as json!
Install
immutable.php is available on composer via packagist.
Why
This project was born out of my love for 3 other projects: Hack (http://hacklang.org), immutable.js (https://facebook.github.io/immutable-js/), and the Standard PHP Library (SPL) datastructures (http://php.net/manual/en/spl.datastructures.php).
- Both Hack and immutable.js show that it's both possible, and practical to work with immutable data structures, even in a very loosely-typed language
- The Hack language introduced many collections of its own, along with special syntax, which are unavailable in PHP.
- SPL has some technically excellent, optimized datastructures, which are often impractical in real world applications.
Why didn't I just use SplFixedArray directly?
The SplFixedArray is very nicely implemented at the low-level, but is often somewhat painful to actually use. Its memory savings vs standard arrays (which are really just variable-sized hashmaps -- the most mutable datastructure I can think of) can be enormous, though perhaps not quite as big a savings as it will be once PHP7 gets here. By composing an object with the SplFixedArray, we can have a class which solves the usability issues, while maintaining excellent performance.
Static-Factory Methods
The SPL datastructures are all very focused on an inheritance-approach, but I found the compositional approach taken in hacklang collections to be far nicer to work with. Indeed, the collections classes in hack are all final
, implying that you must build your own datastructures composed of them, so I took the same approach with SPL. The big thing you miss out on with inheritance is the fromArray
method, which is implemented in C and quite fast, however:
So you can see that while the static class method fromArray()
was called from a FooFixed class, our $foo
is not a FooFixed
at all, but an SplFixedArray
.
ImmArray, however, uses a compositional approach so we can statically bind the factory methods:
Now that dependency injection, and type-hinting in general, are all the rage, it's more important than ever that our datastructures can be built as objects for the class we want. It's doubly important, because implementing a similar fromArray()
in PHP is many times slower than the C-optimized fromArray()
we use here.
De-facto standard array functions
The good ol' PHP library has a pile of often useful, generally well-performing, but crufty array functions with inconsistent interfaces (e.g. array_map($callback, $array)
vs array_walk($array, $callback)
). Dealing with these can be considered one of PHP's quirky little charms. The real problem is, these functions all have one thing in common: your object must be an array. Not arraylike, not ArrayAccessible, not Iterable, not Traversable, etc., but an array. By building in functions so common in JavaScript and elsewhere, e.g. map()
, filter()
, and join()
, one can easily build new immutable arrays by passing a callback to the old one.
Serialize as JSON
More and more, PHP is being used less for bloated, view-logic heavy applications, and more as a thin data layer that exists to provide business logic against a datasource, and be consumed by a client side or remote application. I've found most of what I write nowadays simply renders to JSON, which I'll load in a React.js or ember application in the browser. In the interest of being nice to JavaScript developers, it's important to send arrays as arrays, not "arraylike" objects which need to have a bunch of Object.keys
magic used on them.e.g.
The internal logic makese sense to a PHP dev here -- you're encoding properties, after all, but this format is undesirable when working in JS. Objects in js are unordered, so you need to loop through a separate counter, and lookup each string property-name by casting the counter back to string, doing a property lookup, and ending the loop once you've reached the length of the object keys. It's a silly PitA we often have to endure, when we'd much rather get back an array in the first place. e.g.
Immutability
A special interface gives us an appropriate layer to enforce immutability. While the immutable.php datastructures implement ArrayAccess
, attempts to push or set to them will fail.
Alternative Iterators
PHP7
It's well-known that callbacks are incredibly slow pre-PHPNG days, but once PHP7 becomes the standard the callback-heavy approach to functional programming needed by immutable.php will become far faster. For example, compare this basic test:
On 5.6:
On 7.0alpha2:
Holy moly! Running on my laptop, running the map function (which executes a callback) is 21x faster on PHP7. Running the stable mergesort algorithm is 11x faster on PHP7. Big maps and sorts will always be expensive, but PHP7 drops what may be a prohibitively expensive 300ms map, to a much more manageable 14ms.
All versions of immutable.php with dependencies
ext-json Version *