PHPackages                             bluesnowman/fphp-saber - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. bluesnowman/fphp-saber

ActiveLibrary

bluesnowman/fphp-saber
======================

A functional PHP library, which promotes strong typing, immutable objects, and lazy evaluation.

0.0.1(11y ago)12201Apache-2.0PHPPHP &gt;=5.4.0

Since Jan 2Pushed 10y ago3 watchersCompare

[ Source](https://github.com/bluesnowman/fphp-saber)[ Packagist](https://packagist.org/packages/bluesnowman/fphp-saber)[ Docs](http://github.com/bluesnowman/fphp-saber)[ RSS](/packages/bluesnowman-fphp-saber/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (4)Used By (0)

Saber
=====

[](#saber)

A functional PHP library, which promotes strong typing, immutable objects, and lazy evaluation.

[![License](https://camo.githubusercontent.com/eaa49eb3b557b5be1754645a61499cbe3bb5fb33d9c1380ec04b53f431e10902/68747470733a2f2f706f7365722e707567782e6f72672f626c7565736e6f776d616e2f667068702d73616265722f6c6963656e73652e737667)](https://packagist.org/packages/bluesnowman/fphp-saber)[![Latest Stable Version](https://camo.githubusercontent.com/ae86d958b75e36bf587835c71e1bbfa97dfb50ffedd0fab3664a6321e51af089/68747470733a2f2f706f7365722e707567782e6f72672f626c7565736e6f776d616e2f667068702d73616265722f762f737461626c652e737667)](https://packagist.org/packages/bluesnowman/fphp-saber)[![Build Status](https://camo.githubusercontent.com/d5aeb1395fa183ba7fc96b075d04aa91b81bd925d27b2dd023758ccf12fe9e35/68747470733a2f2f7365637572652e7472617669732d63692e6f72672f626c7565736e6f776d616e2f667068702d73616265722e737667)](http://travis-ci.org/bluesnowman/fphp-saber)[![Dependency Status](https://camo.githubusercontent.com/c233348a43742d1dbf165ef72d95cf0fdb3b5b4a968bee71183841f91551f12d/68747470733a2f2f7777772e76657273696f6e6579652e636f6d2f757365722f70726f6a656374732f3535333165393634313065373134393036363030306366382f62616467652e7376673f7374796c653d666c6174)](https://www.versioneye.com/user/projects/5531e96410e7149066000cf8)[![Code Coverage](https://camo.githubusercontent.com/c15ab79ad5fcd9eeda82a228ac4dce0e2781d2a19f88477f53c1478c3f19ad93/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f626c7565736e6f776d616e2f667068702d73616265722f6261646765732f6770612e737667)](https://codeclimate.com/github/bluesnowman/fphp-saber)[![Issue Count](https://camo.githubusercontent.com/e41685ddcc5a66e3b39210589ca624f1110556ef5f528f09bd3232473ae3e54c/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f626c7565736e6f776d616e2f667068702d73616265722f6261646765732f69737375655f636f756e742e737667)](https://codeclimate.com/github/bluesnowman/fphp-saber)[![Average time to resolve an issue](https://camo.githubusercontent.com/73218978ee3cdd3fdcd4cc473a1ea85bc1ebbd53db71ce32491f3186868f2d0e/687474703a2f2f697369746d61696e7461696e65642e636f6d2f62616467652f7265736f6c7574696f6e2f626c7565736e6f776d616e2f667068702d73616265722e737667)](http://isitmaintained.com/project/bluesnowman/fphp-saber "Average time to resolve an issue")[![Percentage of issues still open](https://camo.githubusercontent.com/0788b71d6b45339b2e1d00be1b3acefe3309ae6bad20532f789a3fbbf38f78b0/687474703a2f2f697369746d61696e7461696e65642e636f6d2f62616467652f6f70656e2f626c7565736e6f776d616e2f667068702d73616265722e737667)](http://isitmaintained.com/project/bluesnowman/fphp-saber "Percentage of issues still open")[More...](https://www.openhub.net/p/fphp-saber)

### Requirements

[](#requirements)

- PHP 7.0+
- The [mbstring](http://php.net/manual/en/book.mbstring.php) extension or the [iconv](http://php.net/manual/en/book.iconv.php) extension (only if dealing with different character sets).
- The [gmp](http://php.net/manual/en/book.gmp.php) extension (only if using `IInteger\Type`).

### [Boxing](http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx)

[](#boxing)

To "box" a PHP typed primitive or object, create an instance of the respective data type using the class's `make` method. This method enforces the type by converting the value to the correct data type. If the value cannot be converted to the correct data type, an exception will be thrown.

```
$object = IInt32\Type::make(7);

```

For better performance, use the `box` method to avoid any unnecessary pre-processing that its corresponding `make` method might otherwise perform before creating the instance.

```
$object = IInt32\Type::box(7);

```

Some data types are initialized using a singleton method. For instance, the `IUnit\Type` class is initialized like so:

```
$object = IUnit\Type::instance();

```

Similarly, other data types have more specific singleton methods. Amongst these is the `ITrit` data type, which has three singleton methods for negative one, zero, and positive one.

```
$negative = ITrit\Type::negative();
$zero = ITrit\Type::zero();
$positive = ITrit\Type::positive();

```

It is recommend that you use these factory/singleton methods, when possible, instead of using the constructor to initialize a data type. This is for both conventional reasons and implementation reasons.

To "unbox" a boxed object, call the `unbox` method on the respective class to get its value.

```
$value = $object->unbox();

```

### [Fluent API](http://en.wikipedia.org/wiki/Fluent_interface)

[](#fluent-api)

Many data types allow for a fluent API; therefore, many methods can be chained together in one statement. Through the use of PHP's magical `__call` method, certain data types can access their respective module's methods as if they were instance methods. (Methods in a module are defined similarly to how [extension methods](http://msdn.microsoft.com/en-us/library/bb383977.aspx) are defined in C#.) For example, you can do the following:

```
$object = IInt32\Type::box(7)->increment()->decrement();

```

This statement is functionally equivalent to writing:

```
$object = IInt32\Module::decrement(IInt32\Module::increment(IInt32\Type::box(7)));

```

Note: this fluent API only works with methods that return `Core\Type` objects.

### Classes

[](#classes)

A `Type` class defines a lean interface for a particular type.

A `Module` class defines a set of methods that are used to process its corresponding `Type` class. All methods are static and must define for their first argument its corresponding `Type` class.

A `Utilities` class defines an assortment of methods that are related to its corresponding `Type` class. All methods are static.

An `Iterator` class defines how a collection is counted and iterated over by PHP.

### Methods

[](#methods)

In general, methods that are NOT preceded by two underscores will return a boxed object.

```
$object = IInt32\Type::box(7)->increment();

```

One notable exception to this rule is the `unbox` method.

Methods that are preceded by two underscores will return an unboxed value, which is typically a PHP typed primitive or object. This is made possible via PHP's magical `__call` method.

```
$value = IInt32\Type::box(7)->__increment();

```

This is essentially functionally equivalent to writing:

```
$value = IInt32\Type::box(7)->increment()->unbox();

```

### Variables

[](#variables)

This library has adopted the following naming conventions for certain variables:

`$c` usually represents a carried value.
`$e` usually represents an exception.
`$i`, `$j`, and `$k` usually represent an index or count.
`$n` usually represents a quantity.
`$p` usually represents a position.
`$r` usually represents a result.

`$x`, `$y`, and `$z` usually represent an object or a value.
`$xs`, `$ys`, and `$zs` usually represent a collection of `$x`, `$y`, and `$z` objects/values, respectively.
`$xss`, `$yss`, and `$zss` usually represent a collection of `$xs`, `$ys`, and `$zs` collections, respectively.

`$xi`, `$yi`, and `$zi` usually represent an iterator for a collection of `$x`, `$y`, and `$z` objects/values, respectively.
`$xsi`, `$ysi`, and `$zsi` usually represent an iterator for a collection of `$xs`, `$ys`, and `$zs` collections, respectively.

### Callables

[](#callables)

A `$closure` function does not have a predefined signature or return type; but, as a general rule, it should utilize Core\\Type objects for parameter and return types.

```
function(?Core\Type... $m) : ?Core\Type

```

An `$operator` function is used to find the result of applying an operator to one or more operands.

```
function(Core\Type $c) : Core\Type
function(Core\Type $c, Core\Type $x) : Core\Type

```

A `$predicate` function is used to find the result of performing a Boolean evaluation.

```
function(Core\Type $x) : IBool\Type
function(Core\Type $x, IInt32\Type $i) : IBool\Type

```

A `$procedure` function is used to perform an operation that does NOT return a value (even though, technically, PHP does return a `null` value by default). In cases where logic benefits to use a return statement to terminate a procedure prematurely, the return value must be either a `null` value or an `IUnit\Type` object.

```
function(Core\Type $x) : ?IUnit\Type
function(Core\Type $x, IInt32\Type $i) : ?IUnit\Type

```

A `$subroutine` function is used to perform an operation that does return a value.

```
function(Core\Type $x) : Core\Type
function(Core\Type $x, IInt32\Type $i) : Core\Type

```

A `$tryblock` function is used to process a block of code that may throw a runtime exception.

```
function() : Core\Type

```

### Choices

[](#choices)

Objects can be evaluated against each other using the `when` clause. A `when` clause is satisfied when both `x` and `y` match (i.e. when `$x->__eq($y)` evaluates to `true`). If a match is encountered, the clause will cause the `$procedure` to be executed.

```
$x = IInt32\Type::box(8);
$y = IInt32\Type::box(8);

Control\Type::choice($x)
	->when($y, function(IInt32\Type $x) {
		// passes, do something
	})
	->otherwise(function(IInt32\Type $x) {
		// skipped
	})
->end();

```

Objects can also be evaluated against each other using the `unless` clause. An `unless` clause is satisfied when both `x` and `y` do NOT match (i.e. when `$x->__eq($y)` evaluates to `false`). If the result of the match is false, the clause will cause the `$procedure` to be executed.

```
$x = IInt32\Type::box(8);
$y = IInt32\Type::box(7);

Control\Type::choice($x)
	->unless($y, function(IInt32\Type $x) {
		// passes, do something
	})
	->otherwise(function(IInt32\Type $x) {
		// skipped
	})
->end();

```

### Sequences

[](#sequences)

A list containing a sequence of numbers can be easily created by doing the following:

```
$object = IInt32\Module::sequence(IInt32\Type::zero(), IInt32\Type::box(5));

```

This means \[0..5\]. It will produce \[0,1,2,3,4,5\].

You can also generate sequences like \[0,2..10\], which will produce \[0,2,4,6,8,10\].

```
$object = IInt32\Module::sequence(IInt32\Type::zero(), ITuple\Type::box2(IInt32\Type::box(2), IInt32\Type::box(10)));

```

Similar methods exist as well for IDouble, IFloat, and IInteger.

### Exceptions

[](#exceptions)

To throw an exception, do the following:

```
$message = 'Hi, my name is :name';
$tokens = array(':name' => 'Blue Snowman');
$code = IInt32\Type::zero();
Control\Exception\Module::raise(new Throwable\UnexpectedValue\Exception(
    $message, // optional
    $tokens,  // optional
    $code     // optional
));

```

Besides using the traditional `try/catch` statement, you can use the built in `try_` control feature:

```
$either = Control\Exception\Module::try_(function() {
	// do something that might cause an exception to be thrown
});

```

This will wrap the result into an `IEither\Type`. Convention dictates that the exception will be wrapped in an `IEither\Left\Type` and a successful result will be wrapped in an `IEither\Right\Type`.

### Hierarchy

[](#hierarchy)

Below describes the relationships between data types:

```
+ Core\Type
  + Control\Type
    + Choice\Type
  + Data\Type
    + IBool\Type
    + IChar\Type
    + ICollection\Type
      + IEither\Type
        + Left\Type
        + Right\Type
      + IMap\Type
        + IHashMap\Type
      + IOption\Type
        + Some\Type
        + None\Type
      + ISeq\Type
        + IArrayList\Type
        + ILinkedList\Type
        + IString\Type
      + ISet\Type
        + IHashSet\Type
      + ITuple\Type
    + INumber\Type
      + IFloating\Type : IFractional\Type
        + IDouble\Type : IReal\Type
        + IFloat\Type : IReal\Type
      + IIntegral\Type : IReal\Type
        + IInt32\Type
        + IInteger\Type
        + ITrit\Type
      + IRatio\Type : IFractional\Type
    + IObject\Type
    + IRegex\Type
    + IUnit\Type
  + Throwable\Runtime\Exception
    + Throwable\EmptyCollection\Exception
    + Throwable\InvalidArgument\Exception
    + Throwable\OutOfBounds\Exception
    + Throwable\Parse\Exception
    + Throwable\UnexpectedValue\Exception
    + Throwable\UnimplementedMethod\Exception
    + Throwable\Unknown\Exception

```

Most data types have a module associated with it.

ICollection types also have an iterator class so that the class can be used with PHP's `foreach` loop. Because these iterator classes must conform to PHP's `Iterator` and `Countable` interfaces, methods in these classes do not necessarily conform to all of the conventions that this library otherwise uses (i.e. some non-doubly underscored methods will return PHP typed primitives instead their respective `Core\Type` objects).

### Unit Tests

[](#unit-tests)

This library provides a convenient `Makefile` for installing, updating, and uninstalling [Composer](https://getcomposer.org/) and [PHPUnit](http://phpunit.de/). Similarly, this `Makefile` can also be used to run any unit test included in this library.

To run this `Makefile`, navigate to the folder where it is located on your hard-drive and then type any of the following commands:

To install both Composer and PHPUnit:

```
make install

```

To update both Composer and PHPUnit:

```
make update

```

To uninstall both Composer and PHPUnit:

```
make uninstall

```

To run all unit tests:

```
make unit-test

```

To run just a specific group of unit tests, for example:

```
make unit-test GROUP=TypeTest

```

For more information regarding additional commands, see the [documentation](https://github.com/bluesnowman/fphp-saber/blob/master/Makefile) in the `Makefile` itself.

### Pull Requests

[](#pull-requests)

Help improve on this library. If you have a bug fix, suggestion, or improvement, please submit a pull request along with any applicable test cases.

### License

[](#license)

Copyright 2014-2016 Blue Snowman

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

###  Health Score

26

—

LowBetter than 43% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity14

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 87.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

4146d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/28607a7a4f1062e205ed2c9858fdec6f0fb855ca9ac9a6e1418367d03bbc4012?d=identicon)[bluesnowman](/maintainers/bluesnowman)

---

Top Contributors

[![ziminji](https://avatars.githubusercontent.com/u/667908?v=4)](https://github.com/ziminji "ziminji (268 commits)")[![bluetechy](https://avatars.githubusercontent.com/u/6248629?v=4)](https://github.com/bluetechy "bluetechy (38 commits)")[![bluesnowman](https://avatars.githubusercontent.com/u/1520731?v=4)](https://github.com/bluesnowman "bluesnowman (1 commits)")

---

Tags

functionalfpfphp

### Embed Badge

![Health badge](/badges/bluesnowman-fphp-saber/health.svg)

```
[![Health](https://phpackages.com/badges/bluesnowman-fphp-saber/health.svg)](https://phpackages.com/packages/bluesnowman-fphp-saber)
```

###  Alternatives

[lstrojny/functional-php

Functional primitives for PHP

2.0k7.3M48](/packages/lstrojny-functional-php)[nikic/iter

Iteration primitives using generators

1.1k5.9M38](/packages/nikic-iter)[qaribou/immutable.php

Immutable, highly-performant collections, well-suited for functional programming and memory-intensive applications.

344146.0k](/packages/qaribou-immutablephp)[magento/magento2-functional-testing-framework

Magento2 Functional Testing Framework

15511.5M30](/packages/magento-magento2-functional-testing-framework)[lambdish/phunctional

λ PHP functional library

3612.0M23](/packages/lambdish-phunctional)[crell/fp

Functional utilities for PHP 8 and later

91429.8k11](/packages/crell-fp)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
