rfc:closures_in_const_expr

This is an old revision of the document!


PHP RFC: Support Closures in constant expressions

Introduction

Proposal

It shall be legal to include Closures in constant expressions. This includes:

  • Attributes.
  • Default Values of Properties, Parameters, and static variables.
  • Constants and Class Constants.

Constraints

Closures placed in constant expressions are subject to the following constraints:

  • They must not include variables from the surrounding scope using use($foo, $bar), because constant expressions are evaluated at compile time, thus there is no surrounding scope. This also means that short closures (arrow functions) are not supported, because they perform implicit capturing.
  • They must be static (and thus they must not access $this). Semantically $this would only be well-defined in default values for properties and possibly attributes, but this would require reevaluating the Closure for each object / attribute instance, which would be different to existing constant expressions which are only evaluated once. For this reason this is left to future scope.

Use Cases

Custom field validation for an attribute-based object validation library:

class Locale
{
    #[Validator\Custom(static function (string $languageCode): bool {
        return \preg_match('/^[a-z][a-z]$/', $languageCode);
    })]
    public string $languageCode;
}

Testcase generation for a testing library:

class CalculatorTest
{
    #[Test\CaseGenerator(static function (): iterable {
        for ($i = -10; $i <= 10; $i++) {
            yield [$i, $i, 0];
            yield [$i, 0, $i];
            yield [0, $i, ($i * -1)];
        }
    })]
    public function testSubtraction(int $minuend, float $subtrahend, int $result)
    {
        \assert(Calculator::subtract($minuend, $subtrahend) === $result);
    }
}

Backward Incompatible Changes

None. Placing Closures into constant-expressions previously resulted in a compile-time error.

Nevertheless, as with every RFC that changes what previously was a compile-time error to be valid PHP code, this RFC requires changes to static analyzers and IDEs to correctly understand the semantics of the code and not erroneously report errors.

Proposed PHP Version(s)

Next PHP 8.x (8.5).

RFC Impact

To SAPIs

None.

To Existing Extensions

None.

To Opcache

Opcache needs to be adjusted to correctly store Closures in constant expressions in SHM. The PoC PR includes the necessary Opcache changes and passes all tests with Opcache / JIT enabled.

New Constants

None.

php.ini Defaults

None.

Open Issues

n/a

Unaffected PHP Functionality

List existing areas/features of PHP that will not be changed by the RFC.

This helps avoid any ambiguity, shows that you have thought deeply about the RFC's impact, and helps reduces mail list noise.

Future Scope

  • Support non-static Closures.
  • Support first-class callables.

Proposed Voting Choices

Support Closures in constant expressions as proposed?
Real name Yes No
alcaeus (alcaeus)  
beberlei (beberlei)  
brzuchal (brzuchal)  
bwoebi (bwoebi)  
derick (derick)  
galvao (galvao)  
girgias (girgias)  
jbnahan (jbnahan)  
kguest (kguest)  
malferov (malferov)  
mbeccati (mbeccati)  
nielsdos (nielsdos)  
ramsey (ramsey)  
sergey (sergey)  
theodorejb (theodorejb)  
timwolla (timwolla)  
Final result: 16 0
This poll has been closed.

Patches and Tests

Implementation

n/a

References

Rejected Features

n/a

rfc/closures_in_const_expr.1729846666.txt.gz · Last modified: 2024/10/25 08:57 by timwolla