Re: [Discussion] Revisiting typed closures

From: Date: Wed, 01 Jul 2026 19:47:40 +0000
Subject: Re: [Discussion] Revisiting typed closures
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-131674@lists.php.net to get a copy of this message
On Wed, Jul 1, 2026 at 5:43 PM Matheus Martins <mathrm@gmail.com> 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

« previous php.internals (#131674) next »