[RFC] throw expression

  109156
March 19, 2020 22:10 ilija.tovilo@me.com (Ilija Tovilo)
Hi everybody!

 

Yesterday I stumbled upon this Tweet by Nikita:

https://twitter.com/nikita_ppv/status/1240309838950866946

 

It answered why this seemingly correct block of code doesn't work:

 

    fn() => throw new Exception('nope');

 

The answer is rather simple. `throw` is a statement, not an expression. However, arrow functions only allow a single expression as their bodies. The obvious solution is to convert `throw` to an expression. This would also allow for the following:

 

    $value = $nullableValue ?? throw new InvalidArgumentException();

    $value = $falsableValue ?: throw new InvalidArgumentException();

 

At the moment this is generally done by moving the `throw` into a function:

 

    function throwInvalidArgumentException() {

        throw new InvalidArgumentException();

    }

 

    $value = $nullableValue ?? throwInvalidArgumentException();

 

or of course by just using an `if` statement:

 

    if ($nullableValue === null) {

        throw new InvalidArgumentException();

    }

 

Neither of those are bad. The new syntax is just slightly more concise.

 

An implementation of the change can be found here:

https://github.com/php/php-src/pull/5279

 

It's also noteworthy that the same feature has semi-recently been added to C# 7.0:

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/throw#the-throw-expression

 

This has been proposed a handful of times in the internals mailing list but never extensively discussed:

https://externals.io/message/49569 (2010)

https://externals.io/message/15301 (2005)

https://externals.io/message/10553 (2004)

 

Let me know what you think!

 

Also, to actually create the RFC I need RFC karma. Can someone grant me those privileges? My username is ilijatovilo.

 

Thank you!