On Sat, Jun 29, 2024, at 11:01, Rob Landers wrote:
> On Sat, Jun 29, 2024, at 02:13, Jordan LeDoux wrote:
>> 
>> 
>> On Fri, Jun 28, 2024 at 12:55 PM Rob Landers <rob@bottled.codes> wrote:
>>> __
>>> 
>>> 
>>>> 3. The private/protected distinction is fairly meaningless for the 
>>>> functions that implement overloads, because the privacy of the function is 
>>>> ignored completely when it is executed to evaluate an operator.
>>> 
>>> Hmm. I like the idea of protected, because it gives a structure to it that 
>>> is apparent and usable right from the IDE. You just “fill in the blanks” or 
>>> stick with the default behavior. 
>> 
>> I do not understand how the visibility has any impact on the usability you 
>> are seeking to provide.
> 
> I guess it depends on what you mean by usability. From a technical 
> standpoint, it has zero usability, but from a dev-ex standpoint, it has a 
> huge amount of usability.
> 
> If we add these as protected methods to the base class, I merely need to 
> write "protected static function<tab>" in my IDE and I will see all the 
> methods I can write. It also lays bare "how it works" for a PHP developer 
> without any magic, making it easier to document.
> 
>> 
>>>> 4. The `static` distinction is also fairly meaningless, as in PHP there is 
>>>> no situation possible where an operator overload can occur WITHOUT it 
>>>> operating on objects themselves.
>>> 
>>> For this, that is the wrong approach. The actual behavior is on the type, 
>>> not the instance. The object instances may not even know their value, they 
>>> merely represent the value.
>> 
>> A GMP object instance that does not know its value? What are you even 
>> talking about? Can you show me some code explaining what you mean? I had 
>> literally months of this argument for the operator overloads RFC, and 
>> studied the overload implementations in six other languages as part of 
>> writing that RFC, I feel like I understand this topic fairly well. But I do 
>> not understand what you are saying here.
> 
> Heh, yeah, it's kinda weird. Let me explain. The GMP class hides its value in 
> a "private" member (because the value isn't actually a number, but a GMP 
> resource), so unless the programmer also sets the value to something they 
> have access to, they won't know the value (but they can always cast $this to 
> a number or operate on it directly). The only way they could get the value is 
> to cast $this to float, which may lose some precision. The idea here is to 
> "write the rules" where the value doesn't matter, or if it does, embed that 
> as part of the rules.
> 
> For example, imagine we want to create a Field class, that takes a range for 
> the field and keeps the value in the field. It might look something like this:

sigh: not enough coffee again and I saw the blunder as soon as I sent it. 
Here's the more correct implementation.

class IntField {
  public function __construct(private int $max, int $value) {
    parent::construct($value, 10);
  }
  protected static function add($left, $right): self {
    // todo: guard that left can be added to right -- ie, both are integers
    $result = parent::add($left, $right);
    if ($result >= $left->max) return new IntField($left->max, $result % 
$left->max);
    return new IntField($left->max, $result);
  }
  // todo: remaining implementation
}
 
> I actually had a bit of a long-thought about it, and I think this is simpler 
> (both to implement and to use) than the traditional approach, and more 
> powerful. With the more traditional approach, how do define communitive 
> rules? You are bound by traditional mathematics, more-or-less. From working 
> in cryptography, a long time ago now, I can say that there are 
> non-communitive rings where having access to both "left" and "right" can 
> allow you to handle this quite well.
> 
>>  
>>> 
>>>> 6. The `comparable` function you propose doesn't actually have an operator 
>>>> it corresponds to. There is no operator in PHP for "is the left value 
>>>> comparable with the right value". There are operators for comparisons 
>>>> themselves, which I assume you meant, but a bool is insufficient as a 
>>>> return type for that.
>>> 
>>> In the engine, there’s just a compare function for internal overrides. So 
>>> we just check that everyone agrees that the two objects are comparable and 
>>> then pass it on to “business as usual.”
>> 
>>  I'm aware of how the compare handler for class entries and zend_compare 
>> interact. What I am saying is that your design is insufficient for <=>. You 
>> cannot return `false` from this method to mean uncomparable, and `true` to 
>> mean comparable. The zend_compare function can validly return 0 or -1, with 
>> the -1 being used for both less than OR greater than because the operands 
>> are reordered to always be a less than comparison. Then 1, which normally is 
>> used for greater than, is used to mean uncomparable.
> 
> Ah, I mean that it calls this as a guard, before ever doing a comparison, not 
> that this output will be used for comparison itself. This is deliberate, to 
> keep it simple. If I get feedback that comparison should be implemented vs. a 
> guard for comparison, I'd be happy to add it.
> 
>> As you are proposing this without any genuine expectation you can pass it, 
>> this will be the last energy I will invest into helping.
> 
> I didn't mean it how I think you are taking it. To expand a bit on what I 
> meant, "we" (as in people who want this feature, like myself) can only create 
> RFCs for it. Maybe one day, the voters will change their mind, "we" will find 
> an implementation they agree with, or they'll forget to vote "no" while 
> enough people vote "yes." So, yes, I genuinely want this feature and I want 
> to propose a feature that works and is the best I can come up with; at the 
> same time, I don't expect it to pass, but I do hope that negative feedback 
> will drive the feature to a compromise or solution that works. The only way 
> to get there is by failing.
> 
> — Rob

— Rob

Reply via email to