Re: [RFC] Operator Overrides -- Lite Edition

From: Date: Sat, 29 Jun 2024 15:21:16 +0000
Subject: Re: [RFC] Operator Overrides -- Lite Edition
References: 1 2  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
On Sat, Jun 29, 2024, at 16:19, Saki Takamachi wrote:
> Hi,
> 
> >> Here are my thoughts on your code.
> >> 
> >> In theory, inheriting from this "improved GMP class" would allow overloading
> >> of computational operators.
> >> 
> >> In effect, this acts like a "calcable interface", with the constructor
> >> passing in meaningless values to the parent constructor and the add method allowing the user to
> >> freely modify the return value.
> >> 
> >> This means that virtually any userland class can use the operator overloading feature
> >> via a "hack".
> > 
> > That is a very valid point, and I feel like it is something I definitely would have
> > thought about since I love abusing features to do things they shouldn't. My hope was that by
> > removing the ability to directly compare, it would reduce the usefulness of "hacking it"
> > into generic overloading since you have to return a GMP instance ... but then, I guess, that GMP
> > instance technically doesn't have to represent a number (though the rest of the engine will
> > very much treat it as a number).
> > 
> > I will think on this some more...
> > 
> > For example, while eating lunch, I was considering whether this even needs to have
> > anything to do with the GMP instance. I was only focusing on the GMP class because right now, it is
> > non-final. Then I started thinking about Jordan's original proposal and how it could be
> > simplified .... there's certainly things to think about.
> > 
> >> This approach is completely wrong.
> > 
> > Ouch, I would hope it would have something useful to it. :)
> > 
> >> 
> >> Rather than proposing this as is, it would be more constructive to propose support for
> >> operator overloading.
> > 
> > That's been tried before, and this was an attempt at the far other extreme,
> > "barely operator overloading". So, there is surely something in the middle. Hopefully.
> > 
> > — Rob
> 
> I would like to state my opinion on this matter, making it clear that I am of the opinion that
> "GMP class should be final."

Yes, the more I consider it, the name of the base class will probably change, though GMP is a good
candidate as a base class for "overridable numbers" for multiple reasons:
 1. near infinite numeric resolution
 2. arbitrarily big numbers (At least I've used it to perform operations on 256bit+ numbers)
 3. pretty fast
This gives a lot of power to whatever number is stored there and isn't limited to float or
integer.

Secondly, numbers are pretty much the only thing you can't override in PHP. There's
ArrayAccess if you want custom array-like things and there is Stringable if you want to control how
your object is concatenated. There's no way to say "this number is a duration and you
multiplying duration times how many cows you have is probably nonsensical." while also still
allowing you to cast to an int/float if you want to do it anyway. Sure, you can write out
$num->times($otherNum), but that isn't scannable or idiomatic to numbers, in general. What
you (or at least I) want to do is write $num * $otherNum, especially because working out the order
of operations is easy.

Before we switched to GMP on a project, working out $num->mul($other->minus($v->pow(2))))
was really hard to follow. With GMP it turned into $num * ($other - ($v ** 2)). Where it got really
hard were things like $num * $other - $v * 3. Looking at this, you already know the order of
operations, you know that $num * other, then $v * 3 comes first. When writing it out, you have to
specifically state the order of operations: $num->mul($other)->sub($v->mul(3))).

It's really easy to mess that up.

> 
> First of all, to meet the requirements that are the basis of this discussion, it is not
> actually necessary to expose the calculation logic; it is enough to simply specify the class of
> result.
> 
> A practical approach to get around this issue is to tell php what class the result should be.
> 
> For example, could prepare a method like resultClass(string $num1Class, string
> $num2Class, string $calcType): string|false, and return the class name of the result based on
> the class names of the two objects to be calculated and the calculation type, such as addition or
> subtraction.
> 
> PHP calls this method as a "hook" when it finishes a calculation and returns the
> result to determine the class of the return value.
> 
> But I don't like this because it's a "hacky" way of doing things with zend.
> Also, I am concerned about the cost of doing this for every calculation.
> 
> The reason I'm putting together what I consider to be a bad method is because it's
> possible that you or someone else will take my idea, add a twist that I haven't thought of, and
> come up with a way to make it all work.

Interesting.

> 
> Regards,
> 
> Saki
> 

— Rob


Thread (27 messages)

« previous php.internals (#124041) next »