On Thu, Apr 13, 2023, at 3:04 PM, Zoltán Fekete wrote: > Hey guys! > >> On 13. Apr 2023, at 16:28, Robert Landers <landers.rob...@gmail.com> wrote: >> >> I'd be down for implementing this in a heartbeat if we >> >> $a = Closure::fromCallable(static fn () => $this->getId()); >> $b = Closure::bindMany($items); // executes `bind` on each item in the >> array, returning an array of closures >> foreach($b as $callback) { >> $callback(); >> } > > Personally I find it a bit inconvenient, and also: won’t in this case > all the closure instance be created so space allocated for them? > >> or something like that. My biggest thing is that there's no real way >> to save much on typing this out. Unless you are doing something fairly >> exotic, you only save a few characters. That's why I said its a lot of >> work for not much benefit. I could be totally wrong though because I, >> personally, do run into wanting this feature several times a year. > > I can only tell my opinion as I also came across the same case / > problem. But what if I do the following: > > ``` > $items = [new Verification(“1”), new Verification(“2”))]; > > $ids = array_map(NotVerification::getId(…), $items); // ofc I did that > so my fault but not allowing something to be done… I think it’s half > win. But it’s very misleading > ``` > > Additionally: if I don’t have the class imported and don’t even need > it, than it has to be. > > Essentially what we only need in the first parameter is the method name > that should be called. > > I cannot really assess how big of a hassle it would be, but what I > personally think that it look nice is something like this: > > ``` > class Verification > { > public function __construct(private string $id) {} > > public function getId(): string > { > return $this->id; > } > > public static function getIdAbs(self $instance) { > return abs($instance->id); > } > } > > $items = [new Verification(“1”), new Verification(“2”))]; > > array_map($$->getId(…), $items); > > array_map($$::getIdAbs(…), $items); > ``` > > This way the class does not have to be imported. Later one might be > able to add additional parameters even. > > ``` > class Verification > { > // […] > > public static function getIdAbs(self $instance, array $idMap) { > // do something with the $idMap > return abs($instance->id); > } > } > > // […] > > array_map($$::getIdAbs(…, $idMap), $items); > > ``` > > I know this might be a little more exotic. But it is very straight > forward for static analysis tools. And no import has to be done for > classes.
I believe the fancy academic name for what we're discussing here is "lenses", and I agree that they'd be very useful. I currently use a user-space wrapper like so: function prop(string $prop): \Closure { return static fn (object $o): mixed => $o->$prop; } function method(string $method, ...$args): \Closure { return static fn (object $o): mixed => $o->$method(...$args); } Which lets me do this: $parentNames = pipe($vals, amap(method('getParent')), amap(prop('name')), ); But I really don't like the stringy method and property names. The T_BLING (that is the only name I will allow for $$) marker has been discussed on and off a few times over the years, I think first in Sara's original pipes proposal many years ago. I was actually going to suggest the same in this thread before I saw you did. :-) More abstractly, $$ meaning "the only obvious value in context" has potential, but also risk, because "obvious" is not always obvious. I do think it's an area to explore, though, and would definitely help with functional style code that relies heavily on closures. --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php