Hi > There is one loophole, in that an interface may require an __invoke() > method: > > interface TwoInts > { > public function __invoke(int $a, int $b): int; > } > > I was playing around with the code and parser for this in 2020 but my idea was to introduce a new syntax that is inspired by C# - Delegates [1]
delegate Reducer (?int $sum, int $item = 0): int; class Foo implements Reducer { public function __invoke(?int $sum, int $item = 0): int { } } function reduce(Reducer $reducer) { var_dump($reducer(0, 5)); } reduce(new Foo()); reduce(fn(?int $sum, int $item = 0): int => 8); At the same time, I assumed structural typing for closures would be used. I assumed the delegate will resolve into interface Reducer { public function __invoke(?int $sum, int $item = 0): int {} } I also noticed that once checked closure doesn't have to be checked against the argument types and return type because it won't change which gives some possibility to cache this type check. > The usual discussion has involved a way to specify a callable type's > signature, like so: > > function takeTwo(callable(int $a, int $b): int $c) > { > return $c(1, 2); > } > > But that runs quickly into the problem of verbosity, reusability, and type > aliases, and the discussion usually dies there. > > This is why initially I thought about Delegates as in C# there are not type aliases. The delegate essentially resolves to an interface with `__invoke(?int $sum, int $item = 0): int` method. > ### Structural typing for closures > > The third option would necessitate having similar logic in the engine to > the first. In this case, we take a "structural typing" approach to > closures; that is, "if the types match at runtime, it must be OK." This is > probably closest to the earlier proposals for a `callable(int $x, int $y): > int` syntax (which would by necessity have to be structural), but > essentially uses interfaces as the type alias. > > function takeTwo(TwoInts $c): int > { > return $c(1, 2); > } > > $result = takeTwo(fn(int $x, int $y): int => $x + $y); > I'd love to see this happening. [1] https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/delegates/ Cheers, Michał Marcin Brzuchalski