On Wed, Jan 5, 2022 at 3:24 PM Andreas Hennings <andr...@dqxtech.net> wrote:
> On Wed, 5 Jan 2022 at 20:11, Jordan LeDoux <jordan.led...@gmail.com> > wrote: > > > > > > > > On Wed, Jan 5, 2022 at 6:33 AM Andreas Hennings <andr...@dqxtech.net> > 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