Re: [PHP-DEV] [Discussion] Revisiting typed closures

[email protected] (Osama Aldemeery)
Newsgroups php.internals
Message-ID <CABE7Eu9KVPw3cjZwpYkEMOQSqf+35kmcT+6X_Ev8UTqWGvA+OA@mail.gmail.com>
On Wed, Jul 1, 2026 at 5:43 PM Matheus Martins <[email protected]> wrote:

> Hello internals,
>
> I would like to revisit the idea of giving closures a typed call signature.
>
> e.g. Closure(int, string): array -- enforced at the point a value crosses a
> type boundary (an argument, a return, a property), the same places any
> other
> type is checked.
>
> Today a closure can only be typed as Closure or callable, neither of which
> says anything about its parameters or return, even though that information
> is
> right there.
>
> I know this is not new ground: Callable Prototypes was declined in 2016,
> and
> Garfield and Grekas shared two further RFCs in 2023 -- Structural Typing
> for
> Closures, and Allow Closures to Declare Interfaces they Implement -- both
> still
> in draft.
>
> Before taking it further, I would like to know whether closure typing
> is still considered worth pursuing -- or whether the topic is now regarded
> as
> settled.
>
> References:
>
> - https://wiki.php.net/rfc/callable-types
> - https://wiki.php.net/rfc/structural-typing-for-closures
> -
> https://wiki.php.net/rfc/allow-closures-to-declare-interfaces-they-implement
>
> Thanks.
>

Hi Matheus,

This is something I care about and took a real run at recently, but I came
at it from a different angle, an `Invokable` marker interface PR
<https://github.com/php/php-src/pull/21574> in which
Gina pointed me at function types as the proper solution to what I was
trying to address.
I was convinced, withdrew the PR, and started exploring the same thing you
are exploring now.

So let me hand you what I ran into, in case it helps...

Two things to put in your bag before you invest:

   1. The syntax collides at the lexer. `Closure(int): array` can't be
   tokenized cleanly, because `(int)` is a cast token (same for `(string)`,
   `(array)`, and so on).
   It's been that way for years, and the one attempt to fix it (PR
   https://github.com/php/php-src/pull/1667) was rejected as a token-stream
   BC break.
   So the natural spelling is, unfortunately, the engine-hostile one.
   2. There's a single `Closure` class (Ilija's point here:
   https://externals.io/message/120083#120099), so `Closure(int, string):
   array` isn't a subtype you can instanceof...
   it has to be checked another way at the boundary, which is where the
   usual per-boundary runtime-cost concern comes in.

Hope you find that useful.

Best,
Osama
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.