On Mon, Apr 22, 2019 at 11:48 PM Benjamin Morel <benjamin.mo...@gmail.com>
wrote:

> Hi internals,
>
> I'd like to revive an old discussion <https://externals.io/message/67131>
> about
> object type casting.
>
> The idea would be to allow (ClassName) casting:
>
>     $service = (EmailService) $diContainer->get('email.service');
>
> The above code would throw a TypeError if the value is not an instance of
> the given class. I see the following advantages:
>
> - Type safety: we can be sure that the value is of the correct type or that
> we'll get an Error. This syntax allows to fail early if the variable
> happens to not be of the expected type, and avoids much more verbose
> checks;
> - Static analysis: IDEs and static code analysis tools can now understand
> the type of the variable, without having to resort to `@var` annotations.
>
> These combine into a third advantage: readability. Today's equivalent of
> the above one-liner could be:
>
>     /** @var EmailService $service */
>     $service = $diContainer->get('email.service');
>     if (! $service instanceof EmailService) {
>         throw new TypeError('Expected instance of EmailService, ...');
>     }
>
> Which is a lot of boilerplate code that could be easily avoided by
> introducing this new syntax.
>
> Before moving forward and working on a formal RFC, I'd like to hear your
> thoughts: what's your early feeling about this? Did I miss other
> discussions around this subject? Are there any technical issues that come
> to mind? Could this feature help the upcoming JIT compiler produce more
> efficient machine code by knowing the type of the variable at compile time?
> etc.
>
> Note: "casting" might not be the perfect name here as what we're really
> doing is a type check, but this reuses the type casting syntax and
> resembles Java's object casting.
>
> Thank you,
> Ben
>

Without commenting on the rest of the proposal: It's not possible to use
(ClassName) as a cast syntax, because it is ambiguous. For example (Foo)
[$x] is already valid syntax (fetch constant Foo and take index $x), or
(Foo) +$bar, etc.

The only reason why (int) etc are okay is because we treat the whole (int)
as a single token, something we can't do in general (because it would break
foo(Foo)).

Nikita

Reply via email to