PHP 5.6 の新機能を使って関数を合成する関数を実装する

PHP で合成関数を実現するライブラリは無いものか、と思って探したところ見つからなかったので、[yuyat\compose](https://github.com/yuya-takeyama/compose) というのを作ってみました。
が、いざ Packagist に submit しようとしたところ、「似たような名前のライブラリあるよ?」として [igorw\compose](https://github.com/yuya-takeyama/compose) をサジェストしてくれました。
思い切り車輪の再発明をしてしまいました...

ソースを眺めたところやっていることはほとんど同じですが、`igorw\compose` は PHP 5.3 でも動くような実装になっていました。
せっかくなので、`yuyat\compose` は PHP 5.6 の新機能の実験場にしてみることにしました。

## yuyat\compose の実装

現時点で最新版の実装です。
ライブラリ本体としてはこれで全てです。
https://github.com/yuya-takeyama/compose/blob/186a04d91c6dd7db86c7683e96bb1f5fff536bab/src/compose.php

```php
<?php
namespace yuyat;

function compose(callable ...$functions)
{
    if (count($functions) < 2) {
            throw new \InvalidArgumentException('at least two functions are required');
    }

    $initial = array_shift($functions);

    return array_reduce($functions, function ($f, $g) {
        return function (...$args) use ($f, $g) {
            return $f($g(...$args));
        };
    }, $initial);
}

function pipeline(callable ...$functions)
{
    return compose(...array_reverse($functions));
}
```

## 使い方

`yuyat\compose` を使うと、以下のように、複数の関数を組み合わせて、スペース区切りの文字列を lowerCamelCase に変換するする関数を作ることができます。

```php
<?php
use function yuyat\compose;

$splitAsWords = function ($str) {
    return \preg_split('/\s+/u', $str);
};
$camelizeWords = function ($words) {
    return \array_map('ucfirst', $words);
};
$join = function ($words) {
    return \join('', $words);
};
$lowerCamelize = compose('lcfirst', $join, $camelizeWords, $splitAsWords);

echo $lowerCamelize('foo bar baz'); // => "fooBarBaz"
```

`yuyat\pipeline` という関数もあって、こちらは合成した関数の適用順が `yuyat\compose` の逆になっています。
コード上で読み下せる順番で適用されるので、こちらの方が読みやすいかもしれいません。

# PHP 5.6 の新機能

`yuyat\compose` のなかで使ったものを紹介します。
より詳細な情報については以下のページを参照してください。

http://php.net/manual/en/migration56.new-features.php

## Variadic functions via ... (可変長引数のための構文)

可変長引数自体は、これまでも `func_get_args()` 等を使って実現できましたが、専用の構文が用意されました。
以下のような関数を定義することで、`$args` には引数の `array` がセットされるようになります。

```php
function f(...$args) {
}
```

また、タイプヒンティングにも対応しています。
以下の場合は、`$args` 内の全ての引数が `callable` である必要があります。

```php
function f(callable ...$args) {
}
```

これまでは可変長引数を使用した場合、型チェックは自前で実装する必要がありましたが、全ての型が同一であり、かつスカラ型でない、という前提においてはタイプヒンティングの恩恵を受けられるようになりました。

なお、HHVM でも Variadic functions には対応していますが、タイプヒンティングの併用をすることは[できないようです。](https://github.com/facebook/hhvm/blob/8eb21c3401a17b9b41b7339a912f38d124760f3d/hphp/compiler/parser/parser.cpp#L1185)

全ての引数が同一の型である以上は、静的な解決ができそうな気はしますが、いずれ実装されるものなのかどうか気になるところではあります。

## Argument unpacking via ... (引数展開のための構文)

Variadic functions の対になるような機能です。

以下のように関数呼び出しを行うと、

```php
$args = [1, 2, 3];
f(...$args);
```

以下のように実行されるようになります。

```php
f(1, 2, 3);
```

これまでは `call_user_func_array` 等を使って実現していましたが、より直感的な専用の構文が用意された形です。

また、展開される引数としては、`array` だけでなく `Traversable` インターフェイスを実装したオブジェクトも使用可能です。

## use function (名前空間内関数のインポート)

これは README 中の Usage として使っていますが、名前空間内のクラスだけでなく、関数もインポートできるようになりました。

以下のように記述すると、

```php
use function yuyat\compose;
```

`yuyat\compose` を、単に `compose` として呼び出すことができます。

また、以下のように別名を作ることも、クラスと同様にできます。

```php
use function yuyat\compose as c;
```

# まとめ

これまでの不可能を可能にしたような大きな変更ではないものの、着実に使いやすい言語に進化していると思いました。
ZendEngine 以外の処理系の追随も気になるところです。