Re: [PHP-DEV] [VOTE] noreturn type

2021-04-03 Thread Matthew Brown
On Sat, 3 Apr 2021 at 22:29, David Rodrigues  wrote:

> It is very likely that the proposal will be accepted (it is already 33/10),
>

I'm definitely not counting my chickens.


> Is there any chance of discussing terms, even if the "never" indication is
> winning at the moment? Or did I miss this discussion?
>

The RFC discussion is here: https://externals.io/message/113442. Someone
suggested "terminus", but nobody replied supporting that suggestion (that
was your opportunity!). Lots of people suggested "never", enough that a
vote on "noreturn" vs "never" was added to the final RFC.

As for "terminus", I don't think there's much benefit to PHP having its own
separate term for a type "noreturn"/"never" that already exists in other
languages. I know that naming is one of the "two hard things", but there's
no need to make it any harder.


Re: [PHP-DEV] [VOTE] noreturn type

2021-04-03 Thread David Rodrigues
Just to spice up the discussion a bit, I will try to give my opinion on
this RFC...

It is very likely that the proposal will be accepted (it is already 33/10),
but I still find the terms "noreturn" or "never" unclear. "noreturn" are
two words together, and I am not particularly a fan of this type of
nomenclature (and it may sound repetitive and strange "return no return"),
while "never" can be ambiguous, it could be read as "never return" (OK) or
"return never" (and it sounds a little strange, I guess).

I saw someone (sorry, I don't remember who) suggesting the term "terminus",
so I thought of an alternative like "terminal". Or, if you still want to
take advantage of a keyword and without losing the meaning, "exit"
(including, it makes absolutely clear what is expected as "return": "return
the exit").

Is there any chance of discussing terms, even if the "never" indication is
winning at the moment? Or did I miss this discussion?

Thanks!


Atenciosamente,
David Rodrigues


Em sáb., 3 de abr. de 2021 às 23:07, Matthew Brown 
escreveu:

> On Sat, 3 Apr 2021 at 12:30, Benjamin Eberlei  wrote:
>
> >
> > But adding a new keyword "noreturn" would not be necessary, it could just
> > be an Attribute as i said in my first e-mail explaining my no-vote:
> >
> > #[NoReturn] // sets a function flag modifying the void behavior
> > public function foo(): nothing {
> > return; // throws if it reaches this point
> > }
> >
> > This would be closer to what Psalm and PHP-Stan use at the moment if we
> > replace nothing with void.
> >
> > The problem is that "void" is already not perfect, since the callside
> > doesn't care about "return null" with no return type vs "return" + void
> > return type.
> >
> > If we had "nothing" and "null" instead of "void", and we'd say like PHP
> > works, "return;" actually means "return null;", then:
> >
> > function foo(): nothing {
> > return; // Error: cannot return null from a function that returns
> > nothing.
> > }
> > function bar(): null {
> > return;
> > // or return null;
> > }
> >
> > This would more consistently tie into union types where |null is allowed,
> > however on its own it is not: "foo() : null => error".
> >
> > As Levi said, this noreturn/never just perpetuates/amplifies the existing
> > void mistake and feels off, given that other recent changes to PHP have
> > been more bold, towards removing inconsistencies.
> >
> >
> Clearly comparisons of "noreturn"/"never" to "void" are a bit of a
> minefield, because a number of contributors feel that void was a mistake,
> that its implementation doesn't feel PHP-like.
>
> While I disagree that our proposal is intrinsically connected with the void
> one – noreturn/never could work equally well with a "null" return — our
> proposal does perpetuate one idea behind "void": that PHP can benefit from
> types found in other languages and type systems, and especially types found
> in Hack.
>
> It seems like some of the debate is over whether "noreturn"/"never" is a
> behaviour or a type. If it were purely a behaviour, with no meaning as a
> type, an Attribute would be a much more appropriate location.
>
> It's not just a behaviour, though — it is a type that follows variance
> rules, and it's a type that PHP can check.
>
> If "void" returns are too much of a distraction, think instead of "object"
> return type declarations:
>
> When executing the function
>
> function returnsObject($o) : object {
> if (rand(0, 1)) {
> return $o;
> }
> }
>
> Here PHP's engine checks two separate behaviours
>
> 1. when the function explicitly returns, does it return an object?
> 2. does the function ever finish without returning or throwing or exiting?
>
> Only the first actually involves a strict type check. The second is a
> generic behaviour check, triggered by the existence of a return type. This
> is essentially the same check that we want to trigger with
> "noreturn"/"never".
>
> In fact, as someone recently pointed out, running the following code
> *today* produces similar errors to the ones we propose:
>
> function php7Redirect() : noreturn {
> if (rand(0, 1)) {
> return "bad"; //  Fatal error: Uncaught TypeError
> }
> header("Location: https://php.net;);
> exit; // OK
> }
>
> Our RFC makes this code explicitly legal, and adds covariance. Indeed our
> implementation is small because it correctly treats "noreturn"/"never" as a
> type, allowing us to use the existing return type handling.
>


Re: [PHP-DEV] [VOTE] noreturn type

2021-04-03 Thread Matthew Brown
On Sat, 3 Apr 2021 at 12:30, Benjamin Eberlei  wrote:

>
> But adding a new keyword "noreturn" would not be necessary, it could just
> be an Attribute as i said in my first e-mail explaining my no-vote:
>
> #[NoReturn] // sets a function flag modifying the void behavior
> public function foo(): nothing {
> return; // throws if it reaches this point
> }
>
> This would be closer to what Psalm and PHP-Stan use at the moment if we
> replace nothing with void.
>
> The problem is that "void" is already not perfect, since the callside
> doesn't care about "return null" with no return type vs "return" + void
> return type.
>
> If we had "nothing" and "null" instead of "void", and we'd say like PHP
> works, "return;" actually means "return null;", then:
>
> function foo(): nothing {
> return; // Error: cannot return null from a function that returns
> nothing.
> }
> function bar(): null {
> return;
> // or return null;
> }
>
> This would more consistently tie into union types where |null is allowed,
> however on its own it is not: "foo() : null => error".
>
> As Levi said, this noreturn/never just perpetuates/amplifies the existing
> void mistake and feels off, given that other recent changes to PHP have
> been more bold, towards removing inconsistencies.
>
>
Clearly comparisons of "noreturn"/"never" to "void" are a bit of a
minefield, because a number of contributors feel that void was a mistake,
that its implementation doesn't feel PHP-like.

While I disagree that our proposal is intrinsically connected with the void
one – noreturn/never could work equally well with a "null" return — our
proposal does perpetuate one idea behind "void": that PHP can benefit from
types found in other languages and type systems, and especially types found
in Hack.

It seems like some of the debate is over whether "noreturn"/"never" is a
behaviour or a type. If it were purely a behaviour, with no meaning as a
type, an Attribute would be a much more appropriate location.

It's not just a behaviour, though — it is a type that follows variance
rules, and it's a type that PHP can check.

If "void" returns are too much of a distraction, think instead of "object"
return type declarations:

When executing the function

function returnsObject($o) : object {
if (rand(0, 1)) {
return $o;
}
}

Here PHP's engine checks two separate behaviours

1. when the function explicitly returns, does it return an object?
2. does the function ever finish without returning or throwing or exiting?

Only the first actually involves a strict type check. The second is a
generic behaviour check, triggered by the existence of a return type. This
is essentially the same check that we want to trigger with
"noreturn"/"never".

In fact, as someone recently pointed out, running the following code
*today* produces similar errors to the ones we propose:

function php7Redirect() : noreturn {
if (rand(0, 1)) {
return "bad"; //  Fatal error: Uncaught TypeError
}
header("Location: https://php.net;);
exit; // OK
}

Our RFC makes this code explicitly legal, and adds covariance. Indeed our
implementation is small because it correctly treats "noreturn"/"never" as a
type, allowing us to use the existing return type handling.


Re: [PHP-DEV] [VOTE] noreturn type

2021-04-03 Thread Andreas Leathley

On 03.04.21 21:26, Peter Bowyer wrote:

This and Levi's email make compelling arguments and I would like to see
this adopted. I have changed my vote to "No".

Wasn't Levi arguing for the RFC? Introducing "never" as a bottom type is
what Levi was strongly arguing for, and that is what the RFC currently
proposes/leads to (taking into account the clear lead for "never").

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] noreturn type

2021-04-03 Thread Peter Bowyer
On Sat, 3 Apr 2021 at 17:30, Benjamin Eberlei  wrote:

> The problem is that "void" is already not perfect, since the callside
> doesn't care about "return null" with no return type vs "return" + void
> return type.
>
> If we had "nothing" and "null" instead of "void", and we'd say like PHP
> works, "return;" actually means "return null;", then:
>
> function foo(): nothing {
> return; // Error: cannot return null from a function that returns
> nothing.
> }
> function bar(): null {
> return;
> // or return null;
> }
>
> This would more consistently tie into union types where |null is allowed,
> however on its own it is not: "foo() : null => error".
>
> As Levi said, this noreturn/never just perpetuates/amplifies the existing
> void mistake and feels off, given that other recent changes to PHP have
> been more bold, towards removing inconsistencies.
>

This and Levi's email make compelling arguments and I would like to see
this adopted. I have changed my vote to "No".

Peter


Re: [PHP-DEV] [VOTE] noreturn type

2021-04-03 Thread Andreas Leathley

On 03.04.21 18:30, Benjamin Eberlei wrote:

if (is_string($value) && is_int($value)) {
// inside here $value is_type == "never"
}

The naming "never" here makes no sense, because from a theoretical
perspective reasoning about the type of $value it is nothing and only the
block of code is "never reached".

I suppose PHPStan and Psalm are eager to reuse the new type name for this
kind of type interference, same as TypeScript does. The name is sub
optiomal outside the context of a return type.


I read through all the Typescript and Hack explanations/examples of
"never" and "nothing", and to me "never" seems clearer, which just shows
how different opinions can be. I would not like "nothing" because it
seems so similar to "void" and "null". "This function returns nothing"
would inevitably lead to the question what that actually means. "This
function returns never" is a reasonably clear description. "This
variable at this point is never" or "This variable at this point is
nothing" are both not clear without context, although never implies this
should not happen (or cannot happen) and could be interpreted as "This
variable at this point is never anything", which in general would be
clearer to me (not being familiar with either before this proposal).

From a practical perspective, I think the proposal is about the return
type because this has a clear use case in code today. Your $value
example would lead to the Psalm/PHPStan errors of "Type does not contain
type" (Psalm) or "Result of && is always false" (PHPStan), I don't think
there currently is much use to determine a type of never in these cases.
But that might be something Matt/Ondrej can answer a lot better than me.

I initially preferred "noreturn", but now prefer "never". "noreturn" is
more self-explanatory, but "never" seems more apt and versatile, while
still being quite clear.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] noreturn type

2021-04-03 Thread Benjamin Eberlei
On Sat, Apr 3, 2021 at 5:30 PM Benjamin Eberlei  wrote:

>
>
> On Fri, Apr 2, 2021 at 3:14 AM Aaron Piotrowski  wrote:
>
>>
>> > On Apr 1, 2021, at 2:03 PM, Levi Morrison via internals <
>> internals@lists.php.net> wrote:
>> >
>> > I do not care which name is chosen, but if we are going to have this
>> > sort of thing in the language, it ought to be a bottom type, not an
>> > attribute.
>> >
>>
>> You make an excellent point Levi. I initially chose `noreturn` simply
>> because I was familiar with the name from C and didn't have a strong
>> opinion. However, I agree that `noreturn` is a poor choice for reuse as a
>> bottom type, so I changed my vote to `never`.
>>
>
> i voted against this proposal, but changed my choice of "noreturn" to
> "never", because it would ultimately be slightly less bad to have this name
> for use as a bottom type. The name "never" is still unfortunate, because it
> transmits "behavior" of being used in the context of a function, a better
> name might have been "nothing" as Levi suggests.
>
> But I again get to the point of the problem with this RFC due to naming.
> "never" is actually combining "nothing" type with "noreturn" flag, so for
> me the most consistent way would have been "public noreturn function foo():
> nothing"
>

Sorry, i should have been more detailed/precise before:

Why i think "never" is not a great solution, if you have the same example
that TypeScript uses to explain their "never":

if (is_string($value) && is_int($value)) {
   // inside here $value is_type == "never"
}

The naming "never" here makes no sense, because from a theoretical
perspective reasoning about the type of $value it is nothing and only the
block of code is "never reached".

I suppose PHPStan and Psalm are eager to reuse the new type name for this
kind of type interference, same as TypeScript does. The name is sub
optiomal outside the context of a return type.

So lets say we seperate the two behaviors of "never" into "nothing +
noreturn".

public noreturn function foo(): nothing {
exit();
}

But adding a new keyword "noreturn" would not be necessary, it could just
be an Attribute as i said in my first e-mail explaining my no-vote:

#[NoReturn] // sets a function flag modifying the void behavior
public function foo(): nothing {
return; // throws if it reaches this point
}

This would be closer to what Psalm and PHP-Stan use at the moment if we
replace nothing with void.

The problem is that "void" is already not perfect, since the callside
doesn't care about "return null" with no return type vs "return" + void
return type.

If we had "nothing" and "null" instead of "void", and we'd say like PHP
works, "return;" actually means "return null;", then:

function foo(): nothing {
return; // Error: cannot return null from a function that returns
nothing.
}
function bar(): null {
return;
// or return null;
}

This would more consistently tie into union types where |null is allowed,
however on its own it is not: "foo() : null => error".

As Levi said, this noreturn/never just perpetuates/amplifies the existing
void mistake and feels off, given that other recent changes to PHP have
been more bold, towards removing inconsistencies.


> Its said that composition is better than inheritance, so combining two
> behaviors into one keyword will be limiting in the future, if we think of
> other function flags that should compose with "never".
>
>
>> Cheers,
>> Aaron Piotrowski
>>
>>


Re: [PHP-DEV] [VOTE] noreturn type

2021-04-03 Thread Rowan Tommins

On 03/04/2021 16:30, Benjamin Eberlei wrote:

But I again get to the point of the problem with this RFC due to naming.
"never" is actually combining "nothing" type with "noreturn" flag, so for
me the most consistent way would have been "public noreturn function foo():
nothing"



I'm not sure how the flag and return type could ever be used separately. 
Are you suggesting that we should allow all 3 of these:


- public noreturn function foo(): nothing
- public noreturn function foo(): int
- public function foo(): nothing

How would any tool treat these differently?

Regards,

--
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] noreturn type

2021-04-03 Thread Benjamin Eberlei
On Fri, Apr 2, 2021 at 3:14 AM Aaron Piotrowski  wrote:

>
> > On Apr 1, 2021, at 2:03 PM, Levi Morrison via internals <
> internals@lists.php.net> wrote:
> >
> > I do not care which name is chosen, but if we are going to have this
> > sort of thing in the language, it ought to be a bottom type, not an
> > attribute.
> >
>
> You make an excellent point Levi. I initially chose `noreturn` simply
> because I was familiar with the name from C and didn't have a strong
> opinion. However, I agree that `noreturn` is a poor choice for reuse as a
> bottom type, so I changed my vote to `never`.
>

i voted against this proposal, but changed my choice of "noreturn" to
"never", because it would ultimately be slightly less bad to have this name
for use as a bottom type. The name "never" is still unfortunate, because it
transmits "behavior" of being used in the context of a function, a better
name might have been "nothing" as Levi suggests.

But I again get to the point of the problem with this RFC due to naming.
"never" is actually combining "nothing" type with "noreturn" flag, so for
me the most consistent way would have been "public noreturn function foo():
nothing"

Its said that composition is better than inheritance, so combining two
behaviors into one keyword will be limiting in the future, if we think of
other function flags that should compose with "never".


> Cheers,
> Aaron Piotrowski
>
>


Re: [PHP-DEV] [VOTE] noreturn type

2021-04-02 Thread Kamil Tekiela
I am still not comfortable with the error message "Nothing was expected to
be returned" which is very confusing and I would change it to "was expected
to throw or exit" or "was expected to never return".
I went with "never" because it just reads better: "Function abc returns
never" instead of "Function abc returns noreturn". If "never" wins then the
other error message "A noreturn function must not return" must also be
changed. Maybe "The function must never return"


Re: [PHP-DEV] [VOTE] noreturn type

2021-04-01 Thread Aaron Piotrowski

> On Apr 1, 2021, at 2:03 PM, Levi Morrison via internals 
>  wrote:
> 
> I do not care which name is chosen, but if we are going to have this
> sort of thing in the language, it ought to be a bottom type, not an
> attribute.
> 

You make an excellent point Levi. I initially chose `noreturn` simply because I 
was familiar with the name from C and didn't have a strong opinion. However, I 
agree that `noreturn` is a poor choice for reuse as a bottom type, so I changed 
my vote to `never`.

Cheers,
Aaron Piotrowski



Re: [PHP-DEV] [VOTE] noreturn type

2021-04-01 Thread Levi Morrison via internals
On Thu, Apr 1, 2021 at 6:59 AM Matthew Brown  wrote:
>
> On Thu, 1 Apr 2021 at 04:56, Benjamin Eberlei  wrote:
>
> > This RFC is using the declaration of the return type, to specify that it
> > never returns. As such noreturn or never is a keyword a long the lines of
> > public or final, but it is not a return type.
> >
> > I don't think the argument for potential optimizations in Opcache to
> > eliminate dead code or allow IDEs to hint at dead code are valuable enough
> > to justify this change.
> >
>
> By this argument "void" should also be an attribute – there's no reason to
> hint a value that's not being returned.
>
> You'd write functions like
>
> [\Void]
> function foo() { ... }
>
> But we don't do that, because the wider programming language community has
> agreed that "void" is a type, and at compile-time PHP's engine can ensure
> that "void" functions do not return a value.

For what it is worth, it does return a value `null`, which has a type.
Using "void" is outright wrong, a lie told because "we" voted it this
way. Few people seemed to care when I brought this up, but null makes
sense with union types, covariance, etc, which we now have. I'm still
slightly bitter about this, in case you cannot tell.

The [void RFC][1] said:
> There's no precedent for it and the name doesn't seem to have been an issue 
> until now.

This was disingenuous, as it disregards Swift and Rust, both of which
use a unit type; they just call it () instead of null. These languages
are held in high regard as far as mainstream programming languages go,
but instead we voted to repeat the mistakes of C and company. I
believe Python's PEP 484 for Type Hints was available at this time,
and it uses None when no value is explicitly returned just like PHP
does with null.

But, we decided to do it the wrong way a la C. Let's please not repeat
this mistake. For the record, in C this is an attribute (and
non-standard at that!), not a return type, so this is a particularly
apt comparison.

Please, let's _accurately_ follow type theory and use a bottom type.
According to the [data in Wikipedia][2], the most common names for the
bottom type are:

 1. `never`, used by Elm and Typescript. Note that in Rust the bottom
type is `!` but spelled out in docs as "never".
 2. `nothing`, used by Kotlin, Ceylon, and Scala.

I do not care which name is chosen, but if we are going to have this
sort of thing in the language, it ought to be a bottom type, not an
attribute.

  [1]: https://wiki.php.net/rfc/void_return_type#why_call_it_void_and_not_null
  [2]: https://en.wikipedia.org/wiki/Bottom_type#In_programming_languages

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] noreturn type

2021-04-01 Thread Ondřej Mirtes
On 1. 4. 2021 19:24:35, Bruce Weirdan  wrote:

> Since `throw` is an expression (since PHP 8.0,
> https://wiki.php.net/rfc/throw_expression), it must have a type for its
> result,
> as any expression has a type. And it's result is exactly `noreturn` (or
> `never`, as this option seems to be preferred
> judging by current vote results), because `throw` never returns.
>
> It's quite natural to extend that to function calls that never return as
> well. And then it makes sense to declare that type
> as a part of function signature like you can do with other types.
>
> --
>  Best regards,
>  Bruce Weirdan mailto:
> weir...@gmail.com
>

Yes, this works very well in the typesystem. For example if we define the
type of the match expression as a union of all its arms, then the arm that
always throws or contains exit() has the noreturn/never type, which is
thrown away in a union (int|string|never can be normalized to int|string).


Re: [PHP-DEV] [VOTE] noreturn type

2021-04-01 Thread Bruce Weirdan
On Thu, Apr 1, 2021 at 6:07 PM Benjamin Eberlei  wrote:

>
> ```php
> if (!isset($user)) {
>throw new NotFoundException();
> }
> ```
>

Since `throw` is an expression (since PHP 8.0,
https://wiki.php.net/rfc/throw_expression), it must have a type for its
result,
as any expression has a type. And it's result is exactly `noreturn` (or
`never`, as this option seems to be preferred
judging by current vote results), because `throw` never returns.

It's quite natural to extend that to function calls that never return as
well. And then it makes sense to declare that type
as a part of function signature like you can do with other types.

-- 
  Best regards,
  Bruce Weirdan mailto:
weir...@gmail.com


Re: [PHP-DEV] [VOTE] noreturn type

2021-04-01 Thread Andreas Leathley

On 01.04.21 17:07, Benjamin Eberlei wrote:

I don't know, you are arguing that you forgot a return, but you also did
not forget to add a never return type. You
could easily fix this by inlining the exception instead.

```php
if (!isset($user)) {
throw new NotFoundException();
}
```
Even when you insist on the function, it is a one liner that throws
immediately. Adding the never return type there isn't going to catch a
great many bugs.


Throwing an exception immediately is an alternative, but this only works
if that is the absolute only thing the method does, and even then it
leads to a lot of repetition (if you have many controllers) with very
specific code shared in each controller. Making the identical behavior
between controllers explicit by a shared "notFound" method seems better
coding to me, and it has the advantage of being very readable and
something you can easily recognize between different controllers - you
look it up once and know what it does. If you throw exceptions in each
controller, you might wonder if this is the exact same exception as
another one in another controller. Often you might also want to change
the behavior at some point - for example log the event before throwing
the exception, or handling notFound entirely different. noreturn/never
gives you the flexibility to refactor "throw NotFoundException();" into
a method while keeping the promise that the code flow will not continue.

Abstracting away something like a redirect, an authorization problem or
a 404 also seems an improvement to me (compared to "throw
NotFoundException();") because you write and test that logic once, and
then reuse it in different places. Like with other parts of the type
system in PHP noreturn/never just gives you stronger guarantees and more
information about what a function/method is ought to do and how it behaves.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] noreturn type

2021-04-01 Thread Benjamin Eberlei
On Thu, Apr 1, 2021 at 3:56 PM Andreas Leathley  wrote:

> On 01.04.21 10:56, Benjamin Eberlei wrote:
> > This RFC is using the declaration of the return type, to specify that it
> > never returns. As such noreturn or never is a keyword a long the lines of
> > public or final, but it is not a return type.
> >
> > I don't think the argument for potential optimizations in Opcache to
> > eliminate dead code or allow IDEs to hint at dead code are valuable
> enough
> > to justify this change.
>
> I already use @return no-return (supported by Psalm/PHPStan) in my code
> now, to clarify the code flow, and for me it fits perfectly for return
> types, as not returning is also a result of the function/method. Having
> a return type of "int" or "string" (or even "void") seems misleading
> when the method will never return anyway.
>
> noreturn/never might not be useful in all code, but for some parts like
> in a controller of a web application it makes handling redirects,
> authorization or 404 errors much easier, clearer and less error-prone,
> for example:
>
> ```php
> if (!isset($user)) {
>$this->notFound(); // this is a noreturn/never method
> }
>
> if (!$this->isGranted('adminPrivileges')) {
>$this->notAuthorized(); // this is a noreturn/never method
> }
> ```
>
> Adding noreturn/never on a language level would make sure calling
> "$this->notAuthorized();" never continues code flow. This is often also
> a security issue, as seen by an alternative way of handling the above
> use cases:
>
> ```php
> if (!isset($user)) {
>$this->notFound();
>return;
> }
>
> if (!$this->isGranted('adminPrivileges')) {
>$this->notAuthorized();
>return;
> }
> ```
>
> If you forget a return, suddenly you have issues. So even though
> noreturn/never is a niche language feature not everyone will use, it
> does address a very real use case.


I don't know, you are arguing that you forgot a return, but you also did
not forget to add a never return type. You
could easily fix this by inlining the exception instead.

```php
if (!isset($user)) {
   throw new NotFoundException();
}
```
Even when you insist on the function, it is a one liner that throws
immediately. Adding the never return type there isn't going to catch a
great many bugs.



> Using attributes has the disadvantage
> of not making the intent clear:
>

> ```php
> #[\NoReturn]
> function notAuthorized(): string
> {
>// Some code
> }
> ```
>
> Now you have a return type of string, but also the information that the
> function will never return anyway. That is confusing, but will be
> inevitable in some cases when implementing interfaces or an abstract
> class. In my opinion, the string return type is wrong in this case and
> can only mislead a developer.
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>


Re: [PHP-DEV] [VOTE] noreturn type

2021-04-01 Thread Andreas Leathley

On 01.04.21 10:56, Benjamin Eberlei wrote:

This RFC is using the declaration of the return type, to specify that it
never returns. As such noreturn or never is a keyword a long the lines of
public or final, but it is not a return type.

I don't think the argument for potential optimizations in Opcache to
eliminate dead code or allow IDEs to hint at dead code are valuable enough
to justify this change.


I already use @return no-return (supported by Psalm/PHPStan) in my code
now, to clarify the code flow, and for me it fits perfectly for return
types, as not returning is also a result of the function/method. Having
a return type of "int" or "string" (or even "void") seems misleading
when the method will never return anyway.

noreturn/never might not be useful in all code, but for some parts like
in a controller of a web application it makes handling redirects,
authorization or 404 errors much easier, clearer and less error-prone,
for example:

```php
if (!isset($user)) {
  $this->notFound(); // this is a noreturn/never method
}

if (!$this->isGranted('adminPrivileges')) {
  $this->notAuthorized(); // this is a noreturn/never method
}
```

Adding noreturn/never on a language level would make sure calling
"$this->notAuthorized();" never continues code flow. This is often also
a security issue, as seen by an alternative way of handling the above
use cases:

```php
if (!isset($user)) {
  $this->notFound();
  return;
}

if (!$this->isGranted('adminPrivileges')) {
  $this->notAuthorized();
  return;
}
```

If you forget a return, suddenly you have issues. So even though
noreturn/never is a niche language feature not everyone will use, it
does address a very real use case. Using attributes has the disadvantage
of not making the intent clear:

```php
#[\NoReturn]
function notAuthorized(): string
{
  // Some code
}
```

Now you have a return type of string, but also the information that the
function will never return anyway. That is confusing, but will be
inevitable in some cases when implementing interfaces or an abstract
class. In my opinion, the string return type is wrong in this case and
can only mislead a developer.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] noreturn type

2021-04-01 Thread Matthew Brown
On Thu, 1 Apr 2021 at 04:56, Benjamin Eberlei  wrote:

> This RFC is using the declaration of the return type, to specify that it
> never returns. As such noreturn or never is a keyword a long the lines of
> public or final, but it is not a return type.
>
> I don't think the argument for potential optimizations in Opcache to
> eliminate dead code or allow IDEs to hint at dead code are valuable enough
> to justify this change.
>

By this argument "void" should also be an attribute – there's no reason to
hint a value that's not being returned.

You'd write functions like

[\Void]
function foo() { ... }

But we don't do that, because the wider programming language community has
agreed that "void" is a type, and at compile-time PHP's engine can ensure
that "void" functions do not return a value.

"Noreturn"/"never" is also recognised as a type by the wider programming
language community. It can be checked at both compile-time and run-time by
the engine, as detailed in the RFC. Indeed, _no other return type makes
sense in the context_.

The type definitely felt awkward when I first started using it in
docblocks, but after a while it started to make intuitive sense.

Best wishes,

Matt/Ondrej


Re: [PHP-DEV] [VOTE] noreturn type

2021-04-01 Thread Sebastian Bergmann

Am 01.04.2021 um 10:56 schrieb Benjamin Eberlei:

I voted no, because i think this should at the maximum be an attribute.

This RFC is using the declaration of the return type, to specify that it
never returns. As such noreturn or never is a keyword a long the lines of
public or final, but it is not a return type.

I don't think the argument for potential optimizations in Opcache to
eliminate dead code or allow IDEs to hint at dead code are valuable enough
to justify this change.


Following Benjamin's argument, I have changed my vote to no.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] noreturn type

2021-04-01 Thread Benjamin Eberlei
On Tue, Mar 30, 2021 at 5:07 PM Matthew Brown 
wrote:

> Hey everyone!
>
> The vote for adding noreturn is now open:
>
> https://wiki.php.net/rfc/noreturn_type
>
> Voting will run through April 13th
>
> Best wishes,
>
> Matt and Ondrej
>

I voted no, because i think this should at the maximum be an attribute.

This RFC is using the declaration of the return type, to specify that it
never returns. As such noreturn or never is a keyword a long the lines of
public or final, but it is not a return type.

I don't think the argument for potential optimizations in Opcache to
eliminate dead code or allow IDEs to hint at dead code are valuable enough
to justify this change.


Re: [PHP-DEV] [VOTE] noreturn type

2021-03-31 Thread Matthew Brown
On Wed, 31 Mar 2021 at 09:30, Theodore Brown  wrote:

> On Tue, Mar 30, 2021 at 5:24 PM Matthew Brown 
> wrote:
>
> > On Tue, 30 Mar 2021 at 12:55, Theodore Brown 
> wrote:
> >
> > > On Tue, Mar 30, 2021 at 10:06 AM Matthew Brown <
> matthewmatt...@gmail.com> wrote:
> > >
> > > > Hey everyone!
> > > >
> > > > The vote for adding noreturn is now open:
> > > >
> > > > https://wiki.php.net/rfc/noreturn_type
> > > >
> > > > Voting will run through April 13th
> > >
> > > Hi Matt and Ondrej,
> > >
> > > Thanks for your work on this RFC. I voted for `never` as the type name
> > > because it's more amenable to future use cases like compile-time
> > > exhaustiveness checks (example:
> > >
> https://www.typescriptlang.org/docs/handbook/2/narrowing.html#the-never-type
> ).
> > >
> > > As a bonus `never` is more concise, avoids mashing two words together,
> > > and aligns with TypeScript, which I and many other PHP devs also use.
> >
> > Awesome! The conciseness argument for "never" is already mentioned in
> > the RFC, as is TypeScript's use of the term.
> >
> > Full disclosure (because neither of us is eligible to vote):
> > I slightly prefer "noreturn", and Ondrej strongly prefers "never".
>
> Hi Matt,
>
> I'm confused by this. If Ondrej strongly prefers `never`, why does the
> RFC say "we believe `noreturn` is the best name for this type"?
>
> It might be better to just remove this sentence, or else list your
> separate preferences.
>
> Thanks,
> Theodore


I've removed that sentence.

Opinions evolved — I wrote the RFC with the original language favouring
"noreturn", Ondrej edited it, adding more arguments for "never". Since we
published the RFC some in the community have validated his arguments, and I
think Ondrej's opinion has become stronger as a result (and mine has become
weaker). Whatever happens, I think we care much more that this passes than
what it's exactly called.

Best wishes,

Matt


Re: [PHP-DEV] [VOTE] noreturn type

2021-03-31 Thread Theodore Brown
On Tue, Mar 30, 2021 at 5:24 PM Matthew Brown  wrote:

> On Tue, 30 Mar 2021 at 12:55, Theodore Brown  wrote:
> 
> > On Tue, Mar 30, 2021 at 10:06 AM Matthew Brown  
> > wrote:
> > 
> > > Hey everyone!
> > >
> > > The vote for adding noreturn is now open:
> > >
> > > https://wiki.php.net/rfc/noreturn_type
> > >
> > > Voting will run through April 13th
> > 
> > Hi Matt and Ondrej,
> > 
> > Thanks for your work on this RFC. I voted for `never` as the type name
> > because it's more amenable to future use cases like compile-time
> > exhaustiveness checks (example:
> > https://www.typescriptlang.org/docs/handbook/2/narrowing.html#the-never-type).
> > 
> > As a bonus `never` is more concise, avoids mashing two words together,
> > and aligns with TypeScript, which I and many other PHP devs also use.
> 
> Awesome! The conciseness argument for "never" is already mentioned in
> the RFC, as is TypeScript's use of the term.
> 
> Full disclosure (because neither of us is eligible to vote):
> I slightly prefer "noreturn", and Ondrej strongly prefers "never".

Hi Matt,

I'm confused by this. If Ondrej strongly prefers `never`, why does the
RFC say "we believe `noreturn` is the best name for this type"?

It might be better to just remove this sentence, or else list your separate 
preferences.

Thanks,
Theodore
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] noreturn type

2021-03-31 Thread Andreas Hennings
On Wed, 31 Mar 2021 at 14:41, Ilija Tovilo  wrote:
>
> Hi internals
>
> On Wed, Mar 31, 2021 at 2:14 PM Andreas Hennings  wrote:
> >
> > Also check my comment in the other thread:
> > If in the future we want a "bottom type" that also works for parameters
> > (generics or abstract methods), should we create a new keyword, or should
> > we attempt to find a keyword now that works for all cases?
> > Neither "never" nor "noreturn" seems suitable for use in parameters, but
> > "nothing" would be.
>
> While slightly misleading, noreturn absolutely could work as a
> parameter type, it's just not part of this RFC.

Technically any keyword would be "suitable" in parameters.
But having "noreturn" as a parameter type would look weird.

I think we should decide now if the new keyword should be suitable as
a parameter type name in the future or not.

> I don't see why nothing would be more suitable than never.

For me "nothing" looks a bit more like a type name than "never".
But seeing in your link that this already exists in typescript, I can
live with "never" :)

To your example below:
For me the real use case would be formal interfaces or base classes.
Ofc this will become more relevant with generics, but can already be
useful now with reflection-based architectures.

interface FormalHarvester {
  function harvest(never $x);
}

interface GraintHarvester extends FormalHarvester {
  function harvest(Grain $x);
}

So, if we introduce the "never" keyword now as a return type, with
this future use case in mind, that seems to be fine for me.

>
>
> I do think noreturn/never in parameter types could potentially be
> useful as it would serve as static analysis information and a runtime
> check at the same time.
>
> https://stackoverflow.com/a/39419171/1320374
>
> ```
> function shouldNotHappen(never $never): void {}
>
> /** @param 1|2|3 $foo */
> function foo($foo) {
> switch ($foo) {
> case 1: return 'One';
> case 2: return 'Two';
> }
>
> // Static analyzer can understand this value is not never but 3
> // Throws a type error at runtime when reached as nothing can satisfy 
> never
> shouldNotHappen($foo);
> }
> ```
>
> Although it's worth noting that match doesn't have that problem as it
> throws implicitly on unhandled values. So maybe we should focus our
> efforts on making match usable with code blocks instead of just
> expressions.
>
> Ilija
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] noreturn type

2021-03-31 Thread Ilija Tovilo
Hi internals

On Wed, Mar 31, 2021 at 2:14 PM Andreas Hennings  wrote:
>
> Also check my comment in the other thread:
> If in the future we want a "bottom type" that also works for parameters
> (generics or abstract methods), should we create a new keyword, or should
> we attempt to find a keyword now that works for all cases?
> Neither "never" nor "noreturn" seems suitable for use in parameters, but
> "nothing" would be.

While slightly misleading, noreturn absolutely could work as a
parameter type, it's just not part of this RFC. I don't see why
nothing would be more suitable than never.

I do think noreturn/never in parameter types could potentially be
useful as it would serve as static analysis information and a runtime
check at the same time.

https://stackoverflow.com/a/39419171/1320374

```
function shouldNotHappen(never $never): void {}

/** @param 1|2|3 $foo */
function foo($foo) {
switch ($foo) {
case 1: return 'One';
case 2: return 'Two';
}

// Static analyzer can understand this value is not never but 3
// Throws a type error at runtime when reached as nothing can satisfy never
shouldNotHappen($foo);
}
```

Although it's worth noting that match doesn't have that problem as it
throws implicitly on unhandled values. So maybe we should focus our
efforts on making match usable with code blocks instead of just
expressions.

Ilija

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] noreturn type

2021-03-31 Thread Andreas Hennings
Also check my comment in the other thread:
If in the future we want a "bottom type" that also works for parameters
(generics or abstract methods), should we create a new keyword, or should
we attempt to find a keyword now that works for all cases?
Neither "never" nor "noreturn" seems suitable for use in parameters, but
"nothing" would be.

-- Andreas

On Wed, 31 Mar 2021 at 05:35, Peter Stalman  wrote:

> Aw, my `terminus` suggestion didn't make it. ☹️
>
> Thanks,
> Peter
>


Re: [PHP-DEV] [VOTE] noreturn type

2021-03-30 Thread Peter Stalman
Aw, my `terminus` suggestion didn't make it. ☹️

Thanks,
Peter


Re: [PHP-DEV] [VOTE] noreturn type

2021-03-30 Thread Matthew Brown
On Tue, 30 Mar 2021 at 12:55, Theodore Brown  wrote:

> On Tue, Mar 30, 2021 at 10:06 AM Matthew Brown 
> wrote:
>
> > Hey everyone!
> >
> > The vote for adding noreturn is now open:
> >
> > https://wiki.php.net/rfc/noreturn_type
> >
> > Voting will run through April 13th
>
> Hi Matt and Ondrej,
>
> Thanks for your work on this RFC. I voted for `never` as the type name
> because it's more amenable to future use cases like compile-time
> exhaustiveness checks (example:
>
> https://www.typescriptlang.org/docs/handbook/2/narrowing.html#the-never-type
> ).
>
> As a bonus `never` is more concise, avoids mashing two words together,
> and aligns with TypeScript, which I and many other PHP devs also use.
>
> Kind regards,
> Theodore


Awesome! The conciseness argument for "never" is already mentioned in the
RFC, as is TypeScript's use of the term.

Full disclosure (because neither of us is eligible to vote):
I slightly prefer "noreturn", and Ondrej strongly prefers "never".


Re: [PHP-DEV] [VOTE] noreturn type

2021-03-30 Thread Theodore Brown
On Tue, Mar 30, 2021 at 10:06 AM Matthew Brown  wrote:

> Hey everyone!
> 
> The vote for adding noreturn is now open:
> 
> https://wiki.php.net/rfc/noreturn_type
> 
> Voting will run through April 13th

Hi Matt and Ondrej,

Thanks for your work on this RFC. I voted for `never` as the type name
because it's more amenable to future use cases like compile-time
exhaustiveness checks (example:
https://www.typescriptlang.org/docs/handbook/2/narrowing.html#the-never-type).

As a bonus `never` is more concise, avoids mashing two words together,
and aligns with TypeScript, which I and many other PHP devs also use.

Kind regards,
Theodore
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



[PHP-DEV] [VOTE] noreturn type

2021-03-30 Thread Matthew Brown
Hey everyone!

The vote for adding noreturn is now open:

https://wiki.php.net/rfc/noreturn_type

Voting will run through April 13th

Best wishes,

Matt and Ondrej