Re: [PHP-DEV] RFC: Stop to automatically cast numeric-string to int when using them as array-key
On Wed, 29 Dec 2021, 15:42 Vincent Langlet, wrote: > > I recently discovered that an array was automatically casting > numeric-string keys to int if it was possible. > Having had to track down bugs numerous times over the years, I completely agree this is unexpected behaviour, and would be in favour of it being amended. It is quite a BC break indeed, and both Orklah (Psalm) and Ondrej Mirtes (PHP Stan) agree that the issue is that it's a difficult issue to identify with static analysis (see https://twitter.com/OndrejMirtes/status/1478971968636567552 for some thoughts). As always with type juggling related discussions in PHP, I expect any RFC to be contentious and heavily discussed ;) I expect the main detractors would be the BC breaks, and people might not think the BC break is worth the pain. Just thinking out loud, being able to identify an array type might be a way forward here (using "syntax" already in use by static analysis tools in docblocks, for familiarity), e.g. private array $property; This might "turn off" the automatic type juggling behaviour, for example. If the existing strict_types=1 mode is on, this might fail: $this->property[3] = "hi"; If strict_types=0 or not declared, the key would be cast to a string. That said, I know there has been contentious discussion on this and the related topic of generics multiple times, so don't really want to stir up a hornet's nest there. Great idea, and I'd love to see this fixed, given the countless hours I've wasted trying to track down bugs that are a result of this. But I fear that this would be a difficult one to push through the RFC process, sadly. I hope I'm proven wrong though! Thanks James >
Re: [PHP-DEV] RFC: Trait expects interface
On Wed, Jan 5, 2022 at 11:05 PM Larry Garfield wrote: > On Wed, Jan 5, 2022, at 2:35 PM, Chase Peeler wrote: > > For point 2, that's mainly useful as a way to signal to other developers > "hey, this trait has all but one method of the LoggerInterface, that's how > you'd use it", and to signal static analyzers and refactoring tools the > same thing so that they can be auto-updated if you tweak the interface. I > can see a use for point 2, and it would make my life a bit easier, but it's > overall not high priority. > > I think existing constructs provide 99% of this benefit anyway. interface I { public function hello(); } abstract class A implements I { abstract public function hello(); } trait T { public function hello() { echo 'hello'; } } class C extends A { use T; } // or alternatively class D implements I { use T; } // or abstract class E implements I { use T; } class F extends E { ... } $c = new C; $c->hello(); // $c is instanceof I $d = new D; $d->hello(); // $d is instanceof I $f = new F; $f->hello(); // $f is instanceof I It's not quite as neat as directly having a way of annotating T to say it implements I, but it does the job insofar as your IDE and tools should be able to immediately pick up a change in interface I is not fulfilled by anything relying on trait T to be of type I, either directly or by inheritance. The remaining 1% of benefit could probably be achieved just by naming convention: interface LoggerInterface { ... } trait LoggerInterface_FileLogger { ... } But I still think both goals would be better achieved with something like: interface LoggerInterface { default public function error(string $message) { $this->logger->log('error', $message); } } in the manner of Java...no idea how easy or not it would be for someone a little more experienced than me working on PHP core to do this though. - David > --Larry Garfield > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
Re: [PHP-DEV] RFC: Trait expects interface
On Wed, Jan 5, 2022, at 2:35 PM, Chase Peeler wrote: > First, I'm someone that mainly uses traits to implement the functionality > defined in an interface. I think that's one of the best uses for them. > However, I'm personally not a huge fan of overly restrictive things. For > instance, while there are definitely some use cases for them, I need a > REALLY good reason to justify making a property/method private instead of > protected, or making a class final. I am much the same. > As such, I think this would be better if it didn't throw a fatal error. > When you make it optional, however, I think you are left with something > that can be handled with an attribute just as well as a new keyword: > #[Expects('MyInterface')] > trait foo { } > > However, there might be value in generating a notice/warning, and I think > that would require a keyword, correct? (Not that up to speed on > annotations). Another option might be two support two new keywords: > requires and expects. The former would throw an error if the interface > isn't implemented while the latter will throw a warning/notice/nothing. > > Another option (and I haven't thought about this one enough to decide if I > like it) would be to have the expected interface automatically implemented > in the using class. This would allow the trait to be written under the > assumption it has access to the methods defined in the interface, and will > then throw an error if any of the methods are not implemented in the using > class: > > interface foo { > function a(); > function b(); > } > > trait bar expects foo { >function c(){ >return $this->a() + $this->b(); >} > } > > class baz { > use foo; > } > > The above would throw an error since a() and b() are never implemented and > baz is implementing the foo interface. You can currently get the same > behavior if you define a() and b() as abstract in the trait. However, this > doesn't give you the added benefit of utilizing the interface automatically > within the type system. The more I think about it, the less I like this > idea, since it doesn't require that much additional work to make the code > clearer by explicitly implementing the interface on the class if you want > it implemented. However, I'll go ahead and leave it here because it might > help generate some other ideas. I... still don't see any use in this annotation. Stepping back and ignoring the syntax for a moment, there's two different things here: 1. "This trait expects to be used in a class that has these other methods on it". 2. "This trait mostly/fully fulfills interface X, because it has methods a, b, and c." For point 1, we already have that. It's called abstract methods in traits. This is a solved problem that requires no further resolution. At best it would be a shorthand to copying a few methods from an interface into the trait and sticking "abstract" in front of them. I really don't see a need for that. For point 2, that's mainly useful as a way to signal to other developers "hey, this trait has all but one method of the LoggerInterface, that's how you'd use it", and to signal static analyzers and refactoring tools the same thing so that they can be auto-updated if you tweak the interface. I can see a use for point 2, and it would make my life a bit easier, but it's overall not high priority. --Larry Garfield -- 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 Wed, Jan 5, 2022 at 3:24 PM Andreas Hennings wrote: > On Wed, 5 Jan 2022 at 20:11, Jordan LeDoux > wrote: > > > > > > > > On Wed, Jan 5, 2022 at 6:33 AM Andreas Hennings > wrote: > >> > >> Hello Jordan, > >> do you have any thoughts about these symmetric/left/right modifiers, > >> to get rid of the $operandPos parameter? > >> > >> To me, the parameter could be the kind of thing where in hindsight we > >> ask "why?". > >> > >> Also, can we drop the "public" modifier, if we do a new version of the > RFC? > >> > >> Cheers > >> Andreas > > > > > > It's a totally different design concept (symmetric/left/right) and I've > been going over the design implications before I responded. For instance, > wouldn't this be a special case of method overloading? You're overloading > according to a modifier, not the typing, but there is that to contend with. > If someone defined `symmetric operator +` and `left operator +` which would > be used? (My feeling is left as its more specific.) > > You would not be allowed to provide both on the same class. > > A class can provide either no operator, or the left operator, or the > right operator, or both. > A "symmetric" operator is a shortcut to providing both left and right, > but using the same implementation. > A class with a "symmetric" operator cannot also have a "left" or > "right" version of the same operator - this would be the same as two > methods with the same name. > However, if the parent class has a "symmetric" operator, you _can_ > override the "left" and/or "right" version in the subclass. In that > case, if the subclass provides "left", then the parent "symmetric" > implementation would only be used for the "right" direction. > > I am writing "right" and "left" here, but perhaps "normal" and > "inverted" would be less ambiguous. > Also, perhaps instead of "symmetric" we could write "left right". > > Perhaps this code will clarify: > > class C { > symmetric operator * (int $other) {..} > # left operator * (int $other) {..} // -> Error, already defined. > left operator - (int $other) {..} > right operator - (int $other) {..} > left operator / (float $other) {..} > left operator % (D $other) {..} > } > > class D { > right operator % (C $other) {..} > } > > (new C()) * 5; // -> symmetric operator * > 5 * (new C()); // -> symmetric operator * > (new C()) - 5; // -> left operator - > 5 - (new C()); // -> right operator - > (new C()) / 5; // -> left operator / > 5 / (new C()); // -> Error, no operator provided. > > (new C()) % (new D()); // -> left operator % provided by C. > (new D()) % (new C()); // -> Error, not supported. > > This means, the "right operator" will only ever be called if the left > side does not provide a "left operator". > > Basically this is not so different from your RFC. > Just instead of having to do a "if ($operandPos === > OperandPosition::LeftSide) {..}" inside an implementation, we are > providing two separate implementations. > > > > How would they be stored within the zend_class_entry? Since they would > technically have the same name, something would need to happen for them to > not be in the function table. > > The right and left version would need to be distinguished somehow > internally. > I would say "left" is the default, and "right" has a modifier to its name. > Perhaps for symmetric operators, we could store two distinct entries > internally, if that makes things easier. > > If nothing else symmetric could be handled by having the compiler replace it with left/right version that executes the same code > > > > The public modifier is not required (as stated in the RFC), you can just > add it if you want. Are you asking for `public operator` to produce a > compile error? > > That would be the idea. > Perhaps others will disagree. > Allowing the "public" introduces a meaningless choice that people can > argue about in their code style, and have pointless git commits where > they add or remove the modifier based on preference. > Of course the same could be said about "public" in interface methods. > > I personally don't like it when I don't have a consistent look to my code. One of the things that bother me is code like: function foo(){} protected function bar(){} function baz(){} I want everything to have a visibility indicator for visual consistency. That's why I always use public in my interface methods as well. So, even though it won't cause confusion if omitted for an operator, since it can only be public, I still think it should be allowed. > -- Andreas > > > > > Jordan > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > > -- Chase Peeler chasepee...@gmail.com
Re: [PHP-DEV] RFC: Trait expects interface
On Wed, Jan 5, 2022 at 2:17 PM David Gebler wrote: > On Tue, Jan 4, 2022 at 10:35 PM Kirill Nesmeyanov wrote: > > > How relevant do you think this idea/proposal is? And what possible > > problems or solutions will this entail in the future? > > > > I'm not convinced there's a reasonable need for it. The very nature of > finding yourself in a situation where you want any class using a trait to > also require other things outside the trait kind of suggests you really > want to be using interfaces or abstract classes anyway. > > There is a similar concept for what I think you're trying to achieve in > Java, though, which could also be useful in PHP if it was feasible within > the engine - the ability to provide a default method implementation on > interfaces themselves. > > Short of that, we can already effectively get there with the tools we have; > an abstract class can use a trait and define abstract or concrete methods, > and in doing so can implement one or more interfaces. Obviously traits can > also declare abstract methods but I assume it's the identity/type aspect of > an interface you want here which isn't satisfied by that approach. > > Also worth noting, although I can't say I'm familiar with the mechanics of > traits in PHP's implementation, my understanding has always been that > they're effectively compiler-level copy and paste in to a class so I'm not > sure what interfaces are implemented by the class (or conversely allowing a > trait to implement an interface) would be readily achievable. > > That's my two cents, good luck with whatever you're trying to do anyway. > > - David > > > > -- > > Kirill Nesmeyanov > First, I'm someone that mainly uses traits to implement the functionality defined in an interface. I think that's one of the best uses for them. However, I'm personally not a huge fan of overly restrictive things. For instance, while there are definitely some use cases for them, I need a REALLY good reason to justify making a property/method private instead of protected, or making a class final. As such, I think this would be better if it didn't throw a fatal error. When you make it optional, however, I think you are left with something that can be handled with an attribute just as well as a new keyword: #[Expects('MyInterface')] trait foo { } However, there might be value in generating a notice/warning, and I think that would require a keyword, correct? (Not that up to speed on annotations). Another option might be two support two new keywords: requires and expects. The former would throw an error if the interface isn't implemented while the latter will throw a warning/notice/nothing. Another option (and I haven't thought about this one enough to decide if I like it) would be to have the expected interface automatically implemented in the using class. This would allow the trait to be written under the assumption it has access to the methods defined in the interface, and will then throw an error if any of the methods are not implemented in the using class: interface foo { function a(); function b(); } trait bar expects foo { function c(){ return $this->a() + $this->b(); } } class baz { use foo; } The above would throw an error since a() and b() are never implemented and baz is implementing the foo interface. You can currently get the same behavior if you define a() and b() as abstract in the trait. However, this doesn't give you the added benefit of utilizing the interface automatically within the type system. The more I think about it, the less I like this idea, since it doesn't require that much additional work to make the code clearer by explicitly implementing the interface on the class if you want it implemented. However, I'll go ahead and leave it here because it might help generate some other ideas. -- Chase Peeler chasepee...@gmail.com
Re: [PHP-DEV] [VOTE] User Defined Operator Overloads
On Wed, 5 Jan 2022 at 20:11, Jordan LeDoux wrote: > > > > On Wed, Jan 5, 2022 at 6:33 AM Andreas Hennings wrote: >> >> Hello Jordan, >> do you have any thoughts about these symmetric/left/right modifiers, >> to get rid of the $operandPos parameter? >> >> To me, the parameter could be the kind of thing where in hindsight we >> ask "why?". >> >> Also, can we drop the "public" modifier, if we do a new version of the RFC? >> >> Cheers >> Andreas > > > It's a totally different design concept (symmetric/left/right) and I've been > going over the design implications before I responded. For instance, wouldn't > this be a special case of method overloading? You're overloading according to > a modifier, not the typing, but there is that to contend with. If someone > defined `symmetric operator +` and `left operator +` which would be used? (My > feeling is left as its more specific.) You would not be allowed to provide both on the same class. A class can provide either no operator, or the left operator, or the right operator, or both. A "symmetric" operator is a shortcut to providing both left and right, but using the same implementation. A class with a "symmetric" operator cannot also have a "left" or "right" version of the same operator - this would be the same as two methods with the same name. However, if the parent class has a "symmetric" operator, you _can_ override the "left" and/or "right" version in the subclass. In that case, if the subclass provides "left", then the parent "symmetric" implementation would only be used for the "right" direction. I am writing "right" and "left" here, but perhaps "normal" and "inverted" would be less ambiguous. Also, perhaps instead of "symmetric" we could write "left right". Perhaps this code will clarify: class C { symmetric operator * (int $other) {..} # left operator * (int $other) {..} // -> Error, already defined. left operator - (int $other) {..} right operator - (int $other) {..} left operator / (float $other) {..} left operator % (D $other) {..} } class D { right operator % (C $other) {..} } (new C()) * 5; // -> symmetric operator * 5 * (new C()); // -> symmetric operator * (new C()) - 5; // -> left operator - 5 - (new C()); // -> right operator - (new C()) / 5; // -> left operator / 5 / (new C()); // -> Error, no operator provided. (new C()) % (new D()); // -> left operator % provided by C. (new D()) % (new C()); // -> Error, not supported. This means, the "right operator" will only ever be called if the left side does not provide a "left operator". Basically this is not so different from your RFC. Just instead of having to do a "if ($operandPos === OperandPosition::LeftSide) {..}" inside an implementation, we are providing two separate implementations. > How would they be stored within the zend_class_entry? Since they would > technically have the same name, something would need to happen for them to > not be in the function table. The right and left version would need to be distinguished somehow internally. I would say "left" is the default, and "right" has a modifier to its name. Perhaps for symmetric operators, we could store two distinct entries internally, if that makes things easier. > > The public modifier is not required (as stated in the RFC), you can just add > it if you want. Are you asking for `public operator` to produce a compile > error? That would be the idea. Perhaps others will disagree. Allowing the "public" introduces a meaningless choice that people can argue about in their code style, and have pointless git commits where they add or remove the modifier based on preference. Of course the same could be said about "public" in interface methods. -- Andreas > > Jordan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC: Trait expects interface
On Tue, Jan 4, 2022 at 10:35 PM Kirill Nesmeyanov wrote: > How relevant do you think this idea/proposal is? And what possible > problems or solutions will this entail in the future? > I'm not convinced there's a reasonable need for it. The very nature of finding yourself in a situation where you want any class using a trait to also require other things outside the trait kind of suggests you really want to be using interfaces or abstract classes anyway. There is a similar concept for what I think you're trying to achieve in Java, though, which could also be useful in PHP if it was feasible within the engine - the ability to provide a default method implementation on interfaces themselves. Short of that, we can already effectively get there with the tools we have; an abstract class can use a trait and define abstract or concrete methods, and in doing so can implement one or more interfaces. Obviously traits can also declare abstract methods but I assume it's the identity/type aspect of an interface you want here which isn't satisfied by that approach. Also worth noting, although I can't say I'm familiar with the mechanics of traits in PHP's implementation, my understanding has always been that they're effectively compiler-level copy and paste in to a class so I'm not sure what interfaces are implemented by the class (or conversely allowing a trait to implement an interface) would be readily achievable. That's my two cents, good luck with whatever you're trying to do anyway. - David > -- > Kirill Nesmeyanov
Re: [PHP-DEV] [VOTE] User Defined Operator Overloads
On Wed, Jan 5, 2022 at 6:33 AM Andreas Hennings wrote: > Hello Jordan, > do you have any thoughts about these symmetric/left/right modifiers, > to get rid of the $operandPos parameter? > > To me, the parameter could be the kind of thing where in hindsight we > ask "why?". > > Also, can we drop the "public" modifier, if we do a new version of the RFC? > > Cheers > Andreas > It's a totally different design concept (symmetric/left/right) and I've been going over the design implications before I responded. For instance, wouldn't this be a special case of method overloading? You're overloading according to a modifier, not the typing, but there is that to contend with. If someone defined `symmetric operator +` and `left operator +` which would be used? (My feeling is left as its more specific.) How would they be stored within the zend_class_entry? Since they would technically have the same name, something would need to happen for them to not be in the function table. The public modifier is not required (as stated in the RFC), you can just add it if you want. Are you asking for `public operator` to produce a compile error? Jordan
Re: [PHP-DEV] RFC: Trait expects interface
On 04/01/2022 22:35, Kirill Nesmeyanov wrote: Since «traits» are often an indicator of not very good code and many may not use them quite correctly, for example, as helpers, I suggest adding support for the `expects` keyword to indicate that the trait is part of the code decomposition taking into account ISP. Hi Kirill, I'm a little confused what problem this is trying to solve - in what way does using a trait in the "wrong" inheritance hierarchy constitute "abuse"? On 04/01/2022 23:10, Bruce Weirdan wrote: Prior art: @psalm-require-extends and @psalm-require-implements Psalm annotations:https://psalm.dev/docs/annotating_code/supported_annotations/#psalm-require-extends ... and on 05/01/2022 12:36, Saif Eddin Gmati wrote: ref:https://docs.hhvm.com/hack/traits-and-interfaces/trait-and-interface-requirements The examples in both of these cases appear to be using the requirements primarily as short-hand for listing abstract methods in the trait. For instance: interface FooInterface { public function doFoo(); } trait SillyFooTrait { require implements FooInterface; public function doFooTwice() { $this->doFoo(); $this->doFoo(); } } Is essentially equivalent to: trait SillyFooTrait { abstract public function doFoo(); public function doFooTwice() { $this->doFoo(); $this->doFoo(); } } In other words, the requirement is there because it is actually a requirement for the trait to work correctly, not because of some perceived "correct" use of the trait. This doesn't seem to match your reasoning for proposing the syntax, so maybe I'm missing something? Regards, -- Rowan Tommins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] User Defined Operator Overloads
Hello Jordan, do you have any thoughts about these symmetric/left/right modifiers, to get rid of the $operandPos parameter? To me, the parameter could be the kind of thing where in hindsight we ask "why?". Also, can we drop the "public" modifier, if we do a new version of the RFC? Cheers Andreas On Tue, 4 Jan 2022 at 00:27, Andreas Hennings wrote: > > Hello Jordan, > > I have another note about the RFC. > (I am not sure what's the policy, if we should continue _all_ > discussion here or go back to the RFC thread. Hope it's ok here.) > > OperandPosition::LeftSide > OperandPosition::RightSide > > I wonder if this is the best way to model this. > Especially, it does not account for the case where an operator only > works in one direction, or the allowed operand type is dependent on > the direction. > E.g., (Money / float) is ok, but (float / Money) probably not supported. > Or if it is supported, then the return type will be quite different. > You can throw an exception, but this is not useful for static analysis. > > An alternative syntax with a few more keywords: > > abstract class Money { > symmetric operator * (float|int $other): Money; // Commutative. > left operator / (float|int $other): Money; // Only $a / $b allowed, > $b / $a not possible. > left operator - (Money $other): Money; // $a - $b > right operator - (Money $other): Money; // $b - $a > } > > Btw, in the Matrix example from the RFC, under "When will $operandPos > be useful?", the $operandPos is not really useful, because it will > always pick the default $a - $b version. > The same applies to "-" operator in my Money example, because $other > already implements the operator. > > The $operandPos is only needed if the left operand does _not_ > implement the operator. Which is the case e.g. for complex numbers, or > the Number class from the RFC example. > > I am trying to think of cases where ($a $b) would have a > different type than ($b $a), but I can't think of any. > Or rather, for any case that I could think of, the mirror operator > could simply be provided by $b. > > I am not married to the modifier names, e.g. it could be "symmetric" > or "commutative" or something else. > For left/right perhaps I prefer to talk about the "default direction" > vs the "flipped direction", not sure how this could be turned into > keywords. > If we don't like more keywords, perhaps something like "!operator" for > the flipped version? > > Cheers > Andreas > > On Mon, 3 Jan 2022 at 01:14, Jordan LeDoux wrote: > > > > Hello internals, > > > > I've opened voting on > > https://wiki.php.net/rfc/user_defined_operator_overloads. The voting will > > close on 2022-01-17. > > > > To review past discussions on this RFC and the feature in general, please > > refer to: > > > > - https://externals.io/message/116611 | Current RFC discussion > > - https://externals.io/message/115764 | Initial RFC discussion > > - https://externals.io/message/115648 | Pre-RFC discussion and fact-finding > > > > Jordan -- 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
Hey Jordan. On 05.01.22 10:42, Jordan LeDoux wrote: On Tue, Jan 4, 2022 at 10:50 PM Pierre Joye wrote: I hesitated too, however I think we can't escape this feature. Like it was for the annotation, we need to find a compromise. Your points are valid so I wonder if the RFC could be modified and get to the point we could reach that compromise. There will be the oppositions for the features as a whole, however I am optimistic about our abilities to get there this time rather than wait yet again a few years for something we know we will have anyway. I will certainly be making changes before bringing this RFC back if it is rejected. What exactly those changes are I am not certain yet, but the feedback I receive here from voters will obviously have a large impact on that. As i mentioned elsewhere, swapping to a magic method syntax would be about 2-3 hours of work, I could do that very quickly. But I don't want to make a change like that after the voting has started, so any such changes will have to wait. 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'd rather not see more magic being introduced. That would for me be a reason to vote against the RFC. No matter what it does. Just my 0.02 € Cheers Andreas -- ,,, (o o) +-ooO-(_)-Ooo-+ | Andreas Heigl | | mailto:andr...@heigl.org N 50°22'59.5" E 08°23'58" | | https://andreas.heigl.org | +-+ | https://hei.gl/appointmentwithandreas | +-+ OpenPGP_0xA8D5437ECE724FE5.asc Description: OpenPGP public key OpenPGP_signature Description: OpenPGP digital signature
Re: [PHP-DEV] [VOTE] User Defined Operator Overloads
On Tue, Jan 4, 2022 at 10:50 PM Pierre Joye wrote: > > I hesitated too, however I think we can't escape this feature. Like it > was for the annotation, we need to find a compromise. > > Your points are valid so I wonder if the RFC could be modified and get > to the point we could reach that compromise. There will be the > oppositions for the features as a whole, however I am optimistic about > our abilities to get there this time rather than wait yet again a few > years for something we know we will have anyway. > I will certainly be making changes before bringing this RFC back if it is rejected. What exactly those changes are I am not certain yet, but the feedback I receive here from voters will obviously have a large impact on that. As i mentioned elsewhere, swapping to a magic method syntax would be about 2-3 hours of work, I could do that very quickly. But I don't want to make a change like that after the voting has started, so any such changes will have to wait. 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. Jordan
Re: [PHP-DEV] [VOTE] User Defined Operator Overloads
On Wed, Jan 5, 2022 at 12:26 AM Aleksander Machniak wrote: > > - what is the performance impact? > Each operator evaluation is very slightly better than the equivalent function call, since the VM call chain is very slightly simpler, but for most purposes you can think of the performance as being the same as a method call. This is quite a bit slower than most operator evaluations (which are lightning fast compared to function calls), however this *only* affects *objects* used with operators, which currently always result in a fatal error. So in that sense, there is no performance impact. > - why "[public] operator" and not "operator function"? > As many people in this thread have pointed out, it's possible for less experienced developers to do something truly devious with this (the same way that they can with __get, __set, or __toString). I wanted to avoid using the function keyword at all, because I wanted the code itself to mentally prepare the programmer to treat these differently than arbitrary functions. As I mentioned in a previous email, some will view this as wishy-washy, but that decision was done after consulting a specialist that I know in the field of Human Centered Design (the field of designing technology so that it is used correctly by design alone). That is, in truth, my largest reason for wanting the operator keyword, but it's also something that I invested nearly two months of study and consultation into. That makes it difficult for me to correctly convey that understanding to other people here via email, so I have mostly restricted my arguments to other things. I find myself in the odd position of not really being able to dump all of the research I did here for everyone else, because frankly, no one on this list *should* need to invest a week of studying to understand an RFC. So unfortunately, my best argument in favor of this is one I can't really make, but that *is* the reason that I went this route. > - what about precedence, i.e. what happens with $a + $b * $c? there's no > clear answer > Precedence is handled by the compiler and how it handles the opcodes. That's independent of any of the changes in this RFC, since the opcodes for all the operators are the same with or without operator overloads. So the precedence will be the same if $a, $b, and $c are ints or objects, even if we later (for some reason) changed the precedence of the operators. > - why not allow the tilde operator to be used in a different context?, > e.g. in PostgreSQL it is used as a regular expression match, e.g. >$a ~ '^[a-z]+$' > This would involve changing the opcode evaluation itself, instead of just implementing a do_operation handler in zend_class_entry. It would introduce much more surface for buggy behavior and be a great deal of additional effort for that single operator. > - the Implied Operators table does not mention ~= operation. > The ~= operator does not exist in PHP because the ~ operator is a unary operator in PHP (bitwise not). See: - https://www.php.net/manual/en/language.operators.assignment.php - https://3v4l.org/N9OYF > - I don't like the Reflection API changes > Please suggest changes then. It seems probable this will not pass in this incarnation, so knowing what things to improve before bringing it back would be helpful. Jordan
Re: [PHP-DEV] [VOTE] User Defined Operator Overloads
On 03.01.2022 01:13, Jordan LeDoux wrote: https://wiki.php.net/rfc/user_defined_operator_overloads. The voting will close on 2022-01-17. - what is the performance impact? - why "[public] operator" and not "operator function"? - what about precedence, i.e. what happens with $a + $b * $c? there's no clear answer - why not allow the tilde operator to be used in a different context?, e.g. in PostgreSQL it is used as a regular expression match, e.g. $a ~ '^[a-z]+$' - the Implied Operators table does not mention ~= operation. - I don't like the Reflection API changes -- Aleksander Machniak Kolab Groupware Developer[https://kolab.org] Roundcube Webmail Developer [https://roundcube.net] PGP: 19359DC1 # Blog: https://kolabian.wordpress.com -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php