This RFC proposes a new feature in PHP: type guards for classes (or interfaces). This feature aims to simplify and standardize the process of verifying that a variable is an instance of a specific class, enhancing code readability and reducing boilerplate code.
Motivation
Currently, in PHP, to ensure that a variable is an instance of a specific class, developers need to use the instanceof operator and manually throw an exception if the check fails. This results in repetitive boilerplate code scattered throughout the codebase. A new syntax, (ClassName) $variable, is proposed to streamline this process by performing an instanceof check and throwing a TypeError if the variable is not an instance of the specified class.
Proposal
Introduce a new type guard syntax for classes:
(Foo) $variable;
This syntax will internally perform the following operations:
Check if $variable is an instance of Foo.
If the check fails, throw a TypeError with a message indicating the expected and actual types.
Example:
Consider the following class definition:
class Foo {
// class definition
}
To ensure a variable is an instance of Foo, instead of writing:
if (!$variable instanceof Foo) {
throw new TypeError('Expected instance of Foo, got ' . gettype($variable));
}
Developers can use the new type guard syntax:
(Foo) $variable;
Backward Compatibility
This feature introduces new syntax and does not affect existing code. It is fully backward-compatible, as it does not modify or deprecate any existing functionality.
On Thu, 16 May 2024 at 22:33, Patrik Václavek <PaTrOnY@email.cz> wrote:
Introduction
This RFC proposes a new feature in PHP: type guards for classes (or interfaces). This feature aims to simplify and standardize the process of verifying that a variable is an instance of a specific class, enhancing code readability and reducing boilerplate code.
On Thu, May 16, 2024, at 3:31 PM, Patrik Václavek wrote:
Introduction
*************
This RFC proposes a new feature in PHP: type guards for classes (or
interfaces). This feature aims to simplify and standardize the process
of verifying that a variable is an instance of a specific class,
enhancing code readability and reducing boilerplate code.
Without commenting on the idea itself, this is just a proposal at the moment. The subject line implies there's a formal RFC now up for a vote, when there is not even a formal RFC yet. Ie, please don't abuse the subject line incorrectly.
To comment on the idea itself, I believe Ilija is correct that using pattern matching would be the better approach here. Right now the RFC suggests $foo as <pattern> would return true or throw, but "return $foo or throw" would indeed make more sense. And then give us the entire power of pattern matching. (That RFC will come up formally soon(tm), I swear.)
On Thu, May 16, 2024 at 1:32 PM Patrik Václavek <PaTrOnY@email.cz> wrote:
Introduction
This RFC proposes a new feature in PHP: type guards for classes (or interfaces). This feature aims to simplify and standardize the process of verifying that a variable is an instance of a specific class, enhancing code readability and reducing boilerplate code.
Motivation
Currently, in PHP, to ensure that a variable is an instance of a specific class, developers need to use the instanceof operator and manually throw an exception if the check fails. This results in repetitive boilerplate code scattered throughout the codebase. A new syntax, (ClassName) $variable, is proposed to streamline this process by performing an instanceof check and throwing a TypeError if the variable is not an instance of the specified class.
Proposal
Introduce a new type guard syntax for classes:
(Foo) $variable;
This syntax will internally perform the following operations:
Check if $variable is an instance of Foo.
If the check fails, throw a TypeError with a message indicating the expected and actual types.
Example:
Consider the following class definition:
class Foo {
// class definition
}
To ensure a variable is an instance of Foo, instead of writing:
if (!$variable instanceof Foo) {
throw new TypeError('Expected instance of Foo, got ' . gettype($variable));
}
Developers can use the new type guard syntax:
(Foo) $variable;
Backward Compatibility
This feature introduces new syntax and does not affect existing code. It is fully backward-compatible, as it does not modify or deprecate any existing functionality.
Since this throws, I’m struggling to understand how this would replace any usages of instanceof other than if (!($var instanceof Foo)) throw new TypeError();
Also, this is not an RFC with a page I can look at OR something in a vote, so the subject line is a bit of a lie.
But now that I’ve gotten my grumps out of the way, better class specific syntax is in general something that I think is positive and worth exploring.
On Thu, May 16, 2024, at 22:31, Patrik Václavek wrote:
This feature aims to simplify and standardize the process of verifying that a variable is an instance of a specific class, enhancing code readability and reducing boilerplate code.
Currently, in PHP, to ensure that a variable is an instance of a specific class, developers need to use the instanceof operator and manually throw an exception if the check fails. This results in repetitive boilerplate code scattered throughout the codebase. A new syntax, (ClassName) $variable, is proposed to streamline this process by performing an instanceof check and throwing a TypeError if the variable is not an instance of the specified class.
I view variables changing types to be an anti-pattern.
Instead if adding type guards, I would rather see this problem solved by having typed local variables. This ensures that a variable always holds a specific type, avoiding the need of repetitive scattered type guards. Working with variables would then be the same as working with class properties. They could be typed or untyped.
Also, I see the need for type guards as a symptom of bad composition. Mostly methods that are too large would benefit. If a method is decomposed into smaller methods the use of parameter and return type checks it’s unlikely there is need for additional type guards.