Hi Andreas

On Fri, Jun 16, 2023 at 9:23 PM Andreas Hennings <andr...@dqxtech.net> wrote:
>
> 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;
>     }
> }

This has been discussed a few years back when match expressions were
proposed. I originally wanted to include support for code blocks along
with expressions to offer a more complete alternative to switch
statements. The other major use-case for block expressions are arrow
functions.

Unfortunately, a general solution seems suboptimal due to the subtle
semantic differences. See this message for my detailed thought
process.

https://externals.io/message/109941#109947

I believe it would be best to address blocks for match arms and arrow
functions separately.

I don't believe blocks for general expressions are that useful in PHP
due to the lack of block scoping. Your suggestion to make the block a
separate closure could avoid that (as well as the optimizer issue
mentioned below) but comes with new issues, like making modification
of captured values impossible without by-ref capturing. It seems
confusing that fn {} is auto-executed while fn() {} isn't, as the
former looks like a shortened version of the latter. fn() => fn {}
would also look quite weird. match ($x) { 1 => fn {} } seems ok,
except for being somewhat lengthy.

On another note, the vote for blocks in short closures has failed
lately (https://wiki.php.net/rfc/auto-capture-closure).

The message above also addresses the syntax ambiguity you mentioned.
The {} syntax would be unambiguous in the most useful contexts (e.g.
function parameters, match arms, arrow function bodies, rhs of binary
operators, etc.). It is ambiguous in the general expression context
due to expression statements (statements containing a single
expression followed by `;`), where it's unclear (without lookahead)
whether the `{` refers to a statement block or a block expression.
Replacing all statement blocks with block expressions comes with the
added difficulty of allowing to omit the `;` of block expressions in a
expression statement.

I remember there also being issues with the optimizer (related to
https://www.npopov.com/2022/05/22/The-opcache-optimizer.html#liveness-range-calculation).
The details went over my head at the time.

I'm interested in picking this back up at some point, at least for match arms.

Ilija

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to