Skip to content

Member method partial application #13

@eborden

Description

@eborden

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]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions