php-scalar-objects
php-scalar-objects copied to clipboard
Member method partial application
One of the nice elements of PHP's scalar functions being represented as functions instead of member methods is that they allow for partial application. This is less intuitive with member methods since the eventual callee needs to provide a context and possibly additional arguments.
Functional Example
//Right handed partial application
function right_partial = ($callable, ...$rightArgs) {
return function (...$leftArgs) use ($callable, $rightArgs) {
return call_user_func_array($callable, array_merge($leftArgs, $rightArgs));
};
}
$strings = ['asfd', 'sdfg', 'setw', 'uyts', 'ghjk'];
// Partial application
array_map(right_partial('str_pos', 's', 0), $strings); //[1, 0, 0, 3, false]
// Inline
array_map(function ($str) {
return str_pos($str, 's', 0);
}, $strings); //[1, 0, 0, 3, false]
Object Example
For member methods a special arrow function needs to exist to support these declarative techniques:
//Left handed partial application
function arrow ($method, $leftArgs) {
return function ($context, $rightArgs) use ($method, $leftArgs) {
return call_user_func_array([$context, $method], array_merge($leftArgs, $rightArgs));
}
}
// Partial application
$strings->map(arrow('indexOf', 's', 0)); //[1, 0, 0, 3, false]
// Inline
$strings->map(function ($str) {
return $str->indexOf('s', 0);
}); //[1, 0, 0, 3, false]
Sugar
It would be nice if this could be sugared and provided at the language level. Options:
$strings->map(_->indexOf('s', 0)); //[1, 0, 0, 3, false]
$strings->map($->indexOf('s', 0)); //[1, 0, 0, 3, false]