Hi all, śr., 22 kwi 2020 o 16:29 Dan Ackroyd <dan...@basereality.com> napisał(a):
> On Tue, 21 Apr 2020 at 14:08, moliata <moli...@protonmail.com> wrote: > > > > > I wanted to ignite a friendly discussion whether > > PHP should allow typed callable properties. > > IMO no. > > I agree, a callable brings as much information as a resource type - you know the type but are unable to use it without additional information. > Trying to fix the problems with callables would be a huge amount of > work, and not actually give that much benefit. Even just documenting > the problems with callables* is a non-trivial amount of work, and I > suspect there are many horrors lurking with the SPL code related to > them. > > > I believe we should look into... > > I'm pretty sure that choosing a different problem to solve that: > > * would be easier to solve. > * provide more benefit in the long term. > * not require breaking a lot of userland + internal code immediately, > but instead allow for migration over a longer period. > I was pinged by Dan with typedef topic nearly 3 weeks ago and then started thinking of the way to define callable types with some initial implementation. I chose pattern known from other languages like C# where there are types known as delegates. And so far got to the last line of snippet below where I have to figure out some clever type checking with closure: delegate Reducer (?int $sum, int $item = 0): int; class Foo implements Reducer { public function __invoke(?int $sum, int $item = 0): int { return ($sum ?? 0) + $item; } } function reduce(Reducer $reducer) { var_dump($reducer(0, 5)); } reduce(new Foo()); reduce(fn(?int $sum, int $item = 0): int => 8); The delegate declaration resolves to an interface with __invoke method which therefore can be easily checked when the invokable object passed and that information can be easily cached. Probably it can be cached also for closures and functions but didn't get so far with the implementation yet. I was also asked why not a general use typedef which can be used to alias any kind of type not only a callable. But the reason why I chose delegates was that IMO typedef is more like an aliasing mechanism, which means all that is possible to be aliased should also be possible to be unaliased and pasted in all type constraints used in function/method parameters as well as class properties. Meaning if we allow: typedef reducer = callable(?int $sum, int $item = 0): int; We should also allow: function(callable(?int $sum, int $item = 0): int $reducer) {} Which IMO looks too verbose and that's why I think a delegate might be a good idea as a way to provide callable types checking. Any thoughts are highly appreciated! Cheers, Michał Brzuchalski