rfc:partial_function_application

PHP RFC: Partial Function Application

Introduction

Partial function application is the process of binding only some of the arguments to a function call and leaving the remainder to be bound a later point. In PHP this would be done by a closure.

Proposal

Partial function application is done by using the underscore symbol (_) as a parameter to a function or method call. Instead of calling the function instead a closure will be created and the parameters which are not underscores will be bound. The arity of the closure is the number of underscores used. Underscores can be used in any parameter position. The way the arguments and closed-over variables are bound is determined by the definition of the function that is partially applied; if the function takes that position by reference then the closure will also take that position by reference (or use by reference if applicable). The return type of the closure is also the same as that of the function call it is mirroring.

function f($value, &$ref) {}
 
$array = ['arg' => 0];
 
// the following two groups of statements are equivalent
f(_, $array['arg']);
 
$ref = &$array['arg'];
function($value) use(&$ref) {
    return f($value, $ref);
};

Backward Incompatible Changes

A constant of the name “_” will now be a redefinition, which will emit a warning and leave the original value intact. This effectively means you can no longer declare a constant with that name.

Open Issues

Make sure there are no open issues when the vote starts!

PHP Version

This RFC targets 7.2 or 8.0.

Voting

This RFC requires a 2/3 vote in the affirmative to pass. It will be a simple yes/no vote on whether to include partial function application.

Future Scope

This feature would be particularly useful if we ever created a piping operator. Instead of requiring the $$ symbol for the location of the left-hand side of the |> to be sent to we can instead create a closure and send the result as the only parameter:

// this
$ret = scandir($arg)
    |> array_filter($$, function($x) { return $x !== '.' && $x != '..'; })
    |> array_map(function ($x) use ($arg) { return $arg . '/' . $x; }, $$)
    |> getFileArg($$)
    |> array_merge($ret, $$);
 
// becomes:
$ret = scandir($arg)
    |> array_filter(_, function($x) { return $x !== '.' && $x != '..'; })
    |> array_map(function ($x) use ($arg) { return $arg . '/' . $x; }, _)
    |> getFileArg(_)
    |> array_merge($ret, _);

This makes the |> much easier to explain and understand when compared with the current version that uses $$.

Patches and Tests

Currently no patch.

References

Links to external references, discussions or RFCs

rfc/partial_function_application.txt · Last modified: 2017/09/22 13:28 (external edit)