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

Reply via email to