On Sat, Apr 3, 2021 at 5:30 PM Benjamin Eberlei <kont...@beberlei.de> wrote:
> > > On Fri, Apr 2, 2021 at 3:14 AM Aaron Piotrowski <aa...@trowski.com> 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 >> >>