rfc:iterable

This is an old revision of the document!


PHP RFC: Iterable

Introduction

It is common for a function to accept or return either an array or an object implementing Traversable to be used with foreach. However, because array is a primitive type and Traversable is an interface, there currently is no way to use a type declaration on a parameter or return type to indicate that the value is iterable.

Proposal

This RFC proposes a new iterable pseduo-type. This type is analogous to callable, accepting multiple types instead of one single type.

iterable accepts any array or object implementing Traversable. Both of these types are iterable using foreach and can be used with yield from within a generator.

iterable can be used as a parameter type to indicate that a function requires a set of values, but does not care about the form of the value set (array, Iterator, Generator, etc.) since it will be used with foreach. If a value is not an array or instance of Traversable, a TypeError will be thrown.

function foo(iterable $iterable) {
    foreach ($iterable as $value) {
        // ...
    }
}

iterable can also be used as a return type to indicate a function will return an iterable value. If the returned value is not an array or instance of Traversable, a TypeError will be thrown.

function bar(): iterable {
    return [1, 2, 3];
}

Parameters declared as iterable may use null or an array as a default value.

function foo(iterable $iterable = []) {
    // ...
}

Functions declaring iterable as a return type may also be generators.

function gen(): iterable {
    yield 1;
    yield 2;
    yield 3;
}

This proposal also adds a function is_iterable() that returns a boolean: true if a value is iterable and will be accepted by the iterable pseudo-type, false for other values.

var_dump(is_iterable([1, 2, 3])); // bool(true)
var_dump(is_iterable(new ArrayIterator([1, 2, 3]))); // bool(true)
var_dump(is_iterable((function () { yield 1; })())); // bool(true)
var_dump(is_iterable(1)); // bool(false)
var_dump(is_iterable(new stdClass())); // bool(false)

Backward Incompatible Changes

iterable is implemented as reserved classname, therefore a class, interface, or trait named iterable cannot be declared.

Another function named is_iterable() cannot be declared in the root namespace.

Proposed PHP Version(s)

PHP 7.1

Future Scope

Union Types

If the union types RFC is accepted, then iterable will be a shortcut for array | Traversable. This is a common type requirement for functions, so having a shorter name for this union will be handy.

Voting

This proposal requires a 2/3 majority to be accepted.

Patches and Tests

PR: #1941

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