Expression code blocks

From: Date: Fri, 16 Jun 2023 19:23:11 +0000
Subject: Expression code blocks
Groups: php.internals 
Request: Send a blank email to internals+get-120606@lists.php.net to get a copy of this message
Hello list, I don't know if something like this was already proposed in the past, I did not find anything. Sometimes it would be nice to have a code block inside an expression, like this: public function f(string $key) { return $this->cache[$key] ??= { // Calculate a value for $key. [...] return $value; } } Currently, to achieve the same, we have two options which both add overhead both in code verbosity and in performance: 1. Call another method or closure after the ??=. 2. Use if (isset(...)) instead of the ??= shortcut. This results in repetition of other parts of the expression, because the if/else cannot be inside the expression. E.g. this is option 1 with a closure: public function f(string $key) { return $this->cache[$key] ??= (function () use ($key) { // Calculate a value for $key. [...] return $value; })(); } Option 1 with a real method would look like this: public function f(string $key) { return $this->cache[$key] ??= $this->calc($key); } private function calc(string $key) { // Calculate a value for $key. [...] return $value; } The {} syntax seems like the most obvious choice at first, but I think it would not work. Statement groups with curly brackets are already possible right now, see https://www.php.net/manual/en/control-structures.intro.php, but they are not really useful for anything: They cannot be used as expressions, they don't have their own return value, and they don't isolate their variables. Another option would be a special keyword before the curly block. We could introduce a new keyword like expr, or use an existing one like fn. $x = 4 + fn {return 3;}; // or $x = 4 + expr {return 3;} The compiler/interpreter could either convert the block into a closure, or treat it as a new language feature, which might bring performance benefits. Any thoughts? -- Andreas

« previous php.internals (#120606) next »