Re: Expression code blocks

From: Date: Sat, 17 Jun 2023 14:59:04 +0000
Subject: Re: Expression code blocks
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-120611@lists.php.net to get a copy of this message
On 17/06/2023 12:26, Ilija Tovilo wrote:
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.
I've been pondering various things in this space for a while, particularly since the last auto-capture closures RFC. I haven't quite coalesced on a coherent concept, but there are a few things that I think inter-relate: * Opting into block-scoped variables, while retaining full access to the outer scope, like JS "let" * Code blocks as some kind of first-class thing, distinct from closures * Macro-like constructs that take a block of code and do something special with it, or something like Python's "context managers" One of the use cases people often cite for auto-capture in closures is for use in patterns like this: $db->doInTransaction(function() use (...) {
    $db->execute('some SQL here');
    $db->execute('some more SQL');
    // etc
}); Or this: $name = $cache->memoize(function() use (...) {
    $result = $db->query('some SQL');
    return $result['item_name'];
}); This is a nice pattern, but closures are quite a heavy tool for this job, requiring two extra stack frames (the doInTransaction or memoize method, and the closure itself), and boilerplate to pass the result back through. As I say, I haven't got a coherent design, but I think it would be great to have something context-manager-like: $name = with($cache->memoize() as $cacheItem) {
    let $result = $db->query('some SQL');
    $cacheItem->save( $result['item_name'] );
} ); ... or macro-based: $name = null; $cache->memoize!($name, block {
    let $result = $db->query('some SQL');
    $name = $result['item_name'];
} ); Regards, -- Rowan Tommins [IMSoP]

« previous php.internals (#120611) next »