rfc:foreach_void

This is an old revision of the document!


PHP RFC: foreach iteration of keys with no values

  • Version: 0.1
  • Date: 2016-01-09
  • Author: John Bafford, john@bafford.com
  • Status: Draft (or Under Discussion or Accepted or Declined)

Introduction

When iterating over an array with foreach, it is not possible to retrieve only the array keys without unnecessary extra work or semantic overhead. This RFC proposes new syntax that makes this possible.

Background

At present, there are two main patterns in use to iterate over all of the keys of an array, both of which have drawbacks:

foreach ($array as $key => $value) {
    // use the $key, ignore the $value
}

Retrieving the array value and ignoring it has a performance cost in that an opcode is emitted in compilation (and executed during iteration) to retrieve the value at each iteration. If the $value is never actually used, this is an unnecessary cost.

Additionally, there is a semantic cost, in that even though the $value is intended to be unused, it still exists. There is no clear indication strictly via code that the value is intended to be ignored.

foreach (array_keys($array) as $key) {
}

Retrieving the list of array keys for iteration in this manner is more semantically pure because it clearly indicates intent, but it involves a performance cost as a result of the call to array_keys. (An additional traversal of the array, as well as the time and memory cost of allocating/deallocating a new array to receive copies of the keys from the source array.)

Proposal

In order to iterate over an array and retrieve only its keys, we add the following syntax:

foreach ($array as $key => void) {
}

By adding foreach ($array as $key => void), we gain the ability to iterate over the array’s keys in a performant and semantically appropriate manner, while still making it relatively easy to retrieve the array values should they be needed (either by replacing void with a variable definition, or by actually accessing the value from the source array using the key retrieved in iteration).

By not having a target variable that receives the value, an opcode is no longer emitted (or executed) to copy that value from the source. This provides a minor performance enhancement at runtime at the expense of a slightly more complicated parser and compiler for foreach.

A new E_COMPILE_ERROR is also added. The error “foreach value target must be variable or void” is emitted if a key is requested and the value target specified is not a variable (or reference to a variable), or void.

Patches and Tests

The GitHub Pull Request for this change is here: https://github.com/php/php-src/pull/XXX

While in draft, the direct link to the relevant tree is: https://github.com/jbafford/php-src/tree/foreachvoid

At present, this is a prototype, pending review.

Backward Incompatible Changes

None.

Proposed PHP Version(s)

Next PHP 7.x.

RFC Impact

There should be no adverse impact to SAPIs or existing extensions.

The only change to opcodes emitted is that when the foreach value target is void, the opcode that sets the target variable is omitted. Accordingly, there should be no adverse impact to opcache.

Open Issues

There are no open issues at this time.

Proposed Voting Choices

* Whether to add foreach ($array as $key => void) syntax

This proposal adds new syntax. Accordingly, it requires a 2/3 vote.

rfc/foreach_void.1452378631.txt.gz · Last modified: 2017/09/22 13:28 (external edit)