Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propose never type #1191

Merged
merged 2 commits into from Apr 13, 2022
Merged

Propose never type #1191

merged 2 commits into from Apr 13, 2022

Conversation

b1rdex
Copy link
Contributor

@b1rdex b1rdex commented Oct 10, 2019

This type should be used mainly as a return type to designate a function/method as a never returning back.
It shows that the function/method will always throw an exception or will call exit() or will call trigger_error() or will stop program execution in any other available way.

I'm not a native speaker, so it probably needs some description extension/correction.

This return type is available in many languages/tools:

  1. Kotlin — Nothing return type. See https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-nothing.html
  2. Hack lang — noreturn return type. See https://docs.hhvm.com/hack/built-in-types/noreturn (examples: https://github.com/facebookarchive/hack-langspec/blob/master/tests/Functions/noreturn.php)
  3. Vimeo Psalm — @return no-return PhpDoc type. See Add @return no-return to denote a function that never returns vimeo/psalm#1155 (comment)
    Also, there is a config option, but it's only for functions/static methods and is going to be deprecated/removed in the future.
  4. Phpstan has @return never PhpDoc type. See support type never in phpDoc phpstan/phpstan#1472
    Also, there is a config option and it's possible to specify dynamic method calls there too.
  5. Phan doesn't have this — see Custom exit/error functions phan/phan#2118, but they plan to add it.
  6. PhpStorm doesn't have this feature, but they plan to add it and the PhpDoc tag is not decided yet. See https://youtrack.jetbrains.com/issue/WI-10673

This type should be used mainly as a return type to designate a function/method as a never returning back.
It shows that the function/method will always throw an exception or will call `exit()` or will call `trigger_error()` or will stop program execution in any other available way.

This return type is available in many languages/tools:
1. Kotlin — `Nothing` return type. See https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-nothing.html
2. Hack lang — `noreturn` return type. See https://docs.hhvm.com/hack/built-in-types/noreturn (examples: https://github.com/facebookarchive/hack-langspec/blob/master/tests/Functions/noreturn.php)
3. Vimeo Psalm — `@return no-return` PhpDoc type. See vimeo/psalm#1155 (comment)
+ they have config option, but it's only for functions/static methods and is going to be deprecated/removed in the future.
4. Phpstan has @return never PhpDoc type. See phpstan/phpstan#1472
+ they have config option and it's possible to specify dynamic method calls there too.
5. Phan doesn't have this — see phan/phan#2118, but they plan to add it.
6. PhpStorm doesn't have this feature, but they plan to add it and the PhpDoc tag is not decided yet. See https://youtrack.jetbrains.com/issue/WI-10673
@JanTvrdik
Copy link

@Jean85
Copy link
Member

Jean85 commented Dec 3, 2019

I would personally prefer never, because I feel that Nothing can be mistakenly considered like void, which is a different beast.

@b1rdex
Copy link
Contributor Author

b1rdex commented Dec 9, 2019

Update: upcoming PhpStorm 2020 version will have support for exit points via meta files: https://youtrack.jetbrains.com/issue/WI-10673#focus=streamItem-27-3775062.0-0

@GrahamCampbell
Copy link
Contributor

GrahamCampbell commented Dec 10, 2019

Technically, void is the best type for this, and Unit should be used in place of void. If we view types as sets, then void is the empty set, so, nothing can be of type void, so any function typed with void cannot return anything, so cannot return... it has to exit abnormally. Unit can be viewed as the singleton set. There is only one choice of what to return, so essentially the function has no choice in what it returns.

PHP's (and Java/C like langauges) void is most like "Unit", and no-return would be like "void".

@marc1706
Copy link

Coming from a C/C++ standpoint, void functions cannot return anything. That part is correct. However, void functions are expected to exit normally. Hence and as was mentioned above, signifying this with "void" will be very confusing.
I'd agree with using never as that is very clear that this is "the end of the road". ;)

@GrahamCampbell
Copy link
Contributor

Coming from a C/C++ standpoint, void functions cannot return anything.

Well, formally, they do. From a formal standpoint, the only way to return nothing is to non-terminate, or kill the process, or do something else funky with control, like throwing an exception.

@Crell
Copy link
Contributor

Crell commented Dec 12, 2019

To clarify, since there seems to be some confusion on this point, I believe the proposal is for "this method goes into an infinite loop, by design"; That's different from "this method returns nothing", which is already fully covered by void in PHP.

@b1rdex Is that correct?

@b1rdex
Copy link
Contributor Author

b1rdex commented Dec 13, 2019

To clarify, since there seems to be some confusion on this point, I believe the proposal is for "this method goes into an infinite loop, by design"; That's different from "this method returns nothing", which is already fully covered by void in PHP.

@b1rdex Is that correct?

Yes, it is. Every link to other languages mentioned here has this statement: such return type indicates that the method will exit program or throw exception always, so it'll never return or continue normal execution of a program.

staabm added a commit to redaxo/redaxo that referenced this pull request Jan 26, 2020
@jpickwell
Copy link

jpickwell commented Jul 14, 2020

I'd say never is a better word to represent the idea of "never returns" as opposed to no-return (@return no-return is a tautology) or void which means "nothing"; e.g., @return void means "returns nothing", @return never means "never returns".

@return none is too similar to @return void. So, I do not recommend the use of none over the better term never.

An alternative could be to instead add a new tag; e.g., "@never-returns".

@ashnazg
Copy link
Contributor

ashnazg commented Jan 30, 2021

I like the idea of never here rather than no-return, for the non-hyphenated string if nothing else.

@JanTvrdik , I assume this is still valid in PHPStan?

@muglug , would it be too burdensome to deprecate no-return in favor or never?''

Then again, we could just leave it out of the spec, as a customization that's unstandardized in the tools.

@Crell
Copy link
Contributor

Crell commented Jan 30, 2021

If this is included, I would recommend either:

@return never

or

@noreturn / @no-return

I don't have a strong feeling on which one is better.

@shadowhand
Copy link
Contributor

I prefer @return never but I don't have a strong feeling either way.

@b1rdex
Copy link
Contributor Author

b1rdex commented Jan 31, 2021

I like the idea of never here rather than no-return, for the non-hyphenated string if nothing else.

@JanTvrdik , I assume this is still valid in PHPStan?

@muglug , would it be too burdensome to deprecate no-return in favor or never?''

Then again, we could just leave it out of the spec, as a customization that's unstandardized in the tools.

@return never and @return no-return are supported by the both tools currently.

@rob006
Copy link

rob006 commented Jan 31, 2021

@return never looks ambiguous. What if I have class called never?

@JanTvrdik
Copy link

@rob006 It's exactly as ambiguous as most other keywords. You can have class named Boolean, Integer or Resource. In older PHP versions you could have class named Int or String.

@rob006
Copy link

rob006 commented Jan 31, 2021

@JanTvrdik Now you can't have class Int or String. boolean and integer were discouraged/deprecated as party of PSR-12. It is clear that ecosystem tries to get rid of these ambiguities. What is the point of repeat the same mistakes again and introduce another ambiguities in new specs? @noreturn does not have this problem, it is shorter and does not look like a hack (this is not about what type function returns, but how it behaves, so reusing @return for completely different purpose is just inconsistent). It may also directly translate to attribute like NoReturn, since it is not a special case for @return.

@b1rdex
Copy link
Contributor Author

b1rdex commented Feb 1, 2021

@JanTvrdik Now you can't have class Int or String. boolean and integer were discouraged/deprecated as party of PSR-12. It is clear that ecosystem tries to get rid of these ambiguities. What is the point of repeat the same mistakes again and introduce another ambiguities in new specs? @noreturn does not have this problem, it is shorter and does not look like a hack (this is not about what type function returns, but how it behaves, so reusing @return for completely different purpose is just inconsistent). It may also directly translate to attribute like NoReturn, since it is not a special case for @return.

Why would you invent a new thing while there is already a way to annotate it that is supported/used by popular SCA tools?
no-return and never are already used in libraries and app codes: https://github.com/search?l=PHP&q=no-return&type=Code https://github.com/search?q=%22%40return+never%22&type=Code

Also, never (or whatever it's named) is a type, and it's correct to have it as a return type. Please look at the examples in the first and the second posts.

@rob006
Copy link

rob006 commented Feb 1, 2021

Also, never (or whatever it's named) is a type, and it's correct to have it as a return type.

never is not a type in PHP and it does not have any special meaning (so you can create class with that name, and then it is a type, but not with the meaning you're expecting). Tools will complain about it, for example PhpStorm:
30bf6a83

This is probably a reason why it is mostly used as tool-specific tag (@phpstan-return never), sometimes in pair with regular @return void. Why would you invent new thing that is straight incompatible with existing tools and contradicts common interpretation of how @return annotation works? And again, @noreturn does not have this problem, since unknown tags should be ignored, so you can use new standard with tools that does not support it (at least they will not complain that return type is incorrect).

@b1rdex
Copy link
Contributor Author

b1rdex commented Feb 1, 2021

never is not a type in PHP and it does not have any special meaning (so you can create class with that name, and then it is a type, but not with the meaning you're expecting).

Sure it's not. That's why this thread exists at all :D

Tools will complain about it, for example PhpStorm

PhpStorm supports @return no-return. And even understands it as an exit point:
image

@alfredbez
Copy link

alfredbez commented Mar 11, 2021

There is now a RFC to get something like this into the core: php/php-src#6761

proposed/phpdoc.md Outdated Show resolved Hide resolved
proposed/phpdoc.md Outdated Show resolved Hide resolved
@b1rdex
Copy link
Contributor Author

b1rdex commented Mar 30, 2021 via email

Copy link
Contributor

@caugner caugner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meanwhile, the vote ended in favor of the never return type, and the implementation was merged in php/php-src@6cd0b48.

Accordingly, no-return should be renamed to never in this PR.

proposed/phpdoc.md Outdated Show resolved Hide resolved
proposed/phpdoc.md Outdated Show resolved Hide resolved
Co-authored-by: Claas Augner <github@caugner.de>
@caugner
Copy link
Contributor

caugner commented Jul 2, 2021

@b1rdex Would you mind renaming no-return in the PR title as well?

@b1rdex b1rdex changed the title Propose no-return type Propose never type Jul 2, 2021
@ashnazg ashnazg merged commit 44a91bc into php-fig:master Apr 13, 2022
@ashnazg
Copy link
Contributor

ashnazg commented Apr 13, 2022

never did get implemented into the language...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet