xp-framework / compiler

Compiles future PHP to today's PHP.
19 stars 0 forks source link

Implement "Destructuring Coalesce" RFC #147

Closed thekid closed 1 year ago

thekid commented 1 year ago

Adds support for destructuring coalesce to all PHP versions supported by XP Compiler (7.0 - 8.2). Quoting the RFC:

Allowing for [$a ?? $b] = $array;, where $a is assigned $b if the key in the array is null or missing.

Example

Taken from the RFC:

[$key, $value ?? null]= explode('=', 'key=value', 2);
$key;   // "key"
$value; // "value"

[$key, $value ?? null]= explode('=', 'key', 2);
$key;   // "key"
$value; // null

Implementation

The functionality is implemented by rewriting destructuring assignments inside lang.ast.emit.RewriteDestructuring:

// Input - also works using list(...) syntax
[$key, $value ?? 'default']= $expr;

// Emitted as
$__t= $expr;
is_array($__t)
  ? [$key= $__t[0], $value= $__t[1] ?? 'default']
  : ([$key= null, $value= null] ? $__t : null)
;

Note: The "otherwise" branch of the ternary statement above is needed to be compatible with how list() works. It sets all variables to NULL and returns the given right-hand-side expression if this expression is not an array. For example, $r= list($a, $b)= "Test"; return [$a, $b, $r] returns [null, null, "Test"]!

Shortcomings

This doesn't work when used inside foreach, see also https://github.com/xp-framework/compiler/issues/31#issuecomment-395961865

See also

thekid commented 1 year ago

This doesn't work when used inside foreach

This can be accomplished by rewriting the destructuring statement as the first statement in the foreach loop as seen in xp-framework/compiler@12cbf1b4768d2a0cc2cf9e2fa2717662e1c44284

// Input code
foreach ($this->list as [$key, $value ?? 'default']) {
  echo $key, ' = ', $value, "\n";
}

// Emitted as follows
foreach ($this->list as &$__t) {
  is_array($__t)
    ? [$key= $__t[0], $value= $__t[1] ?? 'default']
    : ([$key= null, $value= null] ? $__t : null)
  ;
  echo $key, ' = ', $value, "\n";
}
thekid commented 1 year ago

From https://wiki.php.net/start#vote

A 2/3 majority is required. The vote started 2022-11-07 and will end 2022-11-21.

🕙 Waiting for this to be either accepted or rejected before continuing here. If accepted, this would be the first PHP 8.3 feature to be supported by XP Compiler!

thekid commented 1 year ago

RFC was rejected, closing without implementation.