PHP RFC: Scalar Pseudo-type

Introduction

Some procedures are capable of accepting or returning any type of the ones that are considered scalar. PHP does not have support for union types and the only way to communicate such support to callers or receivers is via documentation. This RFC proposes the addition of a special scalar pseudo-type that covers all types that are considered scalar – namely bool, float, int, and string – to be valid for both parameter and return type constraints.

Proposal

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

scalar accepts bool, float, int, and string. All of these types can be safely coerced to a string and be printed.

scalar can be used as a parameter type constraint to require that a procedure is called with any of the types that are considered scalar.

function f(scalar $param){echo"{$param}\n";}

scalar can be combined with the nullable constraint to broaden the amount of types that are accepted.

function f(?scalar $param){echo"{$param}\n";}

scalar can also be used as a return type constraint to indicate that a procedure will return any of bool, float, int, or string. The combination with the nullable constraint is supported here as well.

function f(): scalar {return42;}function f(): ?scalar {returnnull;}

Parameters that are constrained to scalar may use a bool, float, int, null, or string as default value.

The function is_scalar to determine whether a value is scalar or not already exist in PHP since a long time and must not be added.

Weak Mode

Objects with a magic toString method are accepted and treated as strings in weak mode. The behavior is 1:1 the same as if the type constraint would have been string in the first place for objects. This ensures perfect consistency and adheres to the principle of least astonishment.

Examples

Scalar Parameters

PHP core already contains a multitude of procedures that could be constrained to scalar instead of mixed.

In other words, it allows one to implement type safe method overloading over a well-defined set of types. It does not cover all possibilities just one common one. (Covering all possibilities is not possible anyways and would require union types.)

Scalar Returns

The return type constraint is less commonly useful than the one for parameters, however, it is specifically of interest while designing supertypes for others and to work around the magic toString method that can only return values of type string (and is incompatible with exceptions).