3v4l.org

run code in 300+ PHP versions simultaneously
<?php class SinglePlaceholder { } class VariadicPlaceholder { } $PLACEHOLDER = new SinglePlaceholder(); $VARIADIC_PLACEHOLDER = new VariadicPlaceholder(); function partial(callable $in, ...$args) { $fmap = []; $partialIndex = 0; $variadic = false; foreach ($args as $k => $arg) { if ($arg instanceof SinglePlaceholder) { $fmap[$partialIndex++] = $k; } if ($arg instanceof VariadicPlaceholder) { $variadic = true; if ($k !== count($args) - 1) { throw new ArgumentCountError('Only the last parameter may be a variadic placeholder'); } $fmap[$partialIndex++] = $k; } } return static function (...$partialArgs) use ($in, $args, $fmap, $variadic) { $expectedCount = count($fmap); if ($variadic) { $expectedCount--; } if (count($partialArgs) < $expectedCount) { throw new ArgumentCountError('Expected ' . count($fmap) . ' only received ' . count($partialArgs)); } foreach ($partialArgs as $pIndex => $pValue) { $targetSlot = $fmap[$pIndex] ?? null; if ($targetSlot === null) { if ($variadic) { $args[] = $pValue; } else { throw new ArgumentCountError('Too many arguments without a variadic placeholder'); } } else { $args[$targetSlot] = $pValue; } } return $in(...$args); }; } function foo($a, $b, $c, $d, $e) { var_dump($a, $b, $c, $d, $e); } print_r(partial('foo', 1, $PLACEHOLDER, 3, $PLACEHOLDER, 5)(2, 4)); print_r(partial('foo', $VARIADIC_PLACEHOLDER)('a', 'b', 'c', 'd', 'e')); print_r(partial('foo', 1, 2, 3, 4, 5)()); $chain = partial('foo', $VARIADIC_PLACEHOLDER); $chain = partial($chain, 1, $VARIADIC_PLACEHOLDER); $chain = partial($chain, 2, $VARIADIC_PLACEHOLDER); $chain = partial($chain, 3, $VARIADIC_PLACEHOLDER); $chain = partial($chain, 4, $VARIADIC_PLACEHOLDER); $chain = partial($chain, 5, $VARIADIC_PLACEHOLDER); print_r($chain());

preferences:
26.21 ms | 402 KiB | 5 Q