Hello, thank you for expanding on your comparison of callables to resources. I didn't completely understand what you meant but now I do.
Speaking of "dynamic" callables - this is also one of the reasons as to why I believe we shouldn't wait for typedefs and should allow properties to be typed as callable (just like parameters/return type). Don't get me wrong, I fully agree that we should have more strict callables and an ability to specify their signatures if they are static (in a sense that they don't change) and not dynamic. But in cases like the one I mentioned, all we can do is specify that we accept any callable. Best regards, Benas Seliuginas ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Wednesday, April 22, 2020 8:39 PM, Michał Brzuchalski <michal.brzuchal...@gmail.com> wrote: > Hi Benas, > > my responses below. > > śr., 22 kwi 2020 o 19:17 moliata <moli...@protonmail.com> napisał(a): > >> Hello, >> >> thank you for an opinion as well! While I do fully agree that callable type >> needs to be improved with features such as typedefs, I found a couple of >> problems in your response. >> >> First of all, I wouldn't say that the callable type provides little-to-no >> information like the resource type. A resource can only be made by specific >> functions such as `fopen()` and are bound to specific use >> cases/implementations >> e. g. MySQL resources are only for MySQL database access. Meanwhile, >> callables >> can be made "freely" (couldn't find a better word :-)) like integers or >> booleans and also in some cases don't have an exact function signature. One >> such example I mention in the next paragraph. > > I only said that it brings as much value as a resource type in usage context. > > Given a resource type constraint on function argument doesn't say anything to > you > as a consumer, you cannot just use that resource without knowledge of its type > the only thing you could do is calling a get_resource_type(resource > $resource) function. > > The same applies to callable, given callable like: 'strtolower', > [DateTimeImmutable::class, 'createFromFormat'] > or fn(int $x): $x*2; and when that came to your function with callable type > constraint > you also don't know how to use it without some reflection inspection cause > the type doesn't bring much value. > > While fulfilling for eg. delegate gives you guarantee that when a > callable/closure is passed it matches > your expectations and you can use it right away without reflection > inspections. > You no longer need additional data to use the variable which applies to > callable and resource as well. > >> Speaking of a snippet you showed, I'm not sure how that implementation would >> work with "dynamic" callables. For example let's assume we have a framework >> that allows registering routes with placeholders to controllers, like this: >> `$router->register('/post/{id}', [$controller, 'show']); // this would pass a >> single parameter to the callable` >> `$router->register('/user/{id}/post/{id}', [$controller, 'showFromUser']); // >> this would pass two parameters to the callable` >> ...in this case, we can't know how many placeholders/parameters a function >> can >> have as that depends on how many placeholders are in the string. A framework >> can only resolve these at runtime. > > True. In this case, it'd be hard to create a static constraint for > callable/closure check > but actually this is not the case we're looking for. Things where mentioned > delegate > match perfectly is the places where your expectations to the callable/closure > type > are static and known at the time when writing code. > > Given that in a situation when the input and the output types are known this > would bring the benefit of runtime check before use. > > Cheers, > Michał Brzuchalski