Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:124014 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id BFC171A009C for ; Sat, 29 Jun 2024 09:01:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1719651784; bh=U6AHZ26Ttn7JMtTExOl/Xxx9qa/TXfnI0zLcUAHyoSw=; h=In-Reply-To:References:Date:From:To:Cc:Subject:From; b=ASGieF7Hv4ZP5r9aQ8JiwtoKPOW1rSOETKUYWs8qKEjNX2X6SnCO1c2T/t8i51tD7 Q5FXFBxqhW6l1qppslVFtAjZ5QlgPWY8C5BpyFP4YqQHCWTHciFhipgDgRFp8mcMdU 2bFYpJirlvgbDs9UHx6kAPs4pypC1UDO3zzGyhfFZmaGX73iNsH2HlbTvaOIwPSjH0 F9bMZEVfcrnlD+FJmrZFCdSzo5KIQ4YFrqRI5mNxb/fM2sZCxLVb96p4/SW4E3B98x gloGo82z/qhnbdzxb/WL27ejCUrFB4ltXJVwo1hY+1waZ6dHwwW4mSrCxUOf8Zh7nR urY/BjSm5mgng== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 998BA1805DD for ; Sat, 29 Jun 2024 09:03:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from fout2-smtp.messagingengine.com (fout2-smtp.messagingengine.com [103.168.172.145]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sat, 29 Jun 2024 09:03:02 +0000 (UTC) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailfout.nyi.internal (Postfix) with ESMTP id 5D43513804D5; Sat, 29 Jun 2024 05:01:43 -0400 (EDT) Received: from imap49 ([10.202.2.99]) by compute1.internal (MEProxy); Sat, 29 Jun 2024 05:01:43 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bottled.codes; h=cc:cc:content-type:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm3; t=1719651703; x= 1719738103; bh=je0LaOCEFe2XPpDD3pBMOjO5GnNN4YamfnerlGdEk/w=; b=N GMBwZg6HckDGYAJ//e4NYDYjSfQuYRfOupT3oAgS8jLVRe3YEyoNSntCIHRNeG9J DYFO4haL9Xu9xiZLVh4u8uhTctsDV8dwv6AZTYNuUl3OVQtFgXxClaPjv4argGkx krAzB+Bqi97kjZ/+mAnMamjZ3TcikteRn5RE+x2afTaWk2qcGPPlQD6FpYFya4ec +at/mvs4UlCVRB80GahcsvaeXjsxRzARucW28KeeU5BWQgttTT4VniFJzuVmWG7H f/W3qtzdM3ZvTTtuYw49LM2Lt8fABJxSrUjIRQz6vu0OFUSR4AjmTW4vhHIO2nG1 CQ2zUjHGtMkgULtLbX22w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; t=1719651703; x=1719738103; bh=je0LaOCEFe2XPpDD3pBMOjO5GnNN 4YamfnerlGdEk/w=; b=DtxbpIdXnq1v1CjiLuGdYNa8rCjl1yZ4jRop15cYO+gw 5BM3j2zaUo3Uu6q7W/4U8rlBJtSvYOxZ2AdWAUz8AT34z9nKQCW/sKGrI+VKNBR1 X7vsL61drPJHs9mOu7OZgyKm3mDgcCGnxMblA7UMelmQfCjI2JWdqC6XnWeqOwM6 Gb1mi26g6NuSkTyHc8RQ0wRbbGdevPPsVpzyhNgmC8aZz2DgLBX1etOfWG0CqUVR fyh7wAGIab8G1E3bBkwLRG01/qcltHmI0cQ4yEXGRsi2saCLJZm7KyhS8DKhJAPt a/Db8z4xn0yWu6zAQdQ+IO6Ng+oSFHnXWYa35Y09Ww== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeftddrtdelgddutdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefofgggkfgjfhffhffvvefutgesrgdtreerreerjeenucfhrhhomhepfdftohgs ucfnrghnuggvrhhsfdcuoehrohgssegsohhtthhlvggurdgtohguvghsqeenucggtffrrg htthgvrhhnpedvheekteelveetfeevgeekgfffvdeuhfelveehvdetiefggedtfeejheet gffhueenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpe hrohgssegsohhtthhlvggurdgtohguvghs X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id ED2A615A0092; Sat, 29 Jun 2024 05:01:42 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.11.0-alpha0-538-g1508afaa2-fm-20240616.001-g1508afaa Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 Message-ID: <33b14c2e-cf81-45c2-ae82-da40719827c6@app.fastmail.com> In-Reply-To: References: <8dc5393e-b552-465a-9237-9251e8bf1001@app.fastmail.com> Date: Sat, 29 Jun 2024 11:01:21 +0200 To: "Jordan LeDoux" Cc: internals@lists.php.net Subject: Re: [PHP-DEV] [RFC] Operator Overrides -- Lite Edition Content-Type: multipart/alternative; boundary=0ed486ab741449c6b863372ee8ed29d5 From: rob@bottled.codes ("Rob Landers") --0ed486ab741449c6b863372ee8ed29d5 Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable On Sat, Jun 29, 2024, at 02:13, Jordan LeDoux wrote: >=20 >=20 > On Fri, Jun 28, 2024 at 12:55=E2=80=AFPM Rob Landers wrote: >> __ >>=20 >>=20 >>> 3. The private/protected distinction is fairly meaningless for the f= unctions that implement overloads, because the privacy of the function i= s ignored completely when it is executed to evaluate an operator. >>=20 >> 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 =E2=80=9Cfill = in the blanks=E2=80=9D or stick with the default behavior.=20 >=20 > 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 stand= point, it has zero usability, but from a dev-ex standpoint, it has a hug= e amount of usability. If we add these as protected methods to the base class, I merely need to= write "protected static function" in my IDE and I will see all the= methods I can write. It also lays bare "how it works" for a PHP develop= er without any magic, making it easier to document. >=20 >>> 4. The `static` distinction is also fairly meaningless, as in PHP th= ere is no situation possible where an operator overload can occur WITHOU= T it operating on objects themselves. >>=20 >> For this, that is the wrong approach. The actual behavior is on the t= ype, not the instance. The object instances may not even know their valu= e, they merely represent the value. >=20 > 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 s= tudied the overload implementations in six other languages as part of wr= iting that RFC, I feel like I understand this topic fairly well. But I d= o not understand what you are saying here. Heh, yeah, it's kinda weird. Let me explain. The GMP class hides its val= ue 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 someth= ing 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 cou= ld get the value is to cast $this to float, which may lose some precisio= n. 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: class IntField { public function __construct(private int $max, int $value) { parent::construct($value, 10); } public function add($left, $right): self { // todo: guard that left can be added to right -- ie, both are integ= ers $result =3D parent::add($left, $right); if ($result >=3D $this->max) return new IntField($this->max, $result= % $this->max); return new IntField($this->max, $result); } // todo: remaining implementation }=20 I actually had a bit of a long-thought about it, and I think this is sim= pler (both to implement and to use) than the traditional approach, and m= ore powerful. With the more traditional approach, how do define communit= ive 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 n= on-communitive rings where having access to both "left" and "right" can = allow you to handle this quite well. > =20 >>=20 >>> 6. The `comparable` function you propose doesn't actually have an op= erator it corresponds to. There is no operator in PHP for "is the left v= alue comparable with the right value". There are operators for compariso= ns themselves, which I assume you meant, but a bool is insufficient as a= return type for that. >>=20 >> In the engine, there=E2=80=99s just a compare function for internal o= verrides. So we just check that everyone agrees that the two objects are= comparable and then pass it on to =E2=80=9Cbusiness as usual.=E2=80=9D >=20 > I'm aware of how the compare handler for class entries and zend_compa= re interact. What I am saying is that your design is insufficient for <=3D= >. 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 becau= se 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 delib= erate, to keep it simple. If I get feedback that comparison should be im= plemented 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 vo= te "no" while enough people vote "yes." So, yes, I genuinely want this f= eature 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 soluti= on that works. The only way to get there is by failing. =E2=80=94 Rob --0ed486ab741449c6b863372ee8ed29d5 Content-Type: text/html;charset=utf-8 Content-Transfer-Encoding: quoted-printable
On Sat, Jun 29,= 2024, at 02:13, Jordan LeDoux wrote:

<= br>
On Fri, Jun 28, 2024 at 12:55=E2=80=AFPM Rob Landers <rob@bot= tled.codes> wrote:
=



= 3. The private/protected distinction is fairly meaningless for the funct= ions that implement overloads, because the privacy of the function is ig= nored completely when it is executed to evaluate an operator.
<= /div>

Hmm. I like the idea of prot= ected, because it gives a structure to it that is apparent and usable ri= ght from the IDE. You just =E2=80=9Cfill in the blanks=E2=80=9D 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 usabilit= y. 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 ne= ed 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 o= perator overload can occur WITHOUT it operating on objects themselves.

For this, that is t= he wrong approach. The actual behavior is on the type, not the instance.= The object instances may not even know their value, they merely represe= nt the value.

A GM= P object instance that does not know its value? What are you even talkin= g about? Can you show me some code explaining what you mean? I had liter= ally 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.
<= div>
Heh, yeah, it's kinda weird. Let me explain. The GMP = class hides its value in a "private" member (because the value isn't act= ually 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 (b= ut they can always cast $this to a number or operate on it directly). Th= e 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 va= lue doesn't matter, or if it does, embed that as part of the rules.
<= /div>

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:

class = IntField {
  public function __construct(private int = $max, int $value) {
    parent::construct($value= , 10);
  }
  public function add($= left, $right): self {
    // todo: guard that le= ft can be added to right -- ie, both are integers
  &= nbsp; $result =3D parent::add($left, $right);
   = ; if ($result >=3D $this->max) return new IntField($this->max, = $result % $this->max);
    return new IntFiel= d($this->max, $result);
  }
  // to= do: remaining implementation


<= div>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, a= nd more powerful. With the more traditional approach, how do define comm= unitive rules? You are bound by traditional mathematics, more-or-less. F= rom working in cryptography, a long time ago now, I can say that there a= re 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 n= o operator in PHP for "is the left value comparable with the right value= ". There are operators for comparisons themselves, which I assume you me= ant, but a bool is insufficient as a return type for that.

In the engine, there=E2=80=99s = just a compare function for internal overrides. So we just check that ev= eryone agrees that the two objects are comparable and then pass it on to= =E2=80=9Cbusiness as usual.=E2=80=9D
=

 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 <=3D>. You cannot return `false` from this me= thod to mean uncomparable, and `true` to mean comparable. The zend_compa= re 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 b= e a less than comparison. Then 1, which normally is used for greater tha= n, is used to mean uncomparable.
=
Ah, I mean that it calls this as a guard, before ever doi= ng a comparison, not that this output will be used for comparison itself= . This is deliberate, to keep it simple. If I get feedback that comparis= on 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 wil= l change their mind, "we" will find an implementation they agree with, o= r 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 fai= ling.

=E2=80=94 Rob
=
--0ed486ab741449c6b863372ee8ed29d5--