Re: [PHP-DEV] [Pre-RFC] Convert exit (and die) from language constructs to functions

2024-02-27 Thread Claude Pache

> 
> I hear you, but what about exit; ?!
> Do not worry exit; is still supported!
> It only requires a _tiny_ bit of dark magic to achieve this!
> exit; would just be interpreted as a fetch to a constant,
> so when attempting to access the undefined exit/die case-insensitive constant
> we just need to exit as if we were calling the function!
> 

Hi Gina,

If it is mostly an implementation detail, this is probably ok. However, please 
make sure that `$foo = 'exit'; constant($foo);` (or any other future way to 
interpolate the constant) does not stop the program, but only fetch the value 
of a “real” constant.

Alternatively, it is probably possible to keep the current parsing with T_EXIT, 
but to make it equivalent to invoke a “regular” function named `exit()` — 
somehow the same way that using the backtick operator is equivalent to calling 
`shell_exec()`, up to the point that disabling `shell_exec()` will also disable 
the the backtick operator?

(BTW, it *is* currently possible to define and use a constant named “exit”: 
https://3v4l.org/aBq2R — of course, no need to keep such a “feature”.)

—Claude

Re: [PHP-DEV] [Pre-RFC] Convert exit (and die) from language constructs to functions

2024-02-24 Thread Gina P. Banyard
On Saturday, 24 February 2024 at 11:46, Kamil Tekiela  
wrote:

> I would actually be against this change. It's a language construct for
> a reason. Functions can be disabled and overridden, but language
> constructs cannot. Exit is supposed to end the script execution
> without any hidden quirks.
> 
> I don't actually see any good reason to make it a function. You can
> very easily solve your pet peeve in userland by simply wrapping exit
> in a function.
> function my_exit(int|string $value):never { exit($value); }
> You can then pass this function as a callable, redefine it in a
> namespace, and it obeys the normal function type juggling rules.
> 
> This is reminiscent of Python 2 -> 3 migration with the print
> 
> statement to a print function change. While you may think you see good
> reasons to make this change, users may see it as trivial and unworthy
> of all the fuss.
> 
> Unless there is some extremely good reason to make exit a function, I
> would advise against doing it.

I'm impressed by the fact that one seems to ignore what my first email says.
It can be a function AND NOT be disabled by the disable_functions INI setting.
It can be a function AND NOT be able to define a custom exit()/die() function 
in a namespace, this is similar to assert() which is also not a language 
construct (which _can_ de disabled with the disable_functions INI setting).
It can be a function AND NOT have _any_ user facing changes.

The PR is implemented in a way so that there is no BC break at all for 
userland, except AST-based tools.
And people have suggested a way to not break AST tools, by transforming exit; 
into exit(); at compile time.

I also find it extremely weird that it is acceptable that exit() has its own 
completely weird type juggling semantics that break user expectations,
when it looks like a function. What is the reason to force users to know and 
learn this weird quirk about exit?

Also, comparing this to the Python 2 to 3 migration with print is *totally* 
disingenuous,
you cannot write: exit 10; or exit "Hello"; if you do, you get a parse error.
I am not suggesting to make require, or echo, or print be functions as that 
_would_ be similar to the Python 2 to 3 migration, and I agree that would be a 
bad idea.

This change just makes the language more consistent and removes one type 
juggling context.

I realize that I probably should have just spent time writing an RFC and doing 
the discussion directly, as I'm effectively laying out the arguments why we 
should do this in an email.

Best regards,

Gina P. Banyard


Re: [PHP-DEV] [Pre-RFC] Convert exit (and die) from language constructs to functions

2024-02-23 Thread Juliette Reinders Folmer



On 24-2-2024 3:47, Gina P. Banyard wrote:



On Saturday, 24 February 2024 at 01:57, Juliette Reinders Folmer 
 wrote:



Hi Gina,

I'm not sure a pet-peeve is a good motivation for creating an (I 
expect large) breaking change.


The upgrade path, I suppose, would be updating calls to `die`/`exit` 
to always have parentheses ? Or alternatively changing those calls to 
new throw expressions ?


While that shouldn't be that huge a problem for real codebases (and 
would be auto-fixable for adding the parentheses), the bigger problem 
I see is the huge amount of teaching materials, tutorials and blog 
posts using the versions without parentheses which will now all be 
invalidated. I think the pain and confusion that will cause for a 
change like this, will linger for years and years.


Smile,
Juliette



I didn't actually know one could do exit;
But like I said, it is extremely easy to support, and the current PR 
does support it by hooking into the undefined constant code in the engine.

I don't have strong opinions about removing support for this.
However, I do have strong opinions about changing the type juggling 
semantics of exit() to be the usual ones, because the current one is 
just confusing.
I am also not sure what would make this a large breaking change, as 
changing this from a language construct to a function provides us with 
more capabilities.




Ah, I think I missed the part about the syntax both with and without 
parentheses still being supported, with the "with parentheses" mapping 
to a function call and the "without parentheses" mapping to a 
case-insensitive constant.


In that case, I don't see a BC-break and I would regard this as an 
"under the hood" change with only a very subtle, minimal impact (the 
type checking part if a param is passed).


I do wonder what the documentation would look like as it would leave it 
as a function, but one with a special status, in that there is a native 
constant of the same name which will enforce the same behaviour.


Smile,
Juliette





Re: [PHP-DEV] [Pre-RFC] Convert exit (and die) from language constructs to functions

2024-02-23 Thread Gina P. Banyard
On Saturday, 24 February 2024 at 01:57, Juliette Reinders Folmer 
 wrote:

> Hi Gina,
>
> I'm not sure a pet-peeve is a good motivation for creating an (I expect 
> large) breaking change.
>
> The upgrade path, I suppose, would be updating calls to `die`/`exit` to 
> always have parentheses ? Or alternatively changing those calls to new throw 
> expressions ?
>
> While that shouldn't be that huge a problem for real codebases (and would be 
> auto-fixable for adding the parentheses), the bigger problem I see is the 
> huge amount of teaching materials, tutorials and blog posts using the 
> versions without parentheses which will now all be invalidated. I think the 
> pain and confusion that will cause for a change like this, will linger for 
> years and years.
>
> Smile,
> Juliette

I didn't actually know one could do exit;
But like I said, it is extremely easy to support, and the current PR does 
support it by hooking into the undefined constant code in the engine.
I don't have strong opinions about removing support for this.
However, I do have strong opinions about changing the type juggling semantics 
of exit() to be the usual ones, because the current one is just confusing.
I am also not sure what would make this a large breaking change, as changing 
this from a language construct to a function provides us with more capabilities.

Best regards,
Gina P. Banyard

Re: [PHP-DEV] [Pre-RFC] Convert exit (and die) from language constructs to functions

2024-02-23 Thread Juliette Reinders Folmer

On 24-2-2024 2:37, Gina P. Banyard wrote:

Hello internals,

I've been having this mild annoyance with exit()/die() since I wrote a CLI
script using a boolean $hasErrors variable to know if the script failed or not
and to indicate if the script failed via a non-zero status code by doing:
exit($hasErrors);

However, it turns this doesn't work, because exit() will cast everything
that is not an integer to a string, something that I find surprising but
also weird as it will not type error on resources or array but rather print
the warning to the CLI.

Anyway, yesterday I decided to put on my mad scientist lab coat and make this
a reality, I have a W.I.P. PR here:
https://github.com/php/php-src/pull/13483

I hear you, but what about exit; ?!
Do not worry exit; is still supported!
It only requires a _tiny_ bit of dark magic to achieve this!
exit; would just be interpreted as a fetch to a constant,
so when attempting to access the undefined exit/die case-insensitive constant
we just need to exit as if we were calling the function!

Having exit and die be functions gives us access to some interesting
functionality, such as defining exit() in a namespace, or removing it via the
disable_functions INI setting (the latter allowing us to define a custom global
exit() which could be useful for testing that a function actually calls exit).

We can also pass it like any other callable and reflect on it with reflection.

Finally, this removes the T_EXIT token and ZEND_EXIT opcode freeing one slot.

The W.I.P. PR implement every possible restriction:
  - not being able to declare an exit()/die() function
  - not being able to disable them
  - not being able to define a constant named exit/die

Maybe it would be wise to deprecate using exit as a statement to be able to get
rid of the undefined constant magic handling.

Anyhoot, before I spend more time on this and write a proper RFC, do people
think this is a good idea or not?


Best regards,

Gina P. Banyard



Hi Gina,

I'm not sure a pet-peeve is a good motivation for creating an (I expect 
large) breaking change.


The upgrade path, I suppose, would be updating calls to `die`/`exit` to 
always have parentheses ? Or alternatively changing those calls to new 
throw expressions ?


While that shouldn't be that huge a problem for real codebases (and 
would be auto-fixable for adding the parentheses), the bigger problem I 
see is the huge amount of teaching materials, tutorials and blog posts 
using the versions without parentheses which will now all be 
invalidated. I think the pain and confusion that will cause for a change 
like this, will linger for years and years.


Smile,
Juliette