Re: [PHP-DEV] [Pre-RFC Discussion] User Defined Operator Overloads (again)
On 14.09.24 23:48, Jordan LeDoux wrote: 1. Should the next version of this RFC use the `operator` keyword, or should that approach be abandoned for something more familiar? Why do you feel that way? 2. Should the capability to overload comparison operators be provided in the same RFC, or would it be better to separate that into its own RFC? Why do you feel that way? 3. Do you feel there were any glaring design weaknesses in the previous RFC that should be addressed before it is re-proposed? 4. Do you feel that there is ANY design, version, or implementation of operator overloads possible that you would support and be in favor of, regardless of whether it matches the approach taken previously? If so, can you describe any of the core ideas you feel are most important? Hello Jordan, Happy you are following up on operator overloads, as I was sad to see the vote fail last time. I think the RFC might benefit from focusing on the comparison operators and the basic arithmetic operators this time, so ==, <=>, +, -, *, / (and maybe % and **). I would especially leave out the bitwise operators (for a possible future RFC), as those to me seem extra niche and not very self-explanatory in terms of good use cases/examples. ==, <=>, +, -, * and / would deliver almost all the benefits to operator overloading I can currently think of. Giving more concrete examples in the RFC of places in the current PHP ecosystem where these operators would simplify code might be helpful - the last RFC had mainly a generic list of use cases, but seeing actual code would help to make it salient how some code can be a lot more readable, especially if you now know about even more use cases than 3 years ago. Otherwise I am hoping that more opponents of operator overloads will chime in and give some constructive feedback.
Re: [PHP-DEV] [Pre-RFC Discussion] User Defined Operator Overloads (again)
On 17.09.24 11:14, Mike Schinkel wrote: How would a developer know if they are using an object that has operators, unless they study all the source code or at least the docs (assuming there are good docs, which there probably are not?) How is that different from using a method on an object? Operators are roughly speaking a different syntax for methods, and if you use an object method, you have to know about it or look up what it does. Also, getting to the implementation of operators would likely be just as easy as looking up methods nowadays, because IDEs would support that kind of lookup. Situation where there is free-reign userland operator overloading: Junior developer Joe is using Symfony and learns about this great new operator overload feature so decides to implement all the operators for all his objects, and now he wants to start passing his objects to Symphony code. Joe decides to be clever and implement "/" to concatenate paths strings together but doesn't type his properties, and he ends up passing them to a Symfony function that uses `/` for division, and his program crashes with very cryptic error messages. He reports them to the Symfony developers, and it wastes a bunch of time for everyone until they finally figure out why it failed, because nobody every considered a developer would do such a thing. Most framework and library code is by now type-hinted - I would have understood this argument when operator overloading would be implemented into PHP 5.x, where many classes and functions got values and had no enforced types, so they might have expected an int, yet an object with operator overloading might work but in weird ways, because there were no type hints for int. I cannot see this situation now at all - if a Symfony component wants an int, you cannot pass in an object. If a Symfony component wants a Request object, it will not use operators that it does not expect to be there, even if you would extend the class and add operator support. Using operators implies you know you can use operators, otherwise it will be a fatal error (except for comparisons). From your arguments it also seems you are afraid everybody will use operator overloading excessively and unnecessarily. This seems very unlikely to me - it is not that useful a feature, except for certain situations. Many other languages have had operator overloading for many years of even decades - are there really huge problems in those languages? If yes, maybe PHP can learn from some of the problems there (which I think the original RFC tried to carefully consider), but as far as I know the usage of operator overloading is niche in languages which support it, depending on use case - some people like it, some don't, but they do not seem to be a big problem for these languages or their code in general. Maybe you have some sources on actual problems in other languages? Personally I would love my Money class to finally have operators instead of the current "plus", "minus", "multipliedBy" (and so on) methods which are far less readable. I would only use operator overloading on a few specific classes, but for those the readability improvement would be huge. Also, being able to override comparison operators for objects would be very useful, because currently using == and === with objects is almost never helpful or sufficient.
Re: [PHP-DEV] [RFC] Default expression
On 26.08.24 11:26, Bilge wrote: Thanks for this question; I find this super interesting because it's something we haven't thought about yet. I must admit I completely overlooked that, whilst an interface /can/ require implementers to specify a default, in the case that they do not, it is still valid for implementations to selectively elect to provide one. Therefore I can append to your example the following case (I removed the `string` return type for now): class ZipCompression implements CompressionInterface { public function compress(string $data, int $level) { var_dump($level); } } new GzipCompression()->compress('', default ?? 6); new ZipCompression()->compress('', default ?? 6); In this case, we get the following output: int(4) Fatal error: Uncaught ValueError: Cannot pass default to required parameter 2 of ZipCompression::compress() I would like to fix this if possible, because I think this should be valid, with emphasis on /if possible/, because it may be prohibitively complex. Will update later. That would be a way to fix it, to basically make isset(default) a possible check if there is no default, similar to an undefined variable check. It would also recognize a default value of null as not set in the same way, so one could not differentiate between null and not defined, but that is in line with the language in general.
Re: [PHP-DEV] [RFC] Default expression
On 24.08.24 18:49, Bilge wrote: Hi gang, New RFC just dropped: https://wiki.php.net/rfc/default_expression. I think some of you might enjoy this one. Hit me with any feedback. This one already comes complete with working implementation that I've been cooking for a little while. Considering I don't know C or PHP internals, one might think implementing this feature would be prohibitively difficult, but considering the amount of help and guidance I received from Ilija, Bob and others, it would be truer to say it would have been more difficult to fail! Huge thanks to them. Cheers, Bilge Hello Paul, I think this is an interesting addition to the language. Personally, I would replace the full expression list at the end of the RFC with more examples in real-world scenarios for most of these cases. As far as I skimmed the discussion, there is some worry of "wrong use" (which I do not necessarily share). Showing more examples could be useful to focus on how having default being a full expression gives interesting use cases, instead of talking about what (in isolation) nonsensical code people might write. For me there is another question. When using interfaces and classes, default values can be introduced, like this: interface CompressionInterface { public function compress(string $data, int $level): string; } class GzipCompression implements CompressionInterface { public function compress(string $data, int $level = 4): string { // do something } } When I have the GzipCompression class, I would know there is a default value for $level, but when using the interface there might or might not be a default value, depending on the implementation. As far as I read the RFC, using "default" when there is no default would lead to a runtime exception, but there is no way of finding out if there is a default if you do not already know. Being able to test that could be useful, although I am not sure about the syntax for that. In the example when getting CompressionInterface, I might test for the existence of a default value of $level and leave it at the default if there is a default (maybe I know that some implementations have a default value, others don't). One could test the specific implementation with instanceof checks, but the advantage of "default" could be that you do not need to know the implementation and could only adapt to possibly defined default values.
Re: [PHP-DEV] Passing null to parameter
On 10.11.23 12:33, Craig Francis wrote: On 10 Nov 2023, at 10:54, Alex Wells wrote: PHPStan does find them:https://phpstan.org/r/38fc1545-2567-49b9-9937-f275dcfff6f5 It does not: https://phpstan.org/r/c533ff42-80e4-4309-9751-1ec79e359946 Psalm does give you a PossiblyInvalidArgument here, PHPStan will likely detect this soon too, as both static analyzers are covering more and more ground. Also note that in your example $q could be an array (leading to a fatal error in the code)from the request data, which is why checking types thoroughly (not just coercing them with strval) can be helpful in avoiding unexpected situations and deciding how to handle such situations, instead of yolo-ing it.
Re: [PHP-DEV] Future stability of PHP?
On 11.04.23 15:56, Jeffrey Dafoe wrote: So turn off the deprecation warnings for now. They're just a heads up that behaviour is going to change in the future, with PHP 9. I doubt you'd prefer not to be aware of the change well in advance. Oh, absolutely. We run those "on" in our dev and QA environments but off in production. I'm referring to the work required to mitigate the removal once we plan to migrate to 9. Although our codebase is old, we are funded to keep the code up to date. It's just that a handful of the changes, such as removing dynamic properties, has such a large impact and such a questionable benefit. Removing dynamic properties has multiple benefits - from avoiding typos/mistakes (which before were completely silent) from being able to refactor objects in PHP in general (after PHP9) to be more efficient. The RFC (https://wiki.php.net/rfc/deprecate_dynamic_properties) details those benefits quite well, if there were no benefits it would hardly have passed. This is one of the no-brainer changes for me, as the upgrade path with the attribute is so easy and there are so many benefits. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Future stability of PHP?
On 10.04.23 01:44, Deleu wrote: Over the course of PHP 7 and 8, there were significant concerns on how problematic PHP deprecations and breaking changes were. Now we're starting to see the result of such concerns being ignored. This isn't the first time someone mentions on PHP internals that it's getting harder and harder to stay with PHP, but it's never really received with an open mind. It's either "you don't have to run deprecation-free code" or "you've had years to get rid of that deprecation error, tough luck if you didn't". I love PHP and I built my career around it. I have zero interest in starting from scratch in another language, but I've lost count on how many projects, friends and companies around me have already made the switch to Typescript. It's getting harder and harder to argue in favour of staying with PHP. The PHP ecosystem even just in the last 10 years has changed completely, with composer, more mature frameworks, easily usable independent components and even static analyzers. For me that ecosystem is the big value proposition of PHP, in addition to a good standard library. Typescript has a completely different value proposition, and the language itself is usually not the deciding factor, as there is so much more to it. Only through the deprecations and the type system does PHP even offer some similar features as Typescript - like type checks and the possibility of a static analyzer. If all these changes would not have happened, people likely would argue even more that they had to switch to Typescript, because of the missing type safety in PHP. Nowadays there are even tools now like Rector that can help you automatically upgrade your codebase - that is also a new value proposition. My projects were affected by all the new warnings, deprecations etc. over the years, but I found countless bugs because of those (and many bad choices - is count($string) really what I wanted?). The language warning you when you are likely doing something with little sense is a huge value proposition - otherwise why are people using Typescript instead of Javascript? It would be interesting to know why some people are having such huge problems upgrading their applications, as I think those would often be good stories with something to learn in them. So to the original poster or other people with big problems when upgrading, writing a blog article detailing what happened would be helpful to evaluate if the PHP project could improve something, or even why something broke. And just as a sidenote: I never have more things breaking than when trying to upgrade a JS/TS-project, because of changes in NodeJS, because of slight breaks in dependencies, etc. To me that clearly works better in PHP, but experiences can differ. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Revisiting RFC: Engine Warnings -- Undefined array index
On 13.12.22 13:53, Dan Liebner wrote: It breaks my app. Does that count? This sounds like you completely ignore notices in your application yet elevate warnings to exceptions/errors. It would be better to log both notices and warnings without generating exceptions/errors, and look through those logs from time to time, to see possible issues (and nothing would currently break that way). I used to suppress notices in my applications too, but after logging them it was my experience that notices can usually be easily avoided and often hint at oversights / possible improvements. Here's another suggestion: Make accesses to undefined array keys (objects, variables, etc) return a new `undefined` primitive. That way, developers who are focused on writing concise, readable code can continue to write and maintain code manageably, and developers who are keen on writing a lot of code in a more "strict" manner can handle undefined array key accesses consistently, without having to rely on configuration settings. That would likely be a major change and break in the language (which is usually frowned upon), but if you have a clear concept, you can create an RFC for it and start a discussion. I do think that your view on "concise, readable code" would in my mind be code which is more prone to bugs and unclear in its intentions. If an array index possibly does not exist and you check its value, it would already be unclear to me if you mean to check for its existence, or for a null value, or for a non-empty string, or something else. Making it clear the index might not exist gives a reader more information, and making the expected types (and checks) clearer in general is not an exercise to be strict for fun, but to avoid bugs because of unexpected values. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Revisiting RFC: Engine Warnings -- Undefined array index
On 13.12.22 11:01, Robert Landers wrote: intended: ($a['foo'] ?? null) || ($a['bar'] ?? null) Further, writing code like this increases the number of opcodes needed to perform relatively simple logic by ~150%, increasing end-user latency and spending CPU cycles somewhat needlessly. I think it is quite the opposite: calling the error handler because of E_NOTICE (or now E_WARNING) is quite the additional overhead, and if projects just ignore E_NOTICE their applications will be slowed down because of that, while fixing the code will avoid the error handler altogether. Just because something is longer to write in a programming language also does not make it necessarily slower. But if you have any actual measurements why using the null coalescing operator would slow down code in general that would be something useful to share. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC json_validate() - status: Under Discussion
On 26.08.22 11:00, Michał Marcin Brzuchalski wrote: A `json_decode()` is a substitute that IMO solves 99% of use cases. If I'd follow your logic and accept every small addition that handles 1% of use cases, somebody will raise another RFC for simplexml_validate_string or yaml_validate and the next PhpToken::validate. All above can be valid if we trust that people normally validate 300MB payloads to do nothing if they DON'T fail and there is nothing strange about that. There is already a way to validate XML in PHP, and Yaml or PHP is something within the control of a PHP programmer, while JSON is mostly used as a format for communication in APIs, so you never know what you get. If with a new function it becomes much easier to defend against a Denial-of-Service attack for some parts of a JSON API, then this can be a good addition just for security reasons. But this reason, which most resonates with me, is currently missing in the RFC, so I would suggest to add that fast / efficient validation of a common communication format reduces the attack surface for Denial-of-Service attacks. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] Stricter implicit boolean coercions
The vote has been closed, the RFC has been declined with 14 to 3 votes. It would have been interesting to get some more feedback on why people voted No - some took part in the discussion, but most didn't. My assumption is that most didn't find this important enough, especially if strict types is not affected. While I think the RFC would have helped identify obvious bugs (and I find the current behavior of PHP with boolean coercions less than ideal), I can see an argument for voters to not see it as something important enough to change the language, as the problems this RFC would have highlighted can be avoided altogether. If anybody still wants to give some insight on these reasons or a way to improve boolean coercions in another way, I would be happy to hear it. Otherwise thanks to everybody who took part in the discussion, it was an interesting experience. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
[PHP-DEV] [VOTE] Stricter implicit boolean coercions
Hello Internals, I opened the vote about Stricter implicit boolean coercions as announced. The vote will run until 2022-06-20. Discussion: https://externals.io/message/117732 RFC: https://wiki.php.net/rfc/stricter_implicit_boolean_coercions Best regards, Andreas Leathley
Re: [PHP-DEV] [Discussion] Stricter implicit boolean coercions
I have amended the RFC on https://wiki.php.net/rfc/stricter_implicit_boolean_coercions to address the feedback I got so far, I also added an overview of scalar type coercions to give a better sense of how these changes fit in with current type coercion behavior, and I added a Future Scope section with my plans to at some point do a follow-up RFC to make the implicit scalar type coercion behavior available to PHP developers explicitly and why that might make sense. Does anyone have any more feedback or questions on this, or something that is not considered? If not, I would start voting on Sunday (5th of June), but I am happy to extend the discussion time if needed. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] Stricter implicit boolean coercions
On 24.05.22 15:33, Dan Ackroyd wrote: "When discussion ends, and a minimum period of two weeks has passed" Fyi, the two weeks is a minimum, and almost certainly not enough time for subtle BC breaking RFCs like this. I explicitely stated that to make it clear that this should be considered a discussion period. I am not trying to circumvent anything, just make it clear that now is the time to discuss this. And I am ready to fully discuss this, as hopefully I have shown so far. I am also not sure what you mean with "subtle BC breaking RFCs". How is this RFC subtly BC breaking? It introduces a deprecation notice, that is it - for one that is not subtle, it is explicit, and it does not break BC except for introducing said notice. Is that not the very minimal BC break you can achieve to highlight a possible problem in code? I think you should really explicitly list what the changes are in a single table rather than in sentences. What do you think is unclear, and what would you include in such a table? In the Proposal section I listed all values which are considered allowed, and I tried to include more examples there too to highlight the outcome. The behavior is not changed by this RFC. Would you want to know when a value like -375, “false” or NaN is given to a typed boolean (and coerced to true) in a codebase? Yes. Which is why I always use both PHPStan and Psalm to detect those types of things where those types of bugs are important. Also, strict mode is great. Even when using PHPStan and Psalm you can encounter such a value, for example coming from a form, or an API. Using strict mode is a possibility, but also a big hammer - so how do you coerce a value coming from a form in strict mode? With an explicit coercion like (bool) or boolval()? Because there you might also be losing information unexpectedly - I do have some ideas to enable implicit coercions in strict mode, because you might not want to convert "failed" from an API to true by using explicit coercions, in my applications I would prefer to at least notice or even throw an exception in such cases, and the programming language streamlining this could be helpful. In one application recently I actually had the string "false" (coming from a form transmission) being passed to a boolean argument and leading to true, which definitely was unintended. But "false" is a perfectly sensible thing to pass as a string in an API (as HTTP is a string based protocol). As is 'faux' if your API is used by French speaking programmers. You need an layer of code that converts from strings to the precise types your API needs, rather than just passing values straight through. That sounds good in theory, but it is the exact thing that is so hard in practice, when dealing with forms, APIs, different programming languages, different human languages, different input formats, changing code, etc. I am not against writing great code and checking all values all the time, but I do think this is not the reality. Although this change would probably detect some bugs, it's not at all obvious that the amount of pain would be worth it. A lot of applications out there aren't being constantly developed. Instead they are in maintenance mode, where there isn't a programmer dedicated to constantly work on it. There would be lots of function calls to check, and some of them would need code to be modified to maintain the existing behaviour. And all of that would seem to be subtle work, prone to mistakes. Earlier you argued that there is no need to detect -375, "false" or NaN being coerced to a boolean type, because one can use strict mode and static analyzers, now you argue that legacy applications would have too much work generated by this RFC. But I don't quite understand why: This RFC introduces deprecation notices, not TypeErrors. It does not force legacy applications to change anything, it just points out boolean coercions that seem dodgy. If these deprecation notices provide little value in the upcoming years, there is no need to promote them to a TypeError, they could even be removed again - but I do think they will provide value and often point out bugs, so much so that a TypeError will seem reasonable at some point in the future, but there really is no hurry in escalating it. For now just being able to notice these boolean coercions would make a huge difference. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] Stricter implicit boolean coercions
On 23.05.22 20:58, Juliette Reinders Folmer wrote: All in all, I largely agree with the flaws in this proposal as previously pointed out by Christian Schneider in the preliminary discussion. And I don't see those concerns addressed in the RFC (other than making it more explicit what the actual intended change is). I amended the RFC and tried to address and include all of your points, as well as made it clearer what the intention of the RFC is. Adding the behavior of the filter extension was a sensible addition, I didn't even think of its special behavior before you mentioned it, and going into more detail about the other boolean coercions in PHP was also something that needed a more explicit section in the RFC, as it has been brought up by different people in different contexts already and I seem to have prematurely dismissed its importance so far. If you still think other concerns are not addressed I would be happy to know about them. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] Stricter implicit boolean coercions
On 23.05.22 22:54, G. P. B. wrote: I don't like this RFC as it introduces special coercion semantics for boolean *only* in a function (+ typed properties (well at least I hope it impacts typed properties)) context. The obvious other context is the logical one with conditional statements and/or boolean operators (&&, ||, etc.) where it is pretty typical to do if ($string) {} and use $string as a boolean value. Having this be true in some contexts and false in others, depending on the content of the string is far from ideal. However, implicit coercion to bool can also arise when doing comparisons where one of the operands is null or bool. In this case which semantics should be used? The problem is that coercion to a typed boolean is not the same as checking an expression for truthiness. It is somewhat related, but when there is a coercion to a typed boolean only scalar values can be coerced, which makes a big difference. Something like if (['']) is basically the same as if ([''] == true) which is why I call it checking for truthiness. Yet $obj->booleanProperty = ['']; will lead to a type error. So there is a clear difference there already. I also think the expectation is a different one - something like if ($string) is, as far as I have seen, most often used to check if a string it not empty. Yet if you do $obj->booleanProperty = $string; you then seem to specifically want to end up with a boolean type, not do a fuzzy check for truthiness. To me that is a very different situation where I actually find the current behavior surprising, in that is does not matter at all what scalar value I give a typed boolean, it will be happy with anything, and if it was a long string that was converted to boolean, you do possibly lose information. That can easily happen if someone changes a property from a string to boolean, but still assigns it a string somewhere. As soon as you use operators like && or || the intention becomes clearer again: $obj->booleanProperty = $string && $string2; There you are not passing the string directly to a boolean property, you are checking an expression, and you can even do $obj->booleanProperty = $array && $array2; // cannot pass an array to a boolean, but you can check an array (or two) for truthiness / not being empty Can this prevent bugs, for sure, but within the function context we already have a tool to deal with these sorts of issues with strict_types. But could you not argue the same for integers too? Why when you pass a string to an int parameter does it check if it is numeric, and not auto-coerce "hello" to 0? That is different behavior too, and one can use strict_types or explicit coercions instead. My argument is not that the proposal in this RFC is somewhat elegant or solves deep-rooted issues in the language. Similar to the numeric checks for int parameters I am interested in this for purely practical reasons. If somewhere in your application the integer -376 is passed to a boolean property (and coerced to true), would you not rather know about it? Is it not likely a bug, or at least an oversight? Would it not be easier on developers to know that only 7 scalar values are considered "unambigous" when passing to a typed boolean, and that they would be informed if they pass something else? I already rewrote the passage about raising this to a TypeError, where I state that this should be determined later when there is sufficient experience with these deprecation notices, and for me that is not really urgent - if this just remains an unintrusive deprecation notice for the next 10 years that would be fine with me. But I am convinced this will be a useful notice in many applications, where bugs can be found that otherwise would have stayed hidden for a very long time. I appreciate your feedback, and if I can improve anything about the RFC I am open to ideas. I think your RFCs for the type system have made PHP a much better language, and you seem to think about the big picture of the types in PHP, which is important for the language. This RFC might seem like a niche specific change and it does not affect much of PHP itself, but to me that could be what makes it a useful addition - if it mainly reveals bugs in applications, couldn't that be enough of a reason in favor of it? -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] Stricter implicit boolean coercions
On 23.05.22 20:58, Juliette Reinders Folmer wrote: This RFC worries me as, in my opinion, it makes PHP's behaviour more surprising and inconsistent, not less. It also raises the cognitive complexity for developers by yet another level. 1. It introduces a new interpretation of boolean type coercion, which is only applied against type declarations. 2. This new interpretation is not consistent with "normal" boolean type coercion, not consistent with strict types (no coercion) and also not consistent with what is considered a valid boolean value by the Filter extension. I am not sure what you mean by "normal" boolean type coercion and how it would be inconsistent with those. The RFC does not change the behavior of boolean type coercions, it just points out possibly surprising coercions. The filter extension has its very own interpretation of how to validate a boolean which is completely incompatible with how PHP does implicit type coercions already. Yet people using the filter extension are not affected by this RFC at all, they have already chosen their way to convert a value to boolean. But comparing the filter extension with the implicit type conversion does show how dangerous it can be to for example switch from FILTER_VALIDATE_BOOLEAN (with FILTER_NULL_ON_FAILURE) to the implicit boolean conversions from PHP: with the filter extension "false", "off" and "no" are converted to false, while all these values are silently converted to true by implicit boolean conversion by PHP. People switching from the filter extension to the built-in types of PHP have another way of shooting themselves in the foot, and it is easy to miss the change in behavior. While I agree that the current behaviour of PHP can hide bugs, I fear that even more bugs will be introduced when PHP contains yet a third form of coercion to boolean and the type coercion used is dependent on the context. Assuming from the rest of your response, I am assuming you mean "truthiness" comparisons, like in if statements and other expressions. Those are already different from coercions to typed booleans and have different semantics. In an if statement you can check for truthiness with any type, while a typed boolean only accepts scalar values. I am seeing an advantage of further separating those use cases, as a misconception seems to exist that a check for truthiness is just a conversion to boolean. Having clearer semantics would actually lower cognitive complexity from my perspective - knowing that only 7 values are considered sensible for a typed boolean and getting a notice for any other values makes it a lot clearer how it behaves and when I as a developer will get warned. I fear this will only lead to more bugs, not less (because people new to PHP will learn the "type declaration" based boolean coercion rules and assume they apply everywhere). But they would actually apply anywhere, as far as I know: My suggested allowed values for typed booleans can be used in if statements and lead to the exact same behavior. I also fear that for code bases which do not (yet) use scalar type declarations, this will be one more argument not to introduce scalar type declarations (while they should). My suggestion is far less impactful for "legacy" codebases compared to the other scalar type checking - an "int" parameter only accepting valid numbers and leading to a TypeError otherwise is a much bigger hurdle from my perspective than introducing a deprecation notice for a suspect boolean type coercion. I cannot really believe that "failed" not being auto-coerced to true will be the straw that breaks the camels back in legacy codebases. And again: It is just a deprecation notice, I even amended the RFC to say that this being elevated to a TypeError will have to be decided after the impact of the deprecation notices become clear, not now. My goal is not necessarily to be as strict as possible but rather point out to developers where something might be going wrong. I'd say that for this RFC to be acceptable it would need to apply to all implicit type coercions to boolean. However, the BC-break that would cause and the fall-out of this for non-greenfields codebases is just too huge, which, to me, makes this RFC a very strong no-no. I will amend the RFC to show how typed booleans already have their own type coercions that are not the same as the truthiness checks in if or similar expressions - thanks for pointing that out and showing that there is some confusion there that might benefit from a clearer explanation. Changing how truthiness is evaluated in PHP makes no sense to me though, and I don't think such a drastic step is necessary to get a lot of benefits. If you have further feedback, I would be happy to hear it. So far I have not gotten much feedback, and most of it was going towards being positive, so being able to get to know the other perspective would help to address it in the RFC and improve it overall. -- PHP Internals - PHP Runtime Deve
Re: [PHP-DEV] [Discussion] Stricter implicit boolean coercions
On 17.05.22 11:18, Jordi Boggiano wrote: Thanks for the RFC. I think it's overall a good idea, especially for cases like "false" => true, and arguably for ints >1/<0, but my gut feeling is the string=>bool deprecation will lead to a lot of pain. I definitely see this being done in many places where you expect any string value to be true and an empty string to be false (without consideration for the "false" case which is more common in config style use cases). I don't know what you could do to improve this without making the RFC useless though. I wish these things could be tried out in alpha or even up to early RC builds so we could hopefully get community feedback in before deciding whether it's worth the pain inflicted or not. For what its worth, I already found some bugs in the php-src tests where a function definition was probably changed at some point and a string was passed to a bool argument which was obviously not intended, or where a weird value was used for a boolean argument without any apparent reason. These are the type of unintended coercions I am trying to bring to light with the RFC. Using any string as true is also already a bit dangerous: "0" is a special case string that results to false, which adds a big wrinkle to the assumption "non-empty string is true". My main arguments why I think this will not lead to too much unnecessary pain: * Each individual case is easy to fix, the easiest (but also least useful) would be to loosly compare a value to true ($value == true) instead of directly giving the value to a typed bool * bool arguments for internal functions are usually optional, less numerous and are much more likely to be set by a constant expression than a variable * deprecation notices are easy to ignore, and the "disadvantage" of the high number of deprecation notices with 8.0 and 8.1 should be that most tooling and codebases have gotten more used to dealing with them without too much panic I also added these points to the RFC, because I think there is some resentment built up for deprecation notices by now, which I can understand.
Re: [PHP-DEV] [Discussion] Stricter implicit boolean coercions
On 16.05.22 18:24, Guilliam Xavier wrote: Thanks! Am I right that it only affects *type declarations*, and the "Unaffected PHP Functionality" section could also mention implicit boolean evaluation in `if`, ternary conditional (?:) and logical operators (!, &&, ||, and, or, xor)? Yes, that is correct and I just added a note about that in the RFC - thanks for the suggestion! I also added a part about how to avoid the deprecation notice, which should also make it clearer / add some context. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] Stricter implicit boolean coercions
Hello Kamil, I suspect this is very different depending on the codebase. My main reason for introducing this deprecation notice is to start highlighting possible problems in codebases where nobody even suspected them before. In one application recently I actually had the string "false" (coming from a form transmission) being passed to a boolean argument and leading to true, which definitely was unintended. I have tried coming up with reasons why these deprecation notices could be harmful or unnecessary, but I think anytime they occur there is a legitimate reason to check the code (and make it more explicit). If an integer 5 is passed to a boolean type, how is that not suspicious? Yet I do think this is a deprecation notice that will be far less common than some in recent history (like "non-integer-compatible float to int conversions" or "passing null to non-nullable parameters of built-in functions"), because there are far less boolean parameters in the built-in functions of PHP compared to string/int, and I'd wager bool is also less used in codebases compared to string/int/float. If you or anybody else has a recommendation on how to measure how this would affect codebases and what information in that regard would be useful, I am open to look into that more. The impact should be rather low in general because it is only a deprecation notice, and I think a lot of codebases are getting used to dealing with deprecations more with the last two PHP versions. Best regards, Andreas On 16.05.22 17:19, Kamil Tekiela wrote: Hi Andreas, Has any case study been done already about how it will affect existing codebases? Regards, Kamil
[PHP-DEV] [Discussion] Stricter implicit boolean coercions
Hello Internals, After the first discussion about this topic (https://externals.io/message/117608) I have created a preliminary implementation and an RFC for making implicit boolean type coercions more strict: https://wiki.php.net/rfc/stricter_implicit_boolean_coercions With this email I'm starting the two week discussion period. I welcome any feedback on it and hope to further iron out the implementation if needed. I mainly chose the route of introducing a deprecation notice because it is in line with other RFCs that have similar goals (like the Deprecate implicit non-integer-compatible float to int conversions RFC), and it is fairly non-intrusive. Best regards, Andreas
[PHP-DEV] Request for wiki karma
Hello Internals, I would like to request wiki edit privileges to prepare an RFC for Stricter implicit boolean coercions, where I started a discussion recently and am currently finalizing an preliminary implementation. Username: iquito Thanks! Best regards, Andreas Leathley
Re: [PHP-DEV] The future of objects and operators
On 07.05.22 22:59, Jordan LeDoux wrote: I like the way you organized the different levels of support within the feature, it's a good organizational structure for thinking about the feature-set. Given the feedback though, I found myself a little concerned that if I created a Level 1 proposal, it's very possible that the people in groups 1 and 3 above might vote for it. However, in doing so it's also very possible that all the use-cases those voters care about would then be covered, and many would then block anything which helps use-cases they do not commonly use. In essence, the particular feedback I received made me concerned that passing a Level 1 RFC would basically guarantee that Level 2+ would never happen until the voter base itself was significantly changed. Creating "smaller steps" (within a certain feature set) seems to have been the more successful route for PHP RFCs and not necessarily slowed down further enhancements, in my estimation. The more one single RFC is about, the more there is to possibly dislike. It is also easier to reason about less changes at any one point in time and make a more compelling case for the changes. So I think your overall goal of more feature-complete operator overloading remains viable even if you start "small" with a level 1 proposal. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throw a deprecation notice ?
On 02.05.22 13:56, Alexandru Pătrănescu wrote: The point is that this is not an usual deprecation, something that will change to an error in the future. In the end, it's just a change in behavior with no error before or after. It does not fit the "deprecation". As I dealt with several PHP upgrades, and I'm still going to deal with them in the future, I proposed an idea at some point on the mailing list: To find a way to "flag" a behavior change. The problem is that it should be something outside E_ALL, or to be able to handle it in a totally different way than setting an error handler for it. Something that can be used when preparing for an PHP upgrade, something like: register_version_change_handler(callable $callback, $toPhpVersion) While preparing for a future runtime version, it would be deployed to production and would record behavioral changes in a logging system. These changes need to be manually reviewed, of course, as a change can be to return false instead of null and if that value would be used further in an if. When using in a library maybe there could be some token like @@@ to not trigger the handler. To me, adding another error/change handler system seems like a bad way of dealing with this, not to mention that you need to introduce this behavior in a PHP version first before anyone can then use it, so it would be years before this could be useful, and even more years until there would be established patterns and enough knowledge around it. Using the existing way of notices, warnings and errors seems just as good to me, and people have been handling those for many years. Any new way of dealing with this should have a very high bar to clear and would need to prove a huge gain in value. To me this does fit the definition of a deprecation - behavior for the given code will change intentionally in a future version, and you are warning about that future change. But one could also emit a notice, or a warning. The advantage of deprecation notices is that many tools ignore those specifically, as they are something to look at, but not necessarily right at this moment. Being more lenient in certain situations with deprecation notices is therefore a good pattern for easier adoption of new versions. I have included that behavior in my own applications, by logging deprecations separately - I will check them out once in a while, but they do not need immediate attention. Any other PHP notice or warning would warrant immediate attention, as it would be unexpected. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Stricter implicit boolean coercions
On 26.04.22 16:36, Rowan Tommins wrote: On 26/04/2022 14:53, Andreas Leathley wrote: 'on' is only true by "accident" though, because it is a non-empty string, not because of its meaning, and then it is likely that the value 'off' could also be added at some point - which also would be true. The reason I gave that particular example is that it's the default submission value for an HTML checkbox when checked; if it's not checked, it has no value at all (not even an empty string), so in that particular context there is no corresponding "off". Interesting, I didn't know the default value of a checkbox is "on" if no value is specified. That might make it another sensible value to accept for implicit bool conversion, even though I am not sure how many checkboxes are used without setting an explicit value, but it could be considered an established value, especially with how commonplace HTML forms and checkboxes are in PHP applications. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Stricter implicit boolean coercions
On 26.04.22 15:27, Rowan Tommins wrote: I was actually thinking about this the other day, in the context of adding new cast functions which reject more values than our current explicit casts. This is also something I am interested in - having functions which do the same as implicit type casts, so something like "coerce_to_int('hello')" would lead to a TypeError like it would when passing it to an int parameter, and maybe "is_coerceable_to_int('hello')" which would return false, so it would be possible to check values the same way as PHP does internally. The current explicit cast functions are quite heavy-handed and not great for every situation - when parsing a CSV or getting data from a database I would rather coerce values where an error could occur if it doesn't make sense than to explicitely cast and not even notice if the value made no sense at all. When I started thinking about booleans, it was much harder to define what makes sense. I've certainly seen new programmers confused that (bool)'false' is true, and having it error would usually be more helpful; but (bool)'on' being true is useful when dealing with HTML forms, for instance. 'on' is only true by "accident" though, because it is a non-empty string, not because of its meaning, and then it is likely that the value 'off' could also be added at some point - which also would be true. One of the big reasons of starting this discussion is because of HTML forms, as that is where people might add values and not know what that leads to in PHP. At these application boundaries it would be helpful to get a clear message what value was converted to true (but might have lost information by doing that) and what other value to use which is considered more clear. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Stricter implicit boolean coercions
On 26.04.22 14:47, Christian Schneider wrote: There are two big reasons: - BC: Checking for the truthiness of a value is very common and would require a lot of code changes. - Some of us like the conciseness of "if ($foo) ...", see below That would not be my target - in an if expression a lot more values are allowed anyway (arrays, objects, etc.), so this is not about determining truthiness, but actual conversions to a bool type, like a bool parameter, a bool return type or a bool property type. The inspiration for this is the "Deprecate implicit non-integer compatible float to int conversions" (https://wiki.php.net/rfc/implicit-float-int-deprecate), minus the mathematical expressions that were considered there. It is about avoiding probably-unintended values being coerced to boolean and therefore losing information / adding unnoticed bugs to a codebase. I'm definitely against adding more special cases like 'false'. Side-note: Removing something like '0' => false is also a BC break, not just adding 'false'. I am not suggesting removing the coercion from the string '0' to false or changing anything about that. One of the big issues I have with this (as well as undefined variables not being allowed in if ($foo)) is that the replacement constructs are clunky: if ($foo) =>. if (!empty($foo)) For me this is quite a regression in readability but then again that's a matter of taste. And would !empty($foo) even work in your world or how would empty() be defined? empty is also not something I would consider covering, as there you also do not need a conversion to a bool type. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Re: Stricter implicit boolean coercions
On 26.04.22 12:02, Mark Randall wrote: On 26/04/2022 10:54, Andreas Leathley wrote: Any non-empty string (except "0") is converted to true and any non-zero integer or float is converted to true. If we could get rid of "0" being false, that alone would be a huge benefit for the language in the long run. I know why it exists, but I don't think it should. In fact it never should have existed in the first place. For me, highlighting all the places where a possibly unintended conversion to true is happening would make "0" a lot less bad. "0.0" being silently true while "0" and 0.0 is false seems a bit awkward. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
[PHP-DEV] Stricter implicit boolean coercions
Hello Internals, Implicit type coercions (when not using strict_types) have become increasingly less lossy/surprising in PHP, especially coercions to integer and float, where you get a TypeError if you pass a non-numeric string to an integer parameter, and a deprecation notice if you pass a float(-string) with a fractional part to an integer parameter. The big exception so far is coercions to boolean, where you can provide any scalar value and never get an error or a notice. Any non-empty string (except "0") is converted to true and any non-zero integer or float is converted to true. From my perspective this can easily lead to hidden bugs, for example when passing the wrong variable to a boolean argument or boolean property. Passing a string like "hello" as a boolean is probably a bug, just like passing the number 854 or the float 0.1 . "on" and "off" and "true" and "false" all lead to a boolean true, as examples of strings that could be used in applications and might not all be meant as a value of true. I have not found any past proposals or discussions to change boolean coercions, so I would like to find out how the thoughts on internals are to change this, or if there are any reasons not to change this that I have not thought of. Only allowing the following values would make sense from my perspective: '1' => true 1 => true 1.0 => true '' => false '0' => false 0 => false 0.0 => false I can also see a case for allowing the strings 'true' and 'false', and changing 'false' to be coerced to false, but that would be a BC break. I am not sure if that is worthwhile. Anything else would emit either a notice or a warning as a first step (to be determined). My main goal would be to make these probably-not-boolean usages more visible in codebases. Depending on the feedback here I would create an RFC and try to do an implementation (to then discuss it in more detail), so as of now this is mostly about getting some basic feedback on such a change, and if someone else has had any similar thoughts/plans. Thanks for any feedback! Andreas Leathley
Re: [PHP-DEV] NULL Coercion Consistency
There is another 3.5 years until PHP 9 is likely to come out, which is a lot of time for people to adjust their codebase. I could even see an argument for not promoting it to a fatal error in 9.0 if so many people need more time. If it's deprecated, that is an intent to break... and if no other solutions present themselves, and the vote for this RFC fails... why would it be delayed? It will then be clear the Internals developers want this (they would have made an informed choice, and put their name to it). A deprecation notice is fairly harmless. If in two years many projects and many developers say that they need more time to fix these deprecations and promoting them to errors would cause a lot of problems, then it would be easy to prolong the period where it is only a deprecation with a small RFC. By then more people will know if they are impacted, many frameworks will have updated, and there will be a clearer picture if this is such a big deal or not. Right now this is not clear - I doubt most projects are using PHP 8.1, not even all frameworks/libraries are compatible to PHP 8.1. Are you going to suggest any improvements? what have I missed? I'm trying to keep it short, because I know long RFC's can be a problem. An RFC should cover the discussions held on this mailing list. From the RFC howto: "Update your RFC to document all the issues and discussions. Cover both the positive and negative arguments." Do you honestly believe you have done that? I have tried to discuss some counterpoints and alternatives to your proposal, but none are mentioned in the RFC. I also don't see the discussion points of other people in the RFC. None of the alternatives to your proposal are mentioned in the RFC - like changing the internal functions to accept null instead. There have been quite a few suggestions and arguments made so far, and I don't see them in the RFC. I have discussed RFCs with a few people on this mailing list, sometimes with very different opinions about a topic, and not always was there a resolution to the topic at hand. Yet the discussions with you have been the most frustrating so far, because you say you are open to arguments and proposals, yet you do not seem to consider them at all - yet you really seem to believe you are totally open-minded. I have been impressed by a few people on this mailing list who I disagreed with wholeheartedly, because I noticed with how much care they tried to relay disagreeing arguments and other proposals in the RFC and how balanced the RFCs were at the end. Your RFC seems totally incomplete to me and mainly based on your made-up opinion. But at this point I don't think I will get through to you in any way, which is why I will step out of this conversation. If the RFC comes to a vote in the current conditions though I will raise an objection that it does not represent the discussions held on this mailing list and should be disregarded because of that. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] NULL Coercion Consistency
On 14.04.22 14:14, Craig Francis wrote: Yep, I agree with everything you have said there, and it's what George seems to be working towards (which I also agree with): https://github.com/Girgias/unify-typing-modes-rfc Yet your RFC goes exactly against the quoted document by making the differences between strict_types larger. I also cannot explain why NULL should be rejected, other than for those developers who see NULL as an invalid value and also use `strict_types=1`... as in, when a team of developers spends a few hundred hours adding strval() everywhere, what does that actually achieve? what do they tell the client? does it make the code easier to read? does it avoid any bugs? or is it only for 8.1 compatibility? I don't get why you would add strval everywhere. Why are you getting null everywhere? In most of the examples in your RFC "null" is specifically chosen as a default value and could easily be an empty string (why do something like "$_POST['value'] ?? null" if you actually want an empty string?). For the framework examples, the second argument of these functions is the default value - it does not have to be null. And "filter_input" I have not seen in a codebase yet, probably because of its weird double function as retrieving an input variable and also filtering it, with both null, false and the result as a possible return value. The few cases where I encountered the deprecation notice it was always a mistake and easy to fix, and I was glad that was pointed out to me. There is another 3.5 years until PHP 9 is likely to come out, which is a lot of time for people to adjust their codebase. I could even see an argument for not promoting it to a fatal error in 9.0 if so many people need more time. Removing the deprecation and changing fundamental aspects about the type system in PHP by auto-coercing null just so people do not need to update their codebase seems like the worst possible way forward. So far, your RFC does not mention the arguments made against your proposed changes in an understandable way. George Peter Banyard wrote some extensive arguments and you have only included one sentence without any of his arguments and try to refute it in the very next sentence as not really an argument, and it was mentioned by him that coercing null in other languages like Java has lead to problems. Comparisons to other languages could be helpful, as NULL is not just a value in PHP - NULL in MySQL for example also cannot be coerced and is its own distinct value (it even has its own syntax for comparisons). I am still bothered by the language of the RFC in general where you often write things like ".. it hasn't been the case for everyone else", "most developers are not in a position" and so on. Assuming you know what everyone is doing and how everyone is doing it in an RFC does not seem constructive. All the numbers you cite are also circumstantial and not about the supposed problem discussed in the RFC - for example, you assume people not using static analysis are in favor of your RFC, even though this is pure speculation. Compared to all the other RFCs in the last 3 years I read through I don't only disagree with this RFC, I also think it is not very well reasoned about and does not convey the discussions that were held about the topic on this mailing list. It mainly contains your opinion, which seems insufficient for an RFC. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] NULL Coercion Consistency
On 14.04.22 10:10, Craig Francis wrote: My intro says "Roughly 85% scripts do not use strict_types=1", and "Roughly 33% of developers use static analysis" (source of numbers noted in my RFC)... while that does not guarantee anything, it's a fairly good indication that most developers do not care about types (in regards to coercion), or specifically, how you "see null as a real type". As an aside, I would like to include more stats (maybe WordPress install numbers?), but I couldn't think of any which were easy to source (ref reliability), or be that useful to the discussion. I have never used strict_types in any code I have ever written, and I care about types and type coercions. Yet I do not like the strict_types distinction and I am glad that I do not need to use it, and I think we are not that far away from even reconciling these two systems. I do not mind that the string "5" can be passed to an int parameter, while passing the string "hello" will throw a type exception no matter what mode you use. With some adjustments to certain coercions the advantage of strict_types would be even more neglible - as you can pass "hello" to a boolean parameter without problems currently, and I don't like that. Looking at usage numbers and assuming that supports your point seems like a big leap to me. You are assuming these developers are making a choice while it seems quite possible that a lot of code has been written without thinking about all the implications, which is where so many bugs are coming from. In the last months reviewing code I noticed quite a few developers are copy-pasting code like crazy, or using generated code from other tools - both of which are often not well reasoned about. So this has little to do with developers not caring about methods of type coercions and more about the language permitting such code, leading to many follow-up problems. Also, this "problem" only affects the internal functions, yet you want to change it for all functions. If you use a framework and pass a value to a method of that framework, it would already have created a type error with null and a non-nullable argument for quite some time. I think you are making this out to be a bigger problem than it is. Sure, in a codebase with lots of custom code where no incoming variable is checked if it even exists there will be problems, but even then it is easily fixable. In a codebase based on a common framework it is much less of a problem, as you will probably be using lots of framework components and not mainly internal functions, and there you already have the "limitation" of not being able to pass null to a non-nullable method. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] NULL Coercion Consistency
On 13.04.22 15:36, Craig Francis wrote: On Mon, 11 Apr 2022 at 20:08, Andreas Leathley wrote: You are taking parts of the documentation out of context, and omitting the start of the whole "Converting to string" section: "A value can be converted to a string using the (string) cast or the strval() function. String conversion is automatically done in the scope of an expression where a string is needed. This happens when using the echo or print functions, or when a variable is compared to a string. The sections on Types and Type Juggling will make the following clearer." I'm sorry, I've read this several times now, and I'm not sure what this adds. My RFC simply quotes the paragraphs that explain how null is coerced (other than the small abbreviation for booleans, those paragraphs are included in their entirety), I don't think it needs any more context than that, it's not like I'm mis-representing how coercion works (and is used) in PHP. Mentioning the documentation as a reason to be "consistent" (which comes up again and again in your arguments with this RFC) just seems like a bogus reason to me. It is nitpicking about specific sentences in the documentation without refering to the surrounding context. It would be nicer to argue according to real technical arguments instead of arguments about sentences taken out of context in the documentation. You can see NULL however you like, but most developers do not share that view. NULL has been passed to these functions, since, well, forever; and changing code to manually convert NULL to the relevant type is incredibly time consuming, and of questionable value (e.g. when developers simply add strval() everywhere). "Most developers do not share that view". I find statements such as these as a tall order - did you interview the majority of developers around the world? Are you suggesting you are talking as a representative of a large population of PHP developers? How do you think you got such a role? I would prefer some humility and not assume you are an elected leader of an underrepresented group of developers and even knowing the intention behind their code. "NULL has been passed to these functions, since, well, forever" - this also goes for wrong values being passed to functions since forever leading to security issues and bugs. That is the whole point of developing a language: Reducing the surface for bugs, improving parts of it where a lot of bugs have happened historically and not making the same mistakes as other languages (and learning from the good parts of other languages). More people writing code in a certain way does not make that code better or safer.
Re: [PHP-DEV] NULL Coercion Consistency
On 11.04.22 20:22, Craig Francis wrote: Just take NULL to String coercion as an example, the documentation clearly and simply says “null is always converted to an empty string”, this needs to be updated to end with "... except when being passed to a function, in which case NULL will result in a Type Error" (I think that's "broken and inconsistent"). You are taking parts of the documentation out of context, and omitting the start of the whole "Converting to string" section: "A value can be converted to a string using the (string) cast or the strval() function. String conversion is automatically done in the scope of an expression where a string is needed. This happens when using the echo or print functions, or when a variable is compared to a string. The sections on Types and Type Juggling will make the following clearer." In the same section it is also defined how resources and arrays get converted to strings. Following your argument, you should be able to pass arrays and resources to a string parameter because there is a clear definition in the documentation of what then happens. I unfortunately really don't like the direction of your RFC, because I see null as a real type and because it increases the divide between strict_types and not using strict_types. I have never used strict_types - in modern PHP code I find it unnecessary, if you use parameter, property and return types. I am glad PHP has decreased the difference between using strict_types or not, so your direction of trying to increase the difference seems like the wrong way to go. Ideally I would rather want to see a future where strict_types can be removed/reconciled. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Allowing NULL for some internal functions
On 02.03.22 16:00, Craig Francis wrote: I'll note that converting from NULL is used all the time, and is well defined: https://www.php.net/manual/en/language.types.string.php "null is always converted to an empty string." https://www.php.net/manual/en/language.types.integer.php "null is always converted to zero (0)." https://www.php.net/manual/en/language.types.float.php "For values of other types, the conversion is performed by converting the value to int first and then to float" https://www.php.net/manual/en/language.types.boolean.php "When converting to bool, the following values are considered false [...] the special type NULL" This is the behavior for explicit type casting (strval) and the implicit casting when using a variable in a string context, like echo or print. This is basically just a base necessity - for example an array is converted to "Array". All information about the array is lost, except that the string is now called "Array". So would you say something like htmlentities should also accept array values and automatically convert it to the string "Array"? It is used all the time with echo and print, and it is well defined, yet it is still not a good idea. For strval and for echo it makes sense to convert an array to "Array" (barely, to end up with a somewhat useable string), but for parameter types it does not make sense. The same goes, in my opinion, for null. It really depends on your code base... Laravel, Symfony, CakePHP, CodeIgniter (the frameworks I'm familiar with) all return NULL for missing GET/POST/COOKIE values, and that is a useful feature... but when the developer naively passes that to any one of those listed parameters, you will get a deprecation message in 8.1, and a Type Error in the future... and finding all of these is incredibly hard. These frameworks change their types and signatures quite often - much more than PHP ever does. One Symfony project of mine that is now 7 years old has had crazy changes, both in types, signatures, directory structure, etc., yet people adapted and the changes were for the better. Compared to the changes produced by frameworks this deprecation about string values and null seems much smaller to me. And I do think it is important that coercions in the language become less frequent rather than more frequent, also because the language does have a certain "role model" effect. From 7.0 until 8.1 it was a legacy effect that converted null to an empty string, and only for internal functions, but with your proposal it would be an intentional decision to start treating null and scalar types more interchangeably. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Allowing NULL for some internal functions
On 02.03.22 15:27, Craig Francis wrote: On Wed, 2 Mar 2022 at 14:17, Larry Garfield wrote: Null is not an empty string. Null is not a string. Null is not 0. Null is not an integer. So what should this do? $name = ($_POST['name'] ?? NULL); var_dump($name == ''); Is that now going to be false? Comparisons with == are quite worthless, except when comparing objects, as == has so many caveats for when it returns true because of weird rules about what should be considered equal or not for legacy reasons. I don't think I have used == in the last 5 years, and life has gotten so much better because of it. Why not write: $name = ($_POST['name'] ?? ''); Then you know 100% that $name does not contain null. It might not be a string, but it cannot be null. You can still not safely pass it to something like htmlentities or str_starts_with, because $name could be an array. And I think that is the reason why the current deprecation and eventual removal makes sense - it highlights missing logic that can easily lead to errors. If the problem is not null, then it might be that you have another unexpected type like an array, because the value was not properly checked. Putting strval around such code (as one possibility to resolve it) at least improves the code, in that we then have a clear type for the variable, removing some room for errors and bugs. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Allowing NULL for some internal functions
On 02.03.22 15:00, Craig Francis wrote: On Wed, 2 Mar 2022 at 12:26, Dik Takken wrote: So, to get this crystal clear, this is my understanding of what you are proposing for passing null to a non-nullable function parameter (hopefully my ASCII art will come through ok): which | strict_types | PHP 8.0| PHP 8.1| PHP 9 --|---|||-- user | 1 | TypeError | TypeError | TypeError internal | 1 | TypeError | TypeError | TypeError user | 0 | TypeError | TypeError | coerced internal | 0 | coerced| Deprecated | coerced Is this correct? Yes, that's correct... although I'd be doing this for 8.2, to avoid TypeError exceptions being introduced for non `strict_types` scripts in 9.0. This is based on the feedback from the quiz and here; so type coercion from NULL would continue to work, like coercion from the other variable types (string/int/float/bool). Type coercion already often does not work - giving the string "s" to an integer-typed argument will lead to a TypeError, it will not be coerced. I would prefer less coercions rather than more. That you can give a bool-typed argument "s" and it will be coerced to true seems quite bad to me, for example. I am someone who never uses strict_types although I use types everywhere in my code - accepting the string "1" for an integer type seems fine to me, especially because with HTTP requests you always get strings, and often you also get strings from other external sources, like CSV, databases, etc. So type coercion from strings to a certain degree seems reasonable to me (although even there I am using more and more explicit casts), but having to coerce null seems always avoidable to me, and null is a special value explicitely. In my data null and an empty string sometimes are two possible values, and automatic conversion seems like a value judgement by the language that they are kind of similar, which they should not be. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Setting to disable the "Undefined array index" warning
On 15.02.22 13:31, Nicolas BADIA wrote: As it is explained in this ticket https://bugs.php.net/bug.php?id=81417 we use to check if a property exists by accessing it directly like we do in JavaScript. Personally, I subscribe to this coding style and we use it all over our codebase (more than 130 000 lines of PHP code). When it became a notice, we disabled them, but now that it is a warning, it is a lot more problematic for us… We can’t even use the last version of PHP Debug for VSCode. The problem with your way of writing code is that it is ambiguous in meaning, which is why this is a warning. You are not checking if a key in an array exists, you are checking if an array value is "false-y". If the value is an empty string, it is also interpreted as false, if it is null, it is also interpreted as false, if it is an integer of value zero it is also interpreted as false, if it is the string "0" it is also interpreted as false. When you write code as you do, it is easy to introduce subtle errors because of these implicit casts. If you want to check if an array key is defined, you should do it explicitly - this is not about a "coding style", this is about writing the code in a way that actually does what you intend it to do without it meaning multiple things of which some are probably not expected. If you just want a quick fix without solving the underlying problem, you can just add "?? null" to each array key access. If you want to upgrade/improve your code base, which is a worthwhile task, I would suggest the use of a static analyzer (like Psalm or PHPStan) to find out where your code is ambigious. I have found many undetected errors that way, where implicit casts have lead to unexpected outcomes, which is why I am very much in favor of these warnings for undefined array keys. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] User Defined Operator Overloads
On 05.01.22 10:42, Jordan LeDoux wrote: I suppose the alternative would be to withdraw the RFC now that a wider variety of voters are providing feedback than the other three threads. I would let the vote go on, as there are still many voters who have not voted on this yet, giving the proposal more exposure and also giving you a more complete feedback about the outcome. And if this RFC has less voters in total when it ends than other RFCs, that could also be good to know. There have been quite a few big PHP features which failed in the first attempt, but then easily passed in a later attempt after more discussions and changes. Also, your hint about the operator keyword decision and on what that is based on might offer more avenues to change some minds - personally, I would be interested to read a blog article about this (even if it is quite lengthy, and even though I don't have a vote and am not designing languages), and linking that in an RFC could then be some helpful background for some people, even if not everyone reads it. And such an article might be interesting to people outside of PHP. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] User Defined Operator Overloads
On 03.01.22 17:12, Larry Garfield wrote: Also, people keep talking about edge cases. In my experience, "are these two objects equal" (for some object-specific definition of equal) is very much *not* an edge case. I may have less use for overloading % as I don't use advanced math that much, but I compare things all the frickin' time and that would be incredibly useful day to day. Maybe some of the resistance against this RFC is the (understandable) focus on mathematical (or mathematical-adjacent) operations, making it seem that the "real" use-cases are narrow, whereas comparing objects could make quite a bit of code more readable, like comparing addresses, prices, availability or location/position. Having regular methods for operators is possible, but when used a lot the readability does start to suffer. The difficulty in arguing for operator overloading might be that the use cases are specific to a codebase and mainly become apparent once it is available (currently you just work around it). I do think it is a reasonable tool to make some code vastly more readable, and I don't see "novices" using operators a lot - PHP has many simpler features to abuse that can make code absolutely terrible. The RFC is really well thought out and reasoned, by the way - great work Jordan! -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Allowing NULL for some internal functions
On 02.01.22 00:17, Craig Francis wrote: I've spent a few days coming up with a short(ish) list of parameters that are likely to receive `NULL`. The focus is on making it easier for developers to upgrade to newer versions of PHP. I'm thinking of the typical developer, probably using WordPress, isn't using Psalm (at levels 1 to 3, with no baseline), and isn't using `strict_types`; where they don't really have the time to add strval() to everything that could be NULL. I don't think the current deprecation notices are a real hindrance in upgrading to a newer PHP version - there have been many such changes which require possibly many small adaptions in code in the past, like making undefined array keys a warning in PHP 8.0 (which seems a lot more radical than adding the current deprecation notices). Singling out this specific deprecation/change as impactful seems a bit overblown. I also feel like such an un-deprecation would be premature. PHP 8.1 has only just come out, the road until PHP 9.0 is still quite long, and deprecation notices can easily be ignored for now, for those who do not want to change their code right away. If in a year or two this is a big problem in real code, then there would at least be a basis for changing it, but I suspect most codebases will see more benefit in handling their types more properly than if the language "sometimes" automatically converts null to an empty string without complaining about it. I did have some occurances of this deprecation notice in my applications when upgrading to 8.1, and each time it was clearly a bug or oversight. Removing the deprecation notices would also remove those insights into possibly unreliable code. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Migrating to GitHub issues
On 15.11.21 10:47, Derick Rethans wrote: GitHub is a proprietary platform, where unlike with the code repositories, the interactions and issues are not easy to migrate out of again. It is also now owned by MSFT, and although they are making friendly noises towards Open Source, I remain largely skeptical (with as a hint, the stuff they're pulling with AI code completion). All open-source projects I know and use in relation to PHP development are on Github (like Composer and Symfony, to just name two big ones), which in my opinion makes Github an ideal platform for the PHP project itself, as the barrier of entry is lowered. This also has the advantage that if Github "becomes evil" (or just gets worse) for whatever reasons, the PHP project will just be one of many open-source projects which needs to move to a new place. This gives this solution a safety in numbers and will probably make it easier to move rather than harder. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Deprecate dynamic properties
On 25.08.21 12:45, Rowan Tommins wrote: * Adding a parent to an existing class isn't always possible, if it already inherits from something else. Perhaps the behaviour could also be available as a trait, which defined stub __get and __set methods, allowing for the replacement of the internal implementation as you've described? Couldn't this be easily done in userland with the ArrayLikeObject (an example in the RFC) or something similar, just done as a trait? Maybe having an example trait implementation that basically "imitates" stdClass in terms of dynamic properties would be helpful to show in the RFC, to highlight a possible resolution path for legacy code with this problem. This could be an example implementation: trait DynamicPropertiesTrait { private array $dynamicProperties = []; public function &__get(string $name): mixed { return $this->dynamicProperties[$name]; } public function __isset(string $name): bool { return isset($this->dynamicProperties[$name]); } public function __set(string $name, mixed $value): void { $this->dynamicProperties[$name] = $value; } public function __unset(string $name): void { unset($this->dynamicProperties[$name]); } } -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Nullable intersection types
On 23.07.21 11:58, Nicolas Grekas wrote: Hi everyone, as proposed by Nikita and Joe, I'm submitting this late RFC for your consideration for inclusion in PHP 8.1. Intersection types as currently accepted are not nullable. This RFC proposes to make them so. I wrote everything down about the reasons why here: https://wiki.php.net/rfc/nullable_intersection_types Please have a look and let me know what you think. I would suggest to only offer a vote on (A&B)|null being allowed - not because I personally believe in that option, but because there seems to be a lot of tension around being forward-compatible and finding a solution that is as "safe" as possible. I fear if there are multiple syntax options, the rate of no-votes will just be higher, and the RFC will have no chance. From a userland POV I do not think it matters much if for now it is (A&B)|null or A&B|null - the point should be that nullability is possible and can be defined in code. If extra brackets seems to be more future-proof, then why not. Having one clear RFC voting option (with no secondary syntax voting option) also seems the most honest, as if somebody agrees that nullability would be useful but would only accept one syntax choice, that seems impossible to represent, necessitating a no vote on the whole RFC. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] intersection types and null for defaults, properties and return types
On 19.07.21 11:21, azjezz wrote: however, when `T` is an intersection between `X` and `T` ( `X&Y` ), `X&Y $x = null` becomes `null|X&Y $x = null`, which is a combination between union and intersection types, however, as the RFC stats, currently combination between union and intersection types is not support ( hence "pure" ). for this to be allowed, PHP would need to support combining union and intersection types, preferable using parenthesis ( `X|(Y&Z) $x = null` or `(X&Y)|Z $x = null` ). Supporting a syntax like ?A&B could just be a special case just like ?A was in the past, before actual union types existed. I can see how full support for union types and intersection types can get complicated (and may never make it into PHP, or need quite some time until it does), but pure intersection types that can be nullable seems like a relatively simple special case which would be very helpful in code, because you could have optional intersection types in arguments/properties, which is otherwise not possible (and one would have to fall back once again to annotations and less type safety). Nullable intersection types also do not touch upon the main problems of mixing union types and intersection types, namely in reflection, where it would just lead to "ReflectionType::allowsNull" to be true instead of false, but not change any other logic as far as I can tell. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Readonly properties - immutability by default
On 16.07.21 09:06, Nikita Popov wrote: We cannot make properties readonly by default, because that would be a major backwards compatibility break. If you're going for brevity, something you can do is omit the visibility specifier, as it is public by default. "readonly int $prop" works. Would it be possible to adapt constructor property promotion to support this (as far as I tell, it currently does not)? Namely: class A { public function __construct( readonly int $id, ) { } } According to the constructor property promotion RFC, the promotion only happens when public, private and protected is used for an constructor parameter. With the readonly RFC accepted, it would make sense to also do constructor property promotion when readonly is used, to avoid the explicit public, because readonly would also clearly define the parameter as not-only-a-parameter. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Introduce str_left/right In 8.1
On 24.06.21 13:17, Kamil Tekiela wrote: I am against adding these functions, but for different reasons than Sara and George. If we add str_left and str_right then there should be a corresponding variant in mbstring. The byte-string functions are rarely useful. Adding these functions to mbstring unnecessarily complicates the extension for little to no gain. Another point is that if we decide to add them, then we will bikeshed forever in an unresolvable manner about the name. Should it be called str_left or strleft? Current functions don't have a naming convention, so using either variant will be wrong. Personally, I find substr to be more clear about the intent. I know that I am asking for a part of the string. Whereas str_left doesn't convey an action immediately. Without knowing its purpose I wouldn't know if it will pad the string from the left, strip characters from left, or take the leftmost part of the string. Don't take it the wrong way, but I think it's a waste of time to implement a function that doesn't even need a polyfill in the userland. str_left / str_right also seems very unclear to me in terms of the name. But I don't think naming new string functions in general should be difficult - the recent string additions have all started with str_ (like str_contains, str_starts_with) which seems more readable than any of the non-underscore functions. I do think the intended functions can make sense, just because I find substr to be a bit obnoxious - with a necessary offset and an optional length it rarely is obvious to me at a glance what the intention is, as you can do so many different things with it, because offset and length can be positive or negative, and then very different things happen. These new functions are quite similar to str_contains or str_starts_with for me, in that you don't need them, but it makes code so much more readable. str_left_part(string $string, int $length) would make it clear the left part of the string is returned, and it could throw an exception if $length is negative. With substr you might accidentally give it a negative length, or would need to check if a length is positive or negative (if it is in a variable) to know what is happening. str_right_part(string $string, int $length) would make it clear the right part of the string is returned. And if you compare substr usage to these two functions, it might come through how different in arguments & readability it is: substr($string, -3); str_right_part($string, 3); substr($string, 0, 3); str_left_part($string, 3); substr($string, -6, 3); str_left_part(str_right_part($string, 6), 3); If you use substr all the time you might be used to it, but to me I have to stop and think what is happening each time more than would be necessary with dedicated functions. A function like str_contains definitely had a bigger impact than something like str_left_part would have, but it would still make a difference. (By the way, str_left_part/str_right_part is just what came to mind, could be anything as long as it conveys what it is doing clearly enough, which probably always needs two words, not just one) -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Re: [RFC] is_literal
On 18.06.21 08:00, Craig Francis wrote: As there’s been no issues raised with supporting integers, and doing so will help adoption, the implementation will be updated to allow them. Now to choose the name, with the options is_known() from Joe and is_trusted() from Moritz: https://strawpoll.com/bd2qed2xs Keep in mind it might also become a dedicated type in the future. I think "trusted" is a good option, also if you think about adding it as a type in the future and how it reads for somebody looking through code. Something like public function process(string&trusted $input): string&trusted; Would be good in terms of readability and captures the meaning quite well (although having a specific trusted string type might be more sensible, to avoid these intersection types everywhere). "trusted" could be used in a similar way like the "pure" annotations in Psalm/PHPStan (just for a different meaning of course): to signify where non-trusted variables should be reported and could even be used for whole objects to signify they should only ever get and return trusted variables. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Consensus Gathering: is_initialized
On 27.05.21 16:43, Rowan Tommins wrote: isset in this case is abused to check for uninitialized, hiding the actual intent On the contrary, the uninitialized state is what is being abused. If you want to make the intent clear, use a clear flag of "needs lazy-loading", or whatever you're actually using this magic "not null but not really anything else either" state for. How is "uninitialized" magic? It is a state of a class property in PHP that is currently being exposed via reflection, and I have seen quite a few places where it occurs - for example with setter injection in frameworks, as an alternative to setting a property in the constructor. I also prefer properties with default values or values defined in the constructor, yet making it easy to check on something that already exists in the language only seems sensible to me - and I don't see a way of getting rid of that state anytime soon. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Consensus Gathering: is_initialized
On 26.05.21 12:13, Joe Watkins wrote: Not absolutely convinced that it's a good idea, I asked Nikita to review, and he's unconvinced also and suggested a discussion should be started. You can read both of our thoughts about it on the PR. What I'm looking for now, is reasons that we are wrong - good use cases that aren't born from code that is doing bad things ... Equally if you think this is really bad even if the reason has already been mentioned, please make noise. I like it because it is very clear and takes into account the current scope. The alternatives are more messy: - When using "isset" on class properties, it is not obvious if you are checking for initialized state or for null, as it does both - When using reflection, scope does not matter (and you have to explicitely set a property to accessible for private properties) While it is not common that I need to check if a property is initialized, I do think there should be a straightforward way to do it. Setting properties through a constructor is not the only way of initializing parts of a class - some use cases were already brought up, like caching or lazy loading. Also, is_initialized cannot be done in userland, as passing an unitialized property to a function already leads to an error, so every way of checking now is a workaround that cannot be made clearer for the reader of the code. I would prefer it if it also worked for untyped properties, just to be consistent. Static analyzers would also have a much easier time understanding the code compared to now. When using isset on a non-nullable property a static analyzer would rightfully complain that the property is not nullable, as it assumes you are checking for null, not for uninitialized - isset in this case is abused to check for uninitialized, hiding the actual intent. Not sure how good static analyzers are at understanding the reflection code, but is_initialized would make things clearer for both humans and analyzers. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] First-class callable syntax
On 20.05.21 21:35, Larry Garfield wrote: There's been a lot of rapid iteration, experimentation, and rejection. The most recent alternatives are this one from Levi: https://gist.github.com/morrisonlevi/f7cf949c02f5b9653048e9c52dd3cbfd And this one from me: https://gist.github.com/Crell/ead27e7319e41ba98b166aba89fcd7e8 The main takeaways (to give context to Nikita's proposal): * Because of optional arguments, using the same symbol for "copy one parameter from the underlying function" and "copy all remaining parameters from the underlying function" is not viable. It runs into oddball cases where you may intend to only use one argument but end up using multiple, especially in array operation functions that sometimes silently pass keys along to callbacks if they can. Hence the separate ? and ... that were proposed. * Named arguments make things more complicated. One of the questions is whether named placeholders should be supported or not. And if they are, does that mean you can effectively reorder the arguments in the partial application, and what does that mean for usability. It gets complicated and scope-creepy fast. * The most important use cases are: ** "prefill nothing, just give me a callable" (which is the case Nikita's RFC covers) ** "reduce an arbitrary function to a single remaining argument", which lets it be used by various existing callback functions in the standard library (array_map, array_filter, etc.), many user-space APIs, and the pipes RFC that I am planning to bring back up once PFA is figured out (https://wiki.php.net/rfc/pipe-operator-v2). While there are other use cases, the two of those cover the vast majority of uses. (There is some dispute about which of those is larger, or will be larger in the future.) It took a while to realize the first point, which basically killed "? means zero or more". We also went down a rabbit hole of trying to make argument reordering work because some people asked for it, but as noted that's a very deep rabbit hole. My gist above was a reduced-scope version of Levi's that uses two symbols and drops named placeholders. It doesn't give us every possible combination, but it does give us most reasonable combinations. Nikita's "just do the first one" RFC (this thread) was proposed at about the same time, and takes an even-further scope reduction. My own take is that the PFA discussion has been overly-bikeshedded, which is unfortunate since I think we're quite close to now having a workable answer that covers most reasonable use cases. While I agree Nikita's RFC here would be an improvement over 8.0, I don't think throwing in the towel on PFA yet is a good idea. It's a much more robust and powerful approach that still gets us the "first class callable" syntax we all want (at least I assume we all do), and lots of additional power to boot. I'd rather see us try to drive PFA home to completion. If that proves impossible by early July, then this RFC would still get us something this cycle, as long as the syntax is still compatible with PFA. (Otherwise whenever PFA gets sorted out in the future we end up with yet-more-ways to do the same thing that are not optimizations of each other but just competing syntax, in which case no one wins.) I think Levis proposal and the two symbols ... and ? are a really good improvement to the previous PFA RFC (Nikitas/Joes RFC is a good first step in that direction). I do think named arguments are important, but reordering arguments could be confusing and are not necessary (and if named arguments are used for the PFA, it would make sense to use named arguments for calling it too). Another big reason for me why I like Levis proposal more is that he still includes partially applying the new operator. Although the semantics of the new operator are a bit different from regular functions, it would be very handy to support this special case. array_map is an obvious application: $productObjects = array_map(new Product(?, ?, ?), $productIds, $currencies, $prices); But other usages would probably pop up, like abstracting away dependencies of classes by pre-setting those via PFA, like: $productFactory = new Product($dependency1, $dependency2, ...); $productObjects = array_map($productFactory, $productIds, $currencies, $prices); I really like this because from a users perspective this seems very clear and readable to me, even though from the PHP language perspective it might be more messy. About the bikeshedding: Using "..." as a symbol does make sense to me, as variadic unpacking/variadic arguments have a similar connotation (referring to an unknown/arbitrary amount of elements). * was also suggested (as in "somefunction(*)" instead of "somefunction(...)"), and I like that too - * in regex is any amount of elements (even zero), and ? is exactly one placeholder in SQL. As many PHP developers know regex and SQL this would make PFA code a lot easier to understand even if someone is
Re: [PHP-DEV] [RFC] [Draft] Final constants
On 21.04.21 15:14, Christian Schneider wrote: I never really understood the desire to restrict how people can use your code. If there is no good reason to override the value of a class constant people won't do it. If there might be a good reason (even one you as the original designer didn't predict) then why not leave that door open. While I understand the theoretical benefit of being able to specify this behavior I do think it is almost always counter productive and not a pattern I would encourage. Especially not in a dynamic language like PHP. Such restrictions also convey information and intent. One could argue defining a specific return type to a method is restricting its use, but it also clarifies how something should work and avoids unintended changes. final constants might be more niche, but it gives you a choice on how you want a class constant to behave if child classes are necessary and possibly done by someone else. Having "final" for constants seems a good addition to me, especially if the inconsistent behavior with interface constants can be solved at the same time. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] noreturn type
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
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
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
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] [RFC] Auto-capture multi-line closures and shortfunctions take 2
On 27.03.21 17:05, Rowan Tommins wrote: My biggest concern with automatic capture is the potential for *accidentally* capturing variables - that is, intending to introduce a local variable inside the closure, but capturing a variable from the outer scope that happens to have the same name. This is less of an issue with capture by value, but can still mean resources not being freed, e.g. a large array of data not being freed from memory, or an object destructor not executing when expected. This is more likely in PHP than many other languages, because there is no requirement, or even an option, to explicitly declare a local variable in the closure. It's not a new problem, but since single-expression closures are unlikely to use many local variables, it's probably not one that's been given lots of thought. I do think it is great that you are thinking about how this can negatively effect memory or performance (and things like destructors) and if things can be improved. But do the same problems not exist when binding the current class to an anonymous function - whenever an anonymous function is declared in a class (no matter if by function or fn) the whole class is bound to that function, if you don't explicitely use "static function". That binding can encompass many variables and other classes etc., which is common nowadays with dependency injection, yet I have not heard much about problems surrounding this. Binding the variables from the current scope seems like a smaller impact compared to already binding the whole class and all its dependencies. I would welcome any way of automatically capturing all local variables, as this would be a big "quality-of-life" improvement similar to constructor property promotion, to avoid a lot of boilerplate code. I would not use it that much, but when I use it, it would be a big improvement. Using "fn" for this seems consistent to me, and I don't think people would always use it just because it is shorter - and IDEs and static analyzers could detect and discourage use of "fn" if "function" would be sufficient. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Deprecate implicit non-integer-compatible float to int conversions
On 04.03.21 14:07, G. P. B. wrote: This new version of the RFC can be found on the wiki: [2] https://wiki.php.net/rfc/implicit-float-int-deprecate I like the RFC, but I think the diagnostic messages will be hard to understand when they come up in real scripts, especially because they can be platform-dependent and can have two different reasons, and "non-compatible" is not self-explanatory. Giving a very specific message would be more helpful for people experiencing these errors, something like: * Implicit conversion to int from float(-string) with fractional part * Implicit conversion to int from float(-string) which is outside of int range (=> maybe also mentioning the range of the platform) (Maybe there are additional possible errors to consider, but those two seem two obvious possibilities)
Re: [PHP-DEV] [RFC] Allow object keys in arrays
On 12.01.21 17:51, Marco Pivetta wrote: Code written to deal with `array` in a generic way will no longer work when invoked through code paths that produce object keys: this is a general problem with widening types overall, and is a clear BC break. If you look at levels of BC break, this is on the very low end in my opinion. No existing code will break when upgrading to this new PHP version. Only new code written specifically for that PHP version would be impacted, and frameworks/libraries could, if necessary, add additional checks without becoming incompatible with older PHP versions. It helps that currently array keys can be integers or strings, so if the key type is important, some checking is already necessary. Of course tools like Psalm would see a lot of potential issues, but those would only be potential (with new code using this new feature) and having static analyzers reduces the impact of such a BC break even more, as it becomes much easier to spot issues. Might be interesting to change array key type definitions for a few projects/libraries and see if there are that many potential issues, and what they look like. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Short-match
On 15.12.20 20:08, Sara Golemon wrote: Or even better with existing syntax: ```php $this->handler = match($var) { null, true, false => json_encode($var), default => \is_string($var) ? "\"$var\"" : \rtrim(\print_r($var, true)), }; I appreciate that this is a specific counter-example to your example, but you picked the bad example. :p Sure, for this specific example - there are of course longer real-life examples (sometimes even nested ones), often using instanceof, is_array, is_callable and similar constructs, but they seem a bit too much for a discussion. If you add slightly more logic then it might be better: ```php $this->handler = function ($var): string { return match { null === $var => 'null', true === $var => 'true', false === $var => 'false', is_string($var) => '"'.$var.'"', is_callable($var) => 'callable', is_object($var) => get_class($var), default => rtrim(print_r($var, true)), }; }; ``` I guess that would be an advantage of these current switch(true) (and possibly future match {}) statements: it is easy to add additional matches that do not impact the others. I do like Nikitas idea to make it a TypeError for non-bool matches. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Short-match
I checked in my vendor directory for currently used switch(true) usages, there were 96 matches. It is often used when handling an unknown value and needing to display or convert it, as there the structure of a switch is easier to scan compared to other comparisons like ifs (at least it is for me). Compared to match these switch statements are a lot uglier, which shows that there are use cases for it even when you are forced to use switch. This is a good example in my estimation, from the Symfony Console Dumper class (taken from Symfony 5.2), when a value is converted into a string representation: ```php $this->handler = function ($var): string { switch (true) { case null === $var: return 'null'; case true === $var: return 'true'; case false === $var: return 'false'; case \is_string($var): return '"'.$var.'"'; default: return rtrim(print_r($var, true)); } }; ``` With match this becomes much more concise: ```php $this->handler = function ($var): string { return match { null === $var => 'null', true === $var => 'true', false === $var => 'false', \is_string($var) => '"'.$var.'"', default => rtrim(print_r($var, true)), }; }; ``` The same with ifs: ```php $this->handler = function ($var): string { if (null === $var) { return 'null'; } if (true === $var) { return 'true'; } if (false === $var) { return 'false'; } if (\is_string($var)) { return '"'.$var.'"'; } return rtrim(print_r($var, true)); }; ``` The implied return type for match and the reduced amount of code to scan makes match {} much better in my opinion, with ifs you always have to make sure there isn't additional logic somewhere, and it makes it easy to add more complex code "by accident" compared to match. match (true) would be possible now, but the true makes the code a bit confusing, while without the (true) it reads more like natural language ("match the first possible expression in this list and return a corresponding value"). -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Short-match
On 14.12.20 18:33, Larry Garfield wrote: I present to Internals this tiny RFC to follow up on the match() expression RFC from earlier in the year. There was solidly positive support for this shortcut previously but it was removed for simplicity at the time, with the intent to bring it back later. It's now later. https://wiki.php.net/rfc/short-match I think it is a good addition that will make code clearer. If the main counter-argument is that "if - elseif - else" does the same thing, comparing the syntax to that and showing some real-world examples might even convince some more people who think it is unnecessary, as the code mostly speaks for itself, but the example currently in the RFC might be a bit too simplistic to be convincing for the sceptics. It would also be interesting how much switch(true) is used in open source code currently, as it is the currently used "equivalent" to match(true) - I know it is in some parts of the Symfony code, probably because it is often easier to scan over when compared to huge if / elseif blocks. match(true) is clearly an improvement to switch(true), so while match has almost no use so far in PHP code, switch(true) definitely has. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Measuring maximum execution time based on wall-time
On 11.12.20 10:59, Máté Kocsis wrote: That's why I'd like to add support for measuring the execution timeout based on the wall-time. There are a couple of ways to approach the problem though: - by measuring wall-time on all platforms - by adding a new "max_execution_time_type" or so ini setting for optionally changing the meaning of max_execution_time (this is what HHVM is doing) - by adding a new "max_execution_wall_time" ini setting for being able to timeout based on both the real execution time and the CPU time. My POC implementation at https://github.com/php/php-src/pull/6504 currently uses the third solution, but I would be okay with the other possibilities as well (especially with the first one). I would also be very curious if anyone is aware of the reasons why the CPU time metric was chosen back then? In my opinion, wall-time is much more useful, but maybe I'm just missing some technical limitations (?). For my applications the current behavior is the more important one, but implementing both (and being able to set both limits independently) would be an interesting improvement. Next to having hard limits, having a way similar to FPMs request_slowlog_timeout in PHP would be a useful addition in my opinion: to detect slow requests/scripts and report them, as that can be an early warning and something worthy to analyze. Basically, set a time limit for either cpu or wall time, or both, and if that limit is reached call a PHP callable to report it or handle it in some way (similar to how pcntl_signal can act on signals in an async way). This would open up more options, as the current max_execution_time or a new max_execution_wall_time would be a last resort, but most of the time I would rather know about a problem early on and log it. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Attributes and constructor property promotion
On 06.10.20 17:15, Sara Golemon wrote: My opinion on constructor property promotion (CPP) is that it's something for small value object classes and should probably be regarded as code-smell on larger classes. At the same time, annotations belong with more complex objects and not so much with small "struct-like" classes. Given that position, I think we should err towards strictness in how attributes are applied to CPP declarations. That is, we should require them to be meaningfully applicable to both arguments and properties in order to be used in a CPP context. If that's a problem for the consumer, then they should avoid use of CPP. -Sara The current usage of annotations is quite often with small struct-like classes though - I mainly use annotations (and will use attributes) for data that needs to be validated, or entity-like classes that contain data. Those classes are small and simple and would benefit greatly from CPP and attributes used in combination, so it would be a pity to make that impossible. From my understanding suppressing the validation errors in this particular case would be a good solution, or are there any serious downsides to that? -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC: Support for multi-line arrow functions
On 05.10.20 12:15, Deleu wrote: To me that seems like a great argument in favour of the proposal. If you'll want all variables to be imported (which in this case makes completely sense), then `fn() {}` or `fn() => {}` is much less verbose and inline with the mentality to reach for short closures. We reach for short closures to avoid `use()` and convey that the outer process is intertwined with the inner process. `fn()` allows to strengthen the concept that there's no real separation between running SQL stuff in a `callable` that wraps a database transaction. Not necessarily: the arrow functions were specifically implemented for very short anonymous functions with a return value. Making them more and more like the existing "function" syntax would lead to having two different ways of defining anonymous functions that mainly differentiate themselves by including the parent scope by default or not. I like the "function () use (*)" suggestion because it is explicit and opt-in. A shorter syntax like "fn () {}" is less clear, and it could lead to many people always using fn just because it is faster to write (and less to think about), which then could lead to unintended side effects because variables are being copied from the parent scope each time. When you see a usage of "fn () {}" while reading code you would not know if the person used it because it was faster to write, or if the parent scope variables are really needed. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC: Support for multi-line arrow functions
On 05.10.20 12:08, Lynn wrote: How should php deal with the scenario where you want to `use` everything and have one variable by reference? ``` function () use (*, &$butNotThisOne) {}; ``` The easiest would be to only allow "use (*)" with no references or additional syntax. "use (*)" would only copy all local variables into the closure, no references. Personally I have never used references with "use", I think it is much more niche compared to the regular copying, and there is still the explicit (current) syntax to do references. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC: Support for multi-line arrow functions
On 04.10.20 22:08, Rowan Tommins wrote: If we added an opt-in syntax for "capture everything", we might instead write this: $f = function() use (*) { $x = $y = $z = null; } Without re-initialising all local variables, we would no longer be able to know if they were actually local without looking at the surrounding scope for a value that might be captured. I am unconvinced by this trade-off of opt-out instead of opt-in. One use case I've seen proposed is closures which capture a large number of variables; I would be interested to see an example where this is the case and is not a "code smell" in the same way as requiring a large number of parameters. Something like "use (*)" seems like a great enhancement to me. I often use a wrapper function for SQL transactions, something like: ```php public function update(int $numberId, int $addressId, bool $isMainNumber = false): void { $this->transaction->run(function () use ($numberId, $addressId, $isMainNumber): void { // Do all SQL queries for the update }); } ``` In these cases there is a lot of redundancy because of having to import the variables, and if a variable is added, it has to be added in two places in a slightly different way. The following would be much nicer: ```php public function update(int $numberId, int $addressId, bool $isMainNumber = false): void { $this->transaction->run(function () use (*): void { // Do all SQL queries for the update }); } ``` This would also increase code readability. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Shorter Attribute Syntax Change RFC 0.2
On 19.08.20 11:12, Benjamin Eberlei wrote: With the choice being @@ or @{} - nothing would stop someone (not me ;-)) to make an RFC for 8.1 or later proposing to add a second syntax. Sure. If @@ would end up winning again (who knows at this point), at least one positive thing is that @{} could be added later without having a BC break, which reduces the potential future benefits of an enclosed syntax, as it is still possible if needed. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Shorter Attribute Syntax Change RFC 0.2
On 19.08.20 10:47, Benjamin Eberlei wrote: One last change that I didn't see yesterday as it was on Github and not this list is the addition of another syntax proposal @{} with the same benefits as @[], a little more snowflake than compared to other languages, but without the BC Break. I mentioned the benefits of @{} in an email to this list on Monday, with the proposal to have both @@ and @{} as attribute syntax, so both camps could have their syntax (one with delimiters, one without) with minimal BC breaks, and leave the decision to the PHP developers/projects what they prefer in what circumstances, because there can be valid reasons to use both - I probably would use both. @{} could be good to define multiple attributes for classes/properties, @@ could be good for short attributes or ones very entrenched within the code, like function parameters. The @{} syntax could be amended in the future, so this would also be "future-proof". But I guess the division about syntax is too big at this point to consider an approach where we just offer both types of syntax. From a PHP developer viewpoint, it would be preferable though. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Shorter Attribute Syntax Change RFC 0.2
On 18.08.20 00:03, Benas IML wrote: And then boo-yah, 6 months later we want to implement a cool new feature to attributes (a lot of examples were said before, ain't repeating myself) but we can't :(( because there is no ending delimiter and thus, we will run into parsing issues. Both @{} and @@{} would be possible as a future extension of the syntax and would have no BC break at all, if extending the syntax is something that would/should happen - just as possible suggestions. It is likely though that the vast majority of attribute usage will be quite simple (like the ones we have today with annotations: for routes, for validation, for ORMs), so having a simple syntax for a feature which is mostly used in a straightforward way does not seem that crazy. And about your condescending remark of people trying to add to the discussion who have not "proven themselves in the PHP source code": Having a discussion with people who have different viewpoints seems like a big benefit for any project, because it is impossible to be an expert at C code, php-src, PHP code, all PHP frameworks, all the PHP libraries, and all the ways PHP is used today - yet all that can be relevant for language changes and the actual usage of new features, including the syntax. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Shorter Attribute Syntax Change RFC 0.2
As a possible addition/discussion point, I only noticed today that @{} is a syntax that has not been mentioned yet, also not in any previous discussions about attributes as far as I can tell. @{} currently leads to a syntax error, so there is no BC break, and {} is common syntax for grouping expressions in PHP, much more so than [], which is an array-specific syntax. Would it be a possibility to keep @@ and add @{} as a second syntax for attributes, that can be used for grouping (for situations where that makes sense) or other possibly future extensions? Then @@ would be a good syntax for simple attribute definitions, and @{} could be an alternative for people who want to group them or if any more complex attribute features are added to the language later. Because both sides of the "ending delimiter or no ending delimiter" discussion do have some points in their favor, and it seems quite individual what each person prefers. For a language it could be beneficial to give some choices to the developer instead of foreseeing each individual use case, and maybe attributes is such a feature. I previously thought about suggesting both types of syntax (with and without delimiters), but felt the current options all have too many side effects to choose "two side effects" or two BC breaks. But the @@ BC break seems the most harmless BC break of the bunch, and @{} does not have a BC break, so these two option might be good together. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] Shorter Attribute Syntax Change
On 16.08.20 01:07, Paul M. Jones wrote: /me furrows brow If I understand correctly, that means the currently-running vote overlaps with the discussion period? If so, that sounds (again) highly irregular. The proper thing to do here is a full reset: restart the 2-week discussion period at the moment the current vote is declared null and void, then start a new vote (if the RFC is not withdrawn) after thatn 2-week period. Basically, the sooner the current vote is explicitly declared null and avoid, the sooner the properly-conducted 2-week discussion period can begin. Restarting the vote in basically 2 days seems a bit crazy to me too - that would just be as over-hastily as the last time. Again, I don't get it - Sara suggested the 21st as the earliest date to restart the vote. Why does everything has to be done so hastily, and how should a proper discussion happen this way? Benjamin Eberlei is saying that they are now including the arguments for enclosing - and then in two days the vote starts? How should a discussion happen about these points if there is no time for people to actually think about it and respond? As far as I can tell, that is what the 14 days of RFC discussion is about, or longer if needed - to discuss open questions, to include them in the RFC, and make sure a good decision is made with all pertinent information included. By the way, the DocBlock argument Benjamin Eberlei is mentioning is not new - yet annotations in DocBlocks do not need the ending symbol of */ - that is not what encloses annotations, it is what encloses any possible comments. In comparison, an attribute always consists of a class name and then possible parameters, enclosed by parentheses. Peter Bowyer mentioned that the "ending delimiter" argument has been obfuscated to a point where the meaning or reason remains unclear, and I agree - this should be fully explained, discussed and appropriately included in the RFC. I just looked at the RFC - this remains unclear as of now, and deserves its own discussion which still has not happened yet. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] Shorter Attribute Syntax Change
On 15.08.20 12:35, Michał Marcin Brzuchalski wrote: If you wanna follow democratic rules then first of all 4 is not a quorum. Secondly, you should be fine with additional voting about stopping current RFC vote, right? The RFC process has been agreed upon by the people involved with PHP. It does not matter if only one person complains about a rule violation, it should be taken seriously, as the PHP project publicly states that it follows this kind of RFC process. And there was a democratic vote on the RFC process. You seem to mix different concerns - there is no need for a quorum when agreed upon rules are violated. If you steal a purse, then the people of your country do not have to have a vote if that is a crime - it was agreed upon beforehand that it is. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] Shorter Attribute Syntax Change
On 15.08.20 11:54, Michał Marcin Brzuchalski wrote: I don't think there's anything significant changed in the RFC. I really doubt the vote result will change significantly. Currently you're the only one who wants to wipe the vote and there is no much voices willing to follow your proposal. Personally I think extending the vote by additional week is fair enough. Next to Theodore, at least 4 other people in this mailing list have stated that they think the RFC process should be followed as stated in the RFC documents (with proper time for discussion and voting, which was clearly not adhered to) and/or that there is important information missing in the RFC, which both should lead to a change of the RFC and a revote. I am a bit surprised at how casually the RFC process is interpreted - it is the basis of how decisions are made for PHP, yet multiple people have already stated they don't really feel like following the process as described/agreed upon, one of them Derick, a long-time member of PHP Internals, who I would think would want to be a role model for the process. Why even have an RFC process, if parts of it can be ignored depending on the mood of some of its more influential members? Does this behavior inspire confidence in PHP as a language? By the way, the RFC has not yet changed and is still incomplete as of now, and updating it at this time would probably not do much - because how many people re-read an RFC where they already cast the vote? It is unexpected that an RFC is heavily changed after voting has initiated - you would expect it to be complete at that time. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] Shorter Attribute Syntax Change
On 14.08.20 03:41, Levi Morrison via internals wrote: I just want to make sure I understand: there are people who think we haven't discussed the syntax for attributes yet? I assume this is a serious email, but I can't fathom why anyone cares. We've discussed this subject soo much... I am kind of new to the Internals discussions, which might be the reason why I actually read through all the RFC process material, but I recommend anyone to do so too. I will highlight the relevant parts as succinctly as possible: In https://wiki.php.net/rfc/howto - How to create an RFC - it says: * When your RFC is ready for discussion, change the status of your RFC page to "Under Discussion", and send an mail to internals@lists.php.net introducing your RFC. * Listen to the feedback, and try to answer/resolve all questions. Update your RFC to document all the issues and discussions. Cover both the positive and negative arguments. Put the RFC URL into all your replies. * When discussion ends, and a minimum period of two weeks has passed since you mailed internals@lists.php.net in step 4, consider one day heads up mail on the mailing list and then you can move your RFC to “Voting” status. There should be no open questions in the RFC. The two weeks discussion period is specifically about the RFC itself, not the discussion at large, which does make sense to me, as you discuss a specific proposal and are trying to include all relevant information into that RFC, so people voting on the RFC do not have to read through all emails in Internals to get the information - it should be on the RFC page. This is something objectively lacking with this RFC. In https://wiki.php.net/RFC/voting - Voting on PHP features - it says: * Proposal is formally initiated by creating an RFC on PHP wiki and announcing it on the list. * There'd be a minimum of 2 weeks between when an RFC that touches the language is brought up on this list and when it's voted on is required. Other RFCs might use a smaller timeframe, but it should be at least a week. The effective date will not be when the RFC was published on the PHP wiki - but when it was announced on internals@lists.php.net, by the author, with the intention of voting on it. This period can be extended when circumstances warrant it - such as major conferences, key people being busy, force major events, or when discussion merits it - but should never be less than minimal time. * This does not preclude discussion on the merits on any idea or proposal on the list without formally submitting it as a proposal, but the discussion time is measured only since the formal discussion announcement as described above. Here it also specifically mentions a discussion period of two weeks after the RFC was created and announced on the list, yet it mentions it can be only one week if it "does not touch the language". An RFC with a syntax change would definitely touch the language in my opinion. It also mentions again that the discussion period is after the announcement on the list of the RFC - not after the discussion began about the topic in general. The RFC has to exist and be mentioned with the intent on voting on it. Now, I don't know all the history of past RFCs, and maybe some of these rules were not always followed, which someone alluded to in another email. Yet in my understanding of the process, if nobody mentions that timeframes were not heeded or that RFCs are incomplete, it seems likely that there is already a large concensus around the topic, and nobody cares about the details of the process. This is fine, and no harm is done, although it might be good to remember the rules just to be consistent. If on the other hand people reference the documents that should steer the RFC process and there is a clear violation of those, and if there are multiple people who feel their points have not been included in an RFC, then it makes sense to actually read through the RFC documents again and follow them as intended, as obviously the intent of these documents are different from what is happening. Something else to point out, on https://wiki.php.net/rfc at the top it says: * An RFC is effectively “owned” by the person that created it. If you want to make changes, get permission from the creator. If no agreement can be found, the only course of action is to create a competing RFC. In this case, the old RFC page should be modified to become an intermediate page that points to all the competing RFC's. This might be an alternative, if the many discussion points are not included in this RFC and it therefore remains incomplete, to make a competing RFC. Not sure if this has ever been done, but it is on the main RFC overview page, although it seems sad if that would be necessary. I would like to mention that I would help any efforts to make this or another RFC about a possible attribute syntax change as information-complete as possibl
Re: [PHP-DEV] [VOTE] Shorter Attribute Syntax Change
On 13.08.20 15:17, Theodore Brown wrote: The discussion thread you're referencing did not announce an RFC. Per the voting rules, a "Proposal is formally initiated by creating an RFC on PHP wiki and announcing it on the list". After that there must be a minimum two week discussion period before voting starts. The Shorter Attribute Syntax Change RFC failed to meet this requirement. After reading https://wiki.php.net/rfc/howto it is stated clearly there that an RFC has to be created and be "Under Discussion" for at least two weeks. So you were actually wrong that the RFC was one day early - it was at least 8 days early, as the RFC was created and announced on the 4th of August and then put to vote on the 10th of August. It also states in this document: * Listen to the feedback, and try to answer/resolve all questions * Update your RFC to document all the issues and discussions * Cover both the positive and negative arguments Can anybody say with a straight face that this has been done in this case? Just one example: It still states in the RFC that the ending symbol is inconsistent with the language, although multiple people argued another viewpoint about this part with detailed explanations. This kind of discussion belongs in an RFC to show both sides, not just the one that suits the person writing the RFC. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] Shorter Attribute Syntax Change
On 12.08.20 17:25, Sara Golemon wrote: Changing the syntax isn't a feature. It's a refinement. One of the things our long release process provides is a chance to be absolutely certain before we introduce syntax we'll come to regret later. The current RFC does not discuss the BC breaks of each syntax (which seems very important to any syntax changes), it has not taken into account the discussion, and the RFC itself was being discussed for only 6 days (of which two days were on the weekend) before it started its voting process. The discussion was still very much ongoing when voting started. Shoehorning in a syntax at the last minute seems like the opposite of a controlled and long-term release process, at least if there is an ongoing discussion. Looking at the RFC votes now, the opinions are clearly split, which is not a good sign - at least in the previous RFC @@ was a clear winner. Changing syntax again now for the third time could just as well be the decision that will be regretted later on, instead of finding a better concensus in due time. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] Shorter Attribute Syntax Change
On 11.08.20 18:38, Sara Golemon wrote: The perf penalty on 7 and earlier would probably be similar to existing state of the world. Parsing a docblock is easier to fetch from the runtime (as we actually store it), but docblocks contain more than just annotations, so some plus some minus. PHP 8+ performance on theses would certainly be between though, and that's an extra carrot to push users to upgrade. If annotations can't be written until after users upgrade, then that carrot vanishes. If this is something that would realistically happen, I feel this would have needed more explanation in an RFC and maybe some small tests to demonstrate feasability, then it would be a big argument. I read through all the RFCs, but only realized the meaning of this argument now, with some more context. If the Doctrine Annotations library would support a syntax with # for pre-PHP-8 and it would be fast enough, then this argument would be more convincing to me than any of the others together. And it would not need to be #[], it could be any syntax that starts with # - it could also be #@, which definitely seems weird at first, but seems much less likely to occur in code than #[ and would be more similar to current annotations and Javascript syntax. Or it could be something completely different, like #~, which I cannot imagine ever comes up in actual code. Because Rust using the #[] syntax does not seem like an advantage, as Rust syntax in general looks completely different compared to PHP. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] Shorter Attribute Syntax Change
On 11.08.20 18:07, Sara Golemon wrote: Writing this on PHP 7 (or any earlier version for that matter) would be valid syntax (ignored as a comment): #[SomeAttr(123)] function someFunc() {} That's what's meant by Forward Compatibility. Library/Framework authors could aggressively adopt attributes with the #[...] syntax, they can NOT do so with any other syntax. This would be a feature if libraries start parsing PHP token by token and start supporting the #[] syntax for the 7.x versions of PHP - then early adoption would be possible and it would be a real feature. But it seems unclear if that will happen, as it will probably have a heavy price on performance (and might have some complexity). And if some libraries implement it but others don't, then it might get confusing for users about why the new attribute syntax sometimes works and sometimes silently does nothing. It is also not perfect as multi-line attributes with #[ still break, or code with #[] followed by more code instead of a newline and then more code. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] Shorter Attribute Syntax Change
On 11.08.20 15:15, Lynn wrote: If typability really matters, we should've deprecated the backtick version to run things. We also seem to forget about readability. @@ makes things really hard to read for me as it draws attention, the same goes for <> being written as such, with spaces it's fine. In terms of @[] typability, my IDE auto completes the ] when I type [. After that we have to type a word which will most likely require keys on the right side of the keyboard anyway. Sure, typing @@ is easier, for me this is at the cost of readability. I read code more frequently than I write it, so I think this should matter more. Please don't use @@ for annotations/attributes. I do understand that not everyone likes @@ in terms of perceived readability, although in IDEs this will probably be less of a problem (by making @@ less noticeable in terms of colors and contrast). It seems unfortunate to me that this RFC just seems super hasty in terms of unfinished discussions and in that it mixes very different concerns - an ending delimiter is made out to be necessary in terms of language, although that seems contentious at best and would be something to agree on first, separate of the actual syntax and how it looks and feels. And if someone does not like @@ yet would like a different syntax with no delimiters, there is no choice for that. The @[] syntax is very last minute, and including the original choice of @: would have also been an option: at the time it lost against <<>>, but after that <<>> lost against @@, so the choices in the RFC are obviously chosen to make sure a syntax with delimiters is chosen, yet sacrificing a proper discussion (and enable people to think about it more) because of the time constraints - instead of just delaying it for 8.1 and having the necessary time to get to the best possible solution. Just compare the previous RFCs about the attribute feature and syntax and the current one - the current one does not even explain the BC breaks the different syntaxes produce, which was otherwise always one of the more important parts of an RFC, so at best the RFC is incomplete in terms of its information. As far as I can tell almost none of the suggestions to amend the RFCs have been taken into account, so the original discussion about it seems to have been pointless. I am a bit disappointed to see this kind of process in PHP, especially "last-minute" before a new major release. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] Shorter Attribute Syntax Change
On 10.08.20 17:40, Derick Rethans wrote: It missing an ending delimiter was my first reason for wanting to get something better than @@. I don't particularly care much if it ends up being @[], #[], <<>>, or other things such as @:( ). If you have something to open, and close, there there is a distinct area that forms the whole definition of a thing. That's why functions, and classes have { and }, if and other control structures have ( .. ), etc. Being able to define a whole "thing" easily with an open and closing set of symbols, allows for better mental parsing. It also means that syntax highlighting tools can map the opening part with the closing part. (VIM for example, uses the % character to jump between opening and closing symbol). For me the difference would be that with attributes, you are not opening and closing many possible statements, it can only be one (or more, with grouping) class name(s), which then can have arguments, but those are enclosed with (). In comparison, classes can have many possible definitions inside of them (class variables, methods, constants, etc.), so enclosing them clearly makes sense, as you need to know where it ends. The same goes for if, for, while, etc. So if you just have one class name as an attribute, enclosing it seems a bit overkill, as there is already a definition of a class name and how it starts and ends, which is why for me the mental parsing does not seem easier - but what is easily parseable probably depends on many factors and might be different for different people. I would have found a syntax where the delimiters are optional preferable - similar to "if", where you can leave off the {} for exactly one instruction, but you have to add them if there is more than one line of instructions. Or the group use syntax. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] Shorter Attribute Syntax Change
On 10.08.20 15:05, Markus Fischer wrote: Personally, and never gave it much thought TBH, the `@@` AND `<<`/`>>` in fact is the most "unreadable" version to me because duplicate occurrence of a single character somehow creates a noise _for me_, I don't feel eligible to have a vote, but based on that and certainly aware IDEs in the future will help with this, I would vote for _anything_ not duplicating characters, i.e. favoring `#[]` or `@[]` It is a pity that syntax with ending delimiters and syntax with no ending delimiters are now mixed in the discussion, instead of first finding a concensus if delimiters are even needed or what advantages/disadvantages they have. Because there are many alternatives in terms of syntax - looking back at the very first vote about attributes the @: syntax doesn't seem so bad, if no ending delimiters are needed. In the new RFC all alternatives to @@ have delimiters and it is suggested having them is good, yet the possible advantages of delimiters are never explained, ideally with some real-world examples showing why delimiters would be good to have. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] Shorter Attribute Syntax Change
On 10.08.20 15:08, Benjamin Eberlei wrote: () does not count as ending symbol, because it is not required, as such its not an ending symbol. The point Andreas Leathley makes in the discussion thread about new Foo not having an end symbol demonstrates exactly the opposite point he was trying to make, because the new statement itself has to end with a semicolon: new Foo(); new Foo; A statement has an ending symbol semicolon. While I don't know the exact internal semantics of PHP, according to my grasp of the language the new keyword does not need a semicolon at the end - it can be part of any expression, like "new Foo(new Bar);". According to the PHP manual (https://www.php.net/manual/en/language.basic-syntax.instruction-separation.php) instructions in PHP need to be terminated with a semicolon, while "new" as a keyword has no special requirement about a starting or ending delimiter. The point I was trying to make was that new and attributes have the same requirements in that they both need a class name and then optionally arguments for the constructor to that class, so they are both narrow in terms of what they do, attributes even more so than new, which reduces the helpfulness of delimiters as you cannot define arbitrary instructions in attributes - it always starts off with a class and then any possibly more complex instructions will be in the arguments, and those are enclosed by (). -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Shorter Attribute Syntax Change RFC 0.2
Hello Derick & Internals, I am a daily user of PHP and read through all the recent discussions about the attribute syntax, and thought I could add some slightly different viewpoints from an "end-user" who uses the current annotations a lot. This is my first time posting, so I am hoping I am doing this the right way ;-) Currently, I am favoring @@, although I don't have strong preferences to other syntax if it is more useful in some way. Why I prefer @@: 1. The @ symbol is hardly used in PHP, except for error suppression and within comments, so searching and scanning over code with @@ works well and does not have much ambiguity. The syntax with [] (and a symbol) is very close to the PHP syntax for arrays and destructuring, and would now have a different meaning in addition to that. This is not the case for C/C++/C# as far as I can tell, as [] is rarely used in those languages so having [] for attributes there makes it quite recognizable/unique. 2. A big argument about the ending delimiter is about consistency. Yet isn't an attribute almost like the "new" keyword, which also only allows a class name and then optionally some arguments passed to the constructor? It is not like you can define anything but a class + arguments as an attribute, and "new" does not have starting and ending delimiters. 3. What would starting and ending delimiters be used for except for grouping attributes? I would be really interested in use cases, and if delimiters are important, then a few real-world examples why they are important and how the syntax will come in handy later would be the best argument for them. After using the current annotations for years it has not occured to me that something is fundamentally missing, and attributes have been used for many years as annotations in PHP as well as in other languages, so there should be some evidence/examples. 4. If at a later time grouping or more options become necessary, something like @@{} could be an optional syntax. Using {} to optionally group something in PHP has a lot of precendence, and if it is only optional, it seems like a reasonable addition while still having the simple just-one-class-with-arguments attributes. When looking at the new RFC, I feel like none of the syntax arguments in the RFC are very self-explanatory or even would be a factor why I would prefer them or not. A larger explanation about each syntax, some real code samples with each syntax (possibly with colors) and longer pro/con arguments would be a lot better for an informed decision, so if there is a lot of contention around the syntax, I think more time to flesh out such an RFC and then do it for 8.1 would be better. At the same time I do feel like @@ would be a good syntax, but if there are open questions or more discussions to be had it might be better to have the time for those compared to having hasty discussions now with a hasty vote where everyone will be unhappy at the end. Best regards, Andreas -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php