rfc:closure_self_reference

PHP RFC: Closure self reference

Introduction

Currently, the main way used to call a closure from within that closure, is to bind a variable by reference into the closure, when the closure is created.

However this can lead to shenanigans:

$fibonacci = function (int $n) use (&$fibonacci) {
    if ($n === 0) return 0;
    if ($n === 1) return 1;
    return $fibonacci($n-1) + $fibonacci($n-2);
};
 
echo $fibonacci(10). "\n";
$this_is_the_original_fibonacci = $fibonacci;
// ... many lines of code here
$fibonacci = function (int $n) { return rand(0, $n); };
// ... many lines of code here
 
echo $this_is_the_original_fibonacci(10). "\n";

i.e. a change to the variable outside the closure has modified the behaviour of the closure. That a closure can change behaviour like this violates the Principle of least astonishment

Proposal

Allow closures to be aliased to a variable that can be used within the closure:

$fibonacci = function (int $n) as $fibonacci {
    if ($n === 0) return 0;
    if ($n === 1) return 1;
    return $fibonacci($n-1) + $fibonacci($n-2);
};

Backward Incompatible Changes

None known.

Proposed PHP Versions

8.1

RFC Impact

To Opcache

Unknown.

Future Scope

Questions

Proposed Voting Choices

Accept this RFC and make it possible to reference a closure from within itself using `as $variable` ? Yes/no.

Patches and Tests

Links to any external patches and tests go here.

Implementation

None yet.

References

Links to external references, discussions or RFCs

Rejected Features

Keep this updated with features that were discussed on the mail lists.

rfc/closure_self_reference.txt · Last modified: 2020/11/18 21:30 by danack