Hi Khaled
On Fri, Dec 26, 2025 at 4:41 PM Khaled Alam <[email protected]> wrote:
> I'd like to request RFC karma to publish an RFC proposing a native "defer"
> feature and gather community feedback.
RFC karma was granted. Good luck!
> Inspired by Zig's "defer", it schedules a block to run when the current
> function exits (return, exception, or natural end), executed in LIFO order,
> aimed at safer cleanup without repetitive try/finally scaffolding.
I've already shared some technical feedback on the PR, let me reiterate here.
I think it's important that defers are executed on scope-end, rather
than function-end. For functions with many loop iterations, this would
otherwise schedule tons of defer executions for resources that could
have long been released. Relatedly, the way this is currently
implemented, defer referencing changing variables is ineffective. For
example:
function test() {
for ($i = 0; $i < 10; $i++) {
$resource = allocate_some_resource();
defer { close($resource); }
}
}
is roughly equivalent to:
function test() {
for ($i = 0; $i < 10; $i++) {
$resource = allocate_some_resource();
}
for ($i = 0; $i < 10; $i++) {
close($resource);
}
}
Which is obviously incorrect, closing the same resource over and over
again. Executing at end-of-scope would mostly resolve this issue.
On a more technical level, the implementation mostly mirrors
FAST_CALL/FAST_RET used for finally. This seems unnecessary.
FAST_CALL/FAST_RET also already handle exceptions, which your
implementation is currently missing. I believe `defer { <code> } <code
until end of scope>` could mostly be sugar for `try { <code until end
of scope> } finally { <code> }`.
Given those things are so similar, the RFC should make it clear why a
new syntax is beneficial. I suppose it puts the alloc/free code
lexically closer together, which might be worth it for some people.
Ilija