Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:124041 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 84F5E1A009C for <internals@lists.php.net>; Sat, 29 Jun 2024 15:21:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1719674582; bh=KfArFvCSr/igDj40pCIIY/bMgWjrbpsy5yPjq+yvpoI=; h=In-Reply-To:References:Date:From:To:Cc:Subject:From; b=d0nctLXEAJ7xDXMd5WaAviCbnHK4BotuZJAY7sKY7j/avwpYnYRdgBURgctkBvyhk hM98mBJbtnWdcssP0vmkM/gGmOtia4kilsJT8stkBV7p48TTso5nQpGiPkLPymfnJy 5WvWpq5bf/G5HleFnhrji6jzASDzLR4kmKiV0FKVVuWWfHVpw2MD2NKjEIVhf4iNJx sxbh7Nev6E9o3a/JgcJE2zokdO+fqpCCQ8PLpSblVaHCeEaqxkIi7dZk5E8B266bhR oEmBMpwvehlQKo9/3WPCJMqAgtayFeUQkpA2vbuKHD57y3vZpVfWqADvEr/jitNA0L VBj/87gHRhf5w== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id E30BC1813EA for <internals@lists.php.net>; Sat, 29 Jun 2024 15:22:58 +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,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: <rob@bottled.codes> Received: from fout6-smtp.messagingengine.com (fout6-smtp.messagingengine.com [103.168.172.149]) (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 <internals@lists.php.net>; Sat, 29 Jun 2024 15:22:56 +0000 (UTC) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailfout.nyi.internal (Postfix) with ESMTP id BAF6B13801A1; Sat, 29 Jun 2024 11:21:36 -0400 (EDT) Received: from imap49 ([10.202.2.99]) by compute1.internal (MEProxy); Sat, 29 Jun 2024 11:21:36 -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=1719674496; x= 1719760896; bh=KfArFvCSr/igDj40pCIIY/bMgWjrbpsy5yPjq+yvpoI=; b=P AJQq2cA65b+SxZlxtlaOZ2bxS/CIc6orUiXEtSZzEH/5YE7fZFDp/KN3jOuXRvEl RaCdrb7oRmMavvPXKr2RFfCaZ3ycGTRJ7q7YE02IpNBbAdA1JInE37hPxO/Drd4c 9xGlJKb6zSzIJBtcz+pWFGnFZnpuGXiG3N2HUUxLJWMJ38iRSCichuztMjDVU0jJ FYGCcdfBLAzuax5QlgmSgy/D1qjF9Ot4S1a2N96Ec/KymgHF8LenF4DliHFPFgTL 9cLiz+dSUWcyd1bIJie2QmF04R7KUHkqtIkbWCRe95nlQ9GI/Pm7u4xZfjo4P0YI tXo0bPaxpDF+yd9IvAuCA== 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=1719674496; x=1719760896; bh=KfArFvCSr/igDj40pCIIY/bMgWjr bpsy5yPjq+yvpoI=; b=uP4aRSU6uNVbPK7+4hh/FCpyL1j1D5bS9EmBdDA1m3ec sJ6+IkEbshgprewUlfD9QoQ0vMLO0+6s9gpydrYld2OtQSU+35SbBZsg3mvT3fLw Np6NrvsVO7AVIEtp76HQKD7WYzWUAE0DoWpYkwGoeeHzdZ7nMRJ8XnoHxXewi53c WmfWupMffaRizzS9fUFl9Fp8N4X2tgRT2khlQ9D4xcJVthHTs/x5J77vB95Yqf2q mGXXs4NZ+YZLBtlYO9pZ+QUxNUprToTxD0aAsJzCzmEBn/Vz6+Sfx3jGx8ERMLa4 H9SnySAdv3s2+rhsuqTswwRnu1NjwE/yMcHOe6h5Lw== X-ME-Sender: <xms:gCaAZnCn_P4MF4oUsRUFI6ELBYFkB1rWz_X-K37Hhv067c6cIsfBGg> <xme:gCaAZtgGOFO9DMDqHdNVVfdxXvX6wQcROjGyxgfr5MeDtzYbIlFC0Hv3VqU9x_w6N sFhMXceLvYevTWkJ_k> X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeftddrtdelgdekkecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefofgggkfgjfhffhffvvefutgesrgdtreerreerjeenucfhrhhomhepfdftohgs ucfnrghnuggvrhhsfdcuoehrohgssegsohhtthhlvggurdgtohguvghsqeenucggtffrrg htthgvrhhnpedvheekteelveetfeevgeekgfffvdeuhfelveehvdetiefggedtfeejheet gffhueenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpe hrohgssegsohhtthhlvggurdgtohguvghs X-ME-Proxy: <xmx:gCaAZilSgVufSOqhALN_KZh-QqQr8m0qlGF_Qefo3RgPPgrhvw_x_g> <xmx:gCaAZpw9kLZZ9XzQrWiOlAh2Aedb8HL8qJpGwtHBaZ7PTetK4StLsA> <xmx:gCaAZsQn2KJwx-qCWEVIYfxeXDCqdHgXb1PMP50QHNsLruVWDR5d7g> <xmx:gCaAZsaiWat8t4LPixOSfGzRhVz-VG_3LyaNqDaRQZM1Ey6gYo358w> <xmx:gCaAZnfprnY9fb-pHN5Lwlrz0txSBFd02iF0M5HcPXxJI5XhRbNtONz6> Feedback-ID: ifab94697:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id 7182515A0092; Sat, 29 Jun 2024 11:21:36 -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: <mailto:internals+help@lists.php.net list-unsubscribe: <mailto:internals+unsubscribe@lists.php.net> list-post: <mailto:internals@lists.php.net> List-Id: internals.lists.php.net MIME-Version: 1.0 Message-ID: <535cbdef-a6a1-4ca6-9cc6-0839bb2e833b@app.fastmail.com> In-Reply-To: <DD3C5488-4C11-4393-A45D-60F8C49B4DA0@sakiot.com> References: <90ab0ec1-33ad-4342-ad4b-6448ee89bfa7@app.fastmail.com> <DD3C5488-4C11-4393-A45D-60F8C49B4DA0@sakiot.com> Date: Sat, 29 Jun 2024 17:21:16 +0200 To: "Saki Takamachi" <saki@sakiot.com> Cc: "Jordan LeDoux" <jordan.ledoux@gmail.com>, internals@lists.php.net Subject: Re: [PHP-DEV] [RFC] Operator Overrides -- Lite Edition Content-Type: multipart/alternative; boundary=284552c1df484ef38e73143ee302239d From: rob@bottled.codes ("Rob Landers") --284552c1df484ef38e73143ee302239d Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable On Sat, Jun 29, 2024, at 16:19, Saki Takamachi wrote: > Hi, >=20 > >> Here are my thoughts on your code. > >>=20 > >> In theory, inheriting from this "improved GMP class" would allow ov= erloading of computational operators. > >>=20 > >> In effect, this acts like a "calcable interface", with the construc= tor passing in meaningless values to the parent constructor and the add = method allowing the user to freely modify the return value. > >>=20 > >> This means that virtually any userland class can use the operator o= verloading feature via a "hack". > >=20 > > That is a very valid point, and I feel like it is something I defini= tely 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 co= mpare, it would reduce the usefulness of "hacking it" into generic overl= oading since you have to return a GMP instance ... but then, I guess, th= at GMP instance technically doesn't have to represent a number (though t= he rest of the engine will very much treat it as a number). > >=20 > > I will think on this some more... > >=20 > > 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 thi= nking about Jordan's original proposal and how it could be simplified ..= . there's certainly things to think about. > >=20 > >> This approach is completely wrong. > >=20 > > Ouch, I would hope it would have something useful to it. :) > >=20 > >>=20 > >> Rather than proposing this as is, it would be more constructive to = propose support for operator overloading. > >=20 > > That's been tried before, and this was an attempt at the far other e= xtreme, "barely operator overloading". So, there is surely something in = the middle. Hopefully. > >=20 > > =E2=80=94 Rob >=20 > 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 ch= ange, though GMP is a good candidate as a base class for "overridable nu= mbers" 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 l= imited to float or integer. Secondly, numbers are pretty much the only thing you can't override in P= HP. There's ArrayAccess if you want custom array-like things and there i= s Stringable if you want to control how your object is concatenated. The= re's no way to say "this number is a duration and you multiplying durati= on times how many cows you have is probably nonsensical." while also sti= ll allowing you to cast to an int/float if you want to do it anyway. Sur= e, 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 i= s write $num * $otherNum, especially because working out the order of op= erations is easy. Before we switched to GMP on a project, working out $num->mul($other->mi= nus($v->pow(2)))) was really hard to follow. With GMP it turned into $nu= m * ($other - ($v ** 2)). Where it got really hard were things like $num= * $other - $v * 3. Looking at this, you already know the order of opera= tions, you know that $num * other, then $v * 3 comes first. When writing= it out, you have to specifically state the order of operations: $num->m= ul($other)->sub($v->mul(3))). It's really easy to mess that up. >=20 > First of all, to meet the requirements that are the basis of this disc= ussion, it is not actually necessary to expose the calculation logic; it= is enough to simply specify the class of result. >=20 > A practical approach to get around this issue is to tell php what clas= s the result should be. >=20 > For example, could prepare a method like `resultClass(string $num1Clas= s, string $num2Class, string $calcType): string|false`, and return the c= lass name of the result based on the class names of the two objects to b= e calculated and the calculation type, such as addition or subtraction. >=20 > PHP calls this method as a "hook" when it finishes a calculation and r= eturns the result to determine the class of the return value. >=20 > 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 calcul= ation. >=20 > 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 w= ork. Interesting. >=20 > Regards, >=20 > Saki >=20 =E2=80=94 Rob --284552c1df484ef38e73143ee302239d Content-Type: text/html;charset=utf-8 Content-Transfer-Encoding: quoted-printable <!DOCTYPE html><html><head><title></title><style type=3D"text/css">p.Mso= Normal,p.MsoNoSpacing{margin:0} p.MsoNormal,p.MsoNoSpacing{margin:0}</style></head><body><div>On Sat, Ju= n 29, 2024, at 16:19, Saki Takamachi wrote:<br></div><blockquote type=3D= "cite" id=3D"qt" style=3D""><div>Hi,<br></div><div><br></div><div>>&g= t; Here are my thoughts on your code.<br></div><div>>> <br></= div><div>>> In theory, inheriting from this "improved GMP class" w= ould allow overloading of computational operators.<br></div><div>>>= ; <br></div><div>>> In effect, this acts like a "calcable int= erface", with the constructor passing in meaningless values to the paren= t constructor and the add method allowing the user to freely modify the = return value.<br></div><div>>> <br></div><div>>> This m= eans that virtually any userland class can use the operator overloading = feature via a "hack".<br></div><div>> <br></div><div>> That i= s 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 shou= ldn't. My hope was that by removing the ability to directly compare, it = would reduce the usefulness of "hacking it" into generic overloading sin= ce you have to return a GMP instance ... but then, I guess, that GMP ins= tance technically doesn't have to represent a number (though the rest of= the engine will very much treat it as a number).<br></div><div>>&nbs= p;<br></div><div>> I will think on this some more...<br></div><div>&g= t; <br></div><div>> For example, while eating lunch, I was consi= dering whether this even needs to have anything to do with the GMP insta= nce. I was only focusing on the GMP class because right now, it is non-f= inal. Then I started thinking about Jordan's original proposal and how i= t could be simplified ... there's certainly things to think about.<br></= div><div>> <br></div><div>>> This approach is completely w= rong.<br></div><div>> <br></div><div>> Ouch, I would hope it = would have something useful to it. :)<br></div><div>> <br></div>= <div>>> <br></div><div>>> Rather than proposing this as= is, it would be more constructive to propose support for operator overl= oading.<br></div><div>> <br></div><div>> That's been tried be= fore, and this was an attempt at the far other extreme, "barely operator= overloading". So, there is surely something in the middle. Hopefully.<b= r></div><div>> <br></div><div>> =E2=80=94 Rob<br></div><div><= br></div><div>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."<br></d= iv></blockquote><div><br></div><div>Yes, the more I consider it, the nam= e of the base class will probably change, though GMP is a good candidate= as a base class for "overridable numbers" for multiple reasons:<br></di= v><ol><li>near infinite numeric resolution<br></li><li>arbitrarily big n= umbers (At least I've used it to perform operations on 256bit+ numbers)<= br></li><li>pretty fast<br></li></ol><div>This gives a lot of power to w= hatever number is stored there and isn't limited to float or integer.<br= ></div><div><br></div><div>Secondly, numbers are pretty much the only th= ing you can't override in PHP. There's ArrayAccess if you want custom ar= ray-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 n= onsensical." while also still allowing you to cast to an int/float if yo= u 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 yo= u (or at least I) want to do is write $num * $otherNum, especially becau= se working out the order of operations is easy.<br></div><div><br></div>= <div>Before we switched to GMP on a project, working out $num->mul($o= ther->minus($v->pow(2)))) was really hard to follow. With GMP it t= urned into $num * ($other - ($v ** 2)). Where it got really hard were th= ings 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 opera= tions: $num->mul($other)->sub($v->mul(3))).<br></div><div><br><= /div><div>It's really easy to mess that up.</div><div><br></div><blockqu= ote type=3D"cite" id=3D"qt" style=3D""><div><br></div><div>First of all,= to meet the requirements that are the basis of this discussion, it is n= ot actually necessary to expose the calculation logic; it is enough to s= imply specify the class of result.<br></div><div><br></div><div>A practi= cal approach to get around this issue is to tell php what class the resu= lt should be.<br></div><div><br></div><div>For example, could prepare a = method like `resultClass(string $num1Class, string $num2Class, string $c= alcType): string|false`, and return the class name of the result based o= n the class names of the two objects to be calculated and the calculatio= n type, such as addition or subtraction.<br></div><div><br></div><div>PH= P calls this method as a "hook" when it finishes a calculation and retur= ns the result to determine the class of the return value.<br></div><div>= <br></div><div>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.<br></div><div><br></div><div>The reason I'm putting = together what I consider to be a bad method is because it's possible tha= t you or someone else will take my idea, add a twist that I haven't thou= ght of, and come up with a way to make it all work.<br></div></blockquot= e><div><br></div><div>Interesting.</div><div><br></div><blockquote type=3D= "cite" id=3D"qt" style=3D""><div><br></div><div>Regards,<br></div><div><= br></div><div>Saki<br></div><div><br></div></blockquote><div><br></div><= div id=3D"sig121229152">=E2=80=94 Rob<br></div></body></html> --284552c1df484ef38e73143ee302239d--