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

Reply via email to