Re: First-class callable partial application

From: Date: Fri, 17 Mar 2023 01:50:50 +0000
Subject: Re: First-class callable partial application
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-119733@lists.php.net to get a copy of this message
> On 17 Mar 2023, at 05:33, Larry Garfield <larry@garfieldtech.com> wrote: > > On Thu, Mar 16, 2023, at 4:14 AM, Rowan Tommins wrote: >>> On 15/03/2023 21:12, Dan Ackroyd wrote: >>> Would it be desirable to split those two things into two separate >>> RFCs, by having the first RFC not have native syntax support, but >>> instead another static method on Closure? e.g. something like: >>> >>> Closure::partial($callable, array $position_params, array >>> $named_params): Closure {} >> >> >> Hm... now we have the first-class callable syntax, making it an instance >> method on Closure would allow this: >> >> $mapFoo = array_map(...)->partial([$foo]); >> $filterFoo = array_filter(...)->partial([1 => $foo]); >> >> Which could copy over the full signature, so be equivalent to this: >> >> $mapFoo = static fn(array ...$arrays): array => array_map($foo, ...$arrays); >> $filterFoo = static fn(array $array, int $mode = 0): array => >> array_filter($array, $foo, $mode); >> >> While being a similar length to a much less rich version: >> >> $mapFoo = fn($array) => array_map($foo, $array); >> $filterFoo = fn($array) => array_filter($array, $foo); > > Fascinating! I... don't know if we considered something like that or not 3 years ago. > It's been a while. > > It's definitely not as nice as the integrated syntax, but it does have the advantage of > the implementation almost certainly being rather pedestrian in comparison. That approach would > favor left-to-right application, but not force it, which is probably sufficient. > > As a thought experiment, if we had that syntax and functions that were designed to be used with > them, it would look like so: > > function amap(callable $c, iterable $it) { ... } > function implode(string $sep, iterable $it) { ... } > function length(string $s) { ... } > > $arr = [1, 2, 3]; > > $a2 = amap(...)->partial(chr(...))($arr); > > $str = implode(...)->partial(',')($a2); > > Or, if combined with pipes: > > $size = $arr > |> amap(...)->partial(chr(...)) > |> implode(...)->partial(',') > |> length(...); > > Which... is not terrible, especially as it doesn't preclude using higher order functions > for more control. > > We would likely want partial() to accept positional args (left to right) and named args. And > I'm more than happy to say now that the capture is only by value, ever. > > I wonder if there's a shorter name we could use than "partial" to make it more > readable? Or perhaps an operator that applied only to closure objects? > > --Larry Garfield > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > It’s not shorter than “partial” but given “bindTo()” exists, “bindArgs()” is at least clear about what it’s doing. Cheers Stephen

« previous php.internals (#119733) next »