Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:115663 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 24492 invoked from network); 8 Aug 2021 07:11:13 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 8 Aug 2021 07:11:13 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 177741804DB for ; Sun, 8 Aug 2021 00:41:06 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS,URIBL_SBL, URIBL_SBL_A autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-lf1-f50.google.com (mail-lf1-f50.google.com [209.85.167.50]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sun, 8 Aug 2021 00:41:05 -0700 (PDT) Received: by mail-lf1-f50.google.com with SMTP id w20so697021lfu.7 for ; Sun, 08 Aug 2021 00:41:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=zZoBSWWBD9xitzYSfQ6QrW0C3xEaz5uA1af58AMMFis=; b=ZHgcpCK6SK51BRJEr42UGgkH2gK308VEtwtbEYvVO1klPvM16DCpyARN2eBh2BaTWr 83W5dyDwRRdM8BYEJ9fLqVa0djjbKip7A5on4HQy5T6t3RIxSTMaBJoHRl15t03/ILkk qKMr4rxmPxjraUSoNIdD8cgA6c9PSEw8wOm6P6WIWOxw2riyB24swTSxbvFhC+X1n2rT bT+ZbLR4q5nkVwc3/mZdi0xz/MkCsv8P7gHmdK4qZ9Kr/+XHfb1pBQbACdukDEKRdkl7 g+sELgDI4XXbC6mqvUaHPjcaHUhyDTiNiqR0ctDrd/3bCaOiyPKv0XcC3ByTM9z1hXJ1 e8wQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=zZoBSWWBD9xitzYSfQ6QrW0C3xEaz5uA1af58AMMFis=; b=F1HaXH19LAeMgkKOwDLHqDLY5t534hF1zenowrrnIZwyPD6Ul4JE5SmsX/9aDUma0e /LD+8/fL91POBRo6GOXAkdFo/waLN11rygJRHMAFoBEll/M+aWClXndqLImfgPXIRSWx jIuJsTKVBqFBppypHxnfFVVrEfCNfwO4qE26vJ7M1TIWXVGNHIWqZQ+1I8o8rZSoGd/N c86TPbEptDYIjW6LJSiwvJ+5Ijv6eBFfBrmrgNkgONQ5O3CrdtWTtTjETrO+2Pi8SzJu XbykRQN+tqOsRvw4i8Kaceu1J2/cOVRwa+Q2Wwl8tj5Na985prcKbWmnrpUb+bZAXqIm FJFQ== X-Gm-Message-State: AOAM53019vkf46DB10G88Nk4lIZ2DCRMf0f4mHp0nMdlgOssEYY1jEY0 CC8jkmJYaIQQkHV2ncHiD9Hwdajm1g8vkC2xypI= X-Google-Smtp-Source: ABdhPJwgNqy/LfJ2sPsr3S9VNseivxSounD0TZzk6KP9IKD6KMiRNbw4bNL/a9EdHR4GWXs2v2eKjsdbmdmf4gRfD08= X-Received: by 2002:a19:5016:: with SMTP id e22mr13240909lfb.241.1628408463762; Sun, 08 Aug 2021 00:41:03 -0700 (PDT) MIME-Version: 1.0 References: <94696d46-c4e6-406a-b859-89144bff31bf@www.fastmail.com> In-Reply-To: Date: Sun, 8 Aug 2021 00:41:05 -0700 Message-ID: To: Mike Schinkel Cc: php internals , Scott Arciszewski , Larry Garfield , Dan Ackroyd Content-Type: multipart/alternative; boundary="00000000000008289f05c90764f0" Subject: Re: [PHP-DEV] Revisiting Userland Operator Overloads From: jordan.ledoux@gmail.com (Jordan LeDoux) --00000000000008289f05c90764f0 Content-Type: text/plain; charset="UTF-8" On Sat, Aug 7, 2021 at 8:20 PM Mike Schinkel wrote: > > On Aug 7, 2021, at 10:28 AM, Larry Garfield > wrote: > I strongly echo Larry's concern here. > > While I tend to be one who wants more language features, not less, the > availability of unconstrained operator overloading can beckon an > inexperienced and/or undisciplined developer to add operators for many of > the classes they implement, whether or not doing is actually applicable or > a good idea. > > I am even concerned about constrained operator overloading for the same > reason. Here [1][2] are a couple essays to argue against operator > overloading. > > Ruby has operator overloading, and one of the distasteful aspects I found > regarding in programming in Ruby was that everybody's Ruby code you looked > at felt like I was written in a slightly different language. I would hate > that to become the case with PHP, more than it already is. > > I am actually surprised that the last operator overload RFC came close to > passing because adding it seems like it would open a Pandora's box and yet > other proposals that are less Pandoric seem to be anathema on this list. > > That said, I am not unsympathetic to the fact that operator overloading > may well have some extremely valid use-cases, just ones that I do not > personally seem to need on a day-to-day basis when writing code. > > Operator overloading seems to me to be of more value to those who are > essentially wanting to write DSLs (domain-specific languages.) If that is > indeed the case, and there are some DSL like features I wish we could add > to PHP that would generally be non-starters for non-DSL usage. > > I wonder if there is a way to limit to only DSL use-cases? I doubt there > is, but I had to pose the question in case someone else can envision a way > to do so. > > So my main questions are: > > 1.) What are use-cases where operator overloading would really be > valuable? > > 2.) Would it possible that instead of adding operator overloading we could > add classes that could be extended where PHP actually defines the operators > for those classes? > > If we can do #2 we can really work through all the issues with > commutativity, associativity, etc. and also implement all and only the > operators that make sense for the use-case. > > > -Mike > > [1] > https://cafe.elharo.com/programming/operator-overloading-considered-harmful/ > [2] > https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/ > [3] https://externals.io/message/115554#115603 > [4] https://english.stackexchange.com/a/170247/1164 > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > > Hey Mike, Off the top of my head here are some of the use cases that I think benefit greatly from this: - Complex number objects - Fractions objects - Matrix objects (math) - Vector objects (math) - Time/Date intervals - Collections - Arbitrary precision numbers (which are usually represented as a string in PHP) Here are some actual user libraries which would probably use them: - samsara/fermat (this library is mine as a matter of disclosure) - brick/math - markbaker/complex - markbaker/matrix - krowinski/bcmath-extended - malenki/math - markrogoyski/math-php - rubix/tensor - numphp/numphp - mcordingley/linearalgebra The objects which represent a mathematical object that *cannot* be cast to either an integer or a float without losing their meaning are the ones that stand to gain the most. If you have an arbitrary precision number that will overflow both ints and floats, then even providing a method to cast them first doesn't help (that is, adding a __toInt() and toFloat() method would not help). Matrices and vectors cannot be converted to a meaningful scalar in any way that would allow the use of operators. Complex numbers *not only* can't be converted to an int or float, but as I've said in a few places, the correct behavior for the >, <, >=, and <= operators would be to throw an exception as these types of comparison are mathematically undefined for ZFC set theory. As for constraints... well, if I had absolutely no concern for implementation at all, and was just designing what constraints to put on the magic methods, they would be: 1. void is an unsupported return, and failing to return a value results in an error. 2. Variables outside the scope of the method cannot be set. This includes properties on the object which is defining the magic method, and includes sets that occur in called functions and methods. I think that the second restriction there would be quite difficult to accomplish in an implementation. Perhaps it could be done by creating a readonly temporary copy of the objects in question and then executing the magic method on that. In any case, it is certainly possible that we could instead implement some magic *objects* which can be extended that have built-in overloading in specific ways. I think this is actually worse for the following reasons: 1. It would be far less obvious to the programmer that an object would behave differently with a given operator, because the behavior wouldn't be documented in the code itself. 2. It would require many different implementations, some of them very close to each other, to cover the same set of use cases. 3. It would likely result in some maintainability concerns as more users demanded different DSL type implementations be included in core, and the existing ones would need to be maintained. As I've mentioned, while I understand that to many programmers commutativity is a requirement of a good language, it is explicitly incorrect to require commutativity for math operations. The arithmetic operators are commutative for the real numbers, but there are many valid math concepts for which they are not commutative, and I feel like pushing for commutativity is a mistake. It is an attempt to force a behavior that we want on code that it may be incorrect for. Jordan --00000000000008289f05c90764f0--