8

関数のアドバイスメソッドの組み合わせに似たシステムを作成する際に、スタックを吹き飛ばしたくないと思っていました。これには、ツリー トラバーサル (私の実装では)、条件付き再帰などが含まれます。再帰をループに変換するために使用できる数少ない方法の 1 つはトランポリンです。これを試してみたところ、たとえば実装する必要があることがわかりました。短絡ブール式の評価。要するに、トランポリンと継続の組み合わせを実装しました。現在、この構造が存在するかどうか、およびその名前が何であるかを調べようとしています-そのような既存の構造を見つけることができなかったからです。

私の実装 - 手動スタック処理によるバウンス評価:

function immediate($bounce, $args)
{
    $stack = array($bounce->run($args));

    while ($stack[0] instanceof Bounce) {
        $current = array_pop($stack);
        if ($current instanceof Bounce) {
            $stack[] = $current;
            $stack[] = $current->current();
        } else {
            $next = array_pop($stack);
            $stack[] = $next->next($current);
        }
    }

    return $stack[0];
}

バウンス クラス:

class Bounce
{
    protected $current;
    protected $next;

    public function __construct($current, $next)
    {
        $this->current = $current;
        $this->next = $next;
    }

    public function current()
    {
        $fn = $this->current;
        return $fn();
    }

    public function next($arg)
    {
        $fn = $this->next;
        return $fn($arg);
    }
}

そして、例として、短絡 AND 実装 (つまり JavaScript 内first(args) && second(args))。$firstおよびもs を$second返す関数です。Bounce

return new Bounce(
    function () use ($first, $args) {
        return $first($args);
    },
    function ($return) use ($second, $args) {
        if (!$return) {
            return $return;
        }
        return new Bounce(
            function () use ($second, $args) {
                return $second($args);
            },
            null
        );
    }
);

これにより、一般的な再帰が可能になり、通常の関数呼び出しごとに約 3 つの関数呼び出しのオーバーヘッドが発生します (ただし、可変反復回数の一般的なケースでは、記述するのが非常に面倒であり、「遅延再帰」が必要です)。

そのような構造を見た人はいますか?

4

0 に答える 0