Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:116701 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 48223 invoked from network); 21 Dec 2021 12:44:06 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 21 Dec 2021 12:44:06 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id D6D3018053E for ; Tue, 21 Dec 2021 05:47:48 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE 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-vk1-f171.google.com (mail-vk1-f171.google.com [209.85.221.171]) (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 ; Tue, 21 Dec 2021 05:47:48 -0800 (PST) Received: by mail-vk1-f171.google.com with SMTP id o2so8255231vkn.0 for ; Tue, 21 Dec 2021 05:47:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dqxtech-net.20210112.gappssmtp.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=DruzG6SlDgFzFwVcmQoqIvjX8YmI753AZkMUyoHUVuQ=; b=1XiPBnnAWruVL90eg/atUAIPH1w71jg534ro/Am63EkP/mkj4jHG81O1OZaLDvOwpc ntPwCjSk2HfPXWwiQ7bv0cQMHNyAM15TMrnG4osFo6F/G59/86UzWQbztV5uQz1+wWNq vxPw6nAVun4GtHOk97e2Ced6jBcZ0S25DDxgfZJdA9L/CWA3TwHgr66STpJOQ9nfucsm lgQvSBssM4+yBzpbtNb8/fAkkdnzy8cqOg4POsyfTkzaI3r5NobbIuPwspWOYiJx2tfh qsG7WZN/HD8V8K5MHLXzu9oQaV3y3nm68k7VV7oJmog0ngTDck2ehJtvB+7DzEaEEXKM QACQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=DruzG6SlDgFzFwVcmQoqIvjX8YmI753AZkMUyoHUVuQ=; b=uqXci3R/j/vWRPqRNoef4TyqSP+TvpXrGQDpXjb7E5uyg5tNlXWDsku1g5ih1nvuhN ioZUjHovky9eu7wK+oo4M1qySSh/BOPxb03wqHkjlJ/nSThFGpjiKDZphX8iy+RkOfmy fcjNfQjOjrZTkT9izm5/UaIsT3xigYveEcp84Gawy29gfh0QX7TipoAum6sXV4P9cNj9 IF4BPsqbJSCmtn1+EAxg6FLOWIJrEicpYl1405Beu83J5a7Bolyrod07EksbHyRRLk2N UzQ9h+ghgZdTSuyKV629k7t+9hn7V9Ou14MxtGemjLv0PD0KVrvr9aniibkNj6VZqZTv 9fpA== X-Gm-Message-State: AOAM531ZpEzCpLELvaBZopIPx+0JuhCd0N96gMg+jWh0vgKDWbYDoO3q yjVt7NmZuC13xCahBrTOfbb2fjD1zOUuUCcamEVGbA== X-Google-Smtp-Source: ABdhPJyLLiyObJ7EjzUyIDoSAFgUgliHBO/3Hy/Nee2WKPgTVpgoqghj9RALbRwytjB7a03KqBL/f2DYCrrKm9j/uM4= X-Received: by 2002:a05:6122:548:: with SMTP id y8mr1437410vko.24.1640094467703; Tue, 21 Dec 2021 05:47:47 -0800 (PST) MIME-Version: 1.0 References: <44b3fb4b-4693-1639-c8c0-5e17296c196e@gmail.com> <4b58c011-ed87-ba87-201d-0cf8e4116c6f@processus.org> <67431363-cd1e-9575-7d51-0f4d265d05b9@gmail.com> In-Reply-To: Date: Tue, 21 Dec 2021 14:47:36 +0100 Message-ID: To: Jordan LeDoux Cc: Dan Ackroyd , Stanislav Malyshev , PHP internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] [RFC] User Defined Operator Overloads (v0.6) From: andreas@dqxtech.net (Andreas Hennings) On Tue, 21 Dec 2021 at 02:57, Jordan LeDoux wrote= : > > > > On Mon, Dec 20, 2021 at 4:43 PM Andreas Hennings wr= ote: >> >> > The exact position of where that trade-off is 'worth it' is going to >> > be different for different people. But one of the areas where PHP is >> > 'losing ground' to Python is how Python is better at processing data >> > with maths, and part of that is how even trivial things, such as >> > complex numbers, are quite difficult to implement and/or use in >> > userland PHP. >> >> Could be interesting to look for examples in Python. >> I was not lucky so far, but there must be something.. >> ... >> Btw it would be really interesting to find such a list of >> recommendations for Python. >> The reference you added, >> https://isocpp.org/wiki/faq/operator-overloading#op-ov-rules, is for >> C++, which is less comparable to PHP than Python is. > > > During my research phase of this RFC I was able to review many different = takes on this from the Python space. Here is one example of a community dis= cussion about it: > > https://stackoverflow.com/questions/1552260/rules-of-thumb-for-when-to-us= e-operator-overloading-in-python > > One of the interesting things here is that *most* of the warnings for Pyt= hon users discussed at the link are actually *designed* to not be issues wi= thin this RFC. That's on purpose of course, I tried to think about how some= of the design issues in Python could be improved. Right. Your RFC might be the best we can do in the current PHP world, and better than what exists in some other languages. The remaining concerns would apply to any operator overloading RFC in current PHP, and would not be special to this one. > > In Python, the +, +=3D, and ++ operators are implemented independently. I= n this RFC, you may only overload the + operator, and then the VM handles t= he appropriate surrounding logic for the other operators. For instance, wit= h ++$obj or $obj++, you want to return either a reference or a copy, depend= ing on if it's a pre- or post-increment. In this RFC, the handling of when = the ZVAL is returned is handled by the VM automatically, and a subordinate = call to the opcode for + is made when appropriate. The reassignment +=3D wo= rks similarly, with the ZVAL's being assigned automatically and a subordina= te call. This vastly reduces the surface for inconsistency. I see the "Implied Operators" section. I assume this means that a new instance will be created, and stored on the same variable, _if_ the original operator is written in an immutable way (which it should be)? E.g. $money =3D new Money(5); $orig =3D $money; $m2 =3D $money + new Money(2); assert($money =3D=3D=3D $orig); // Checking object identity. assert($m2 !=3D=3D $orig); $money +=3D new Money(1); // Equivalent to $money =3D $money + new Money(1= ); assert($money !=3D=3D $orig); assert($orig->amount() =3D=3D=3D 5); I think we need a strong recommendation to implement operators as immutable= . > > Another warning that is discussed is around overloading the =3D=3D operat= or. A big reason for this is that the Python overloads do NOT require the = =3D=3D overload to return a particular type. Because of this, overloading t= he =3D=3D operator can result in situations in Python where it is difficult= to compare objects for equality. However, in this RFC the =3D=3D operator = can only be overloaded to return a boolean, so the semantic meaning of the = operator remains the same. Though you could of course do something terrible= and mutate the object during an equality comparison, you must return a boo= lean value, ensuring that the operator cannot be co-opted for other purpose= s easily. Additionally, the !=3D and =3D=3D cannot be independently impleme= nted in this RFC, but can in Python. > > In Python the inequality operators can be implemented independently: >, >= =3D, <=3D, <. They *also* are not required to return a boolean value. In th= is RFC, independent overloads for the different comparisons are not provide= d. Instead, you must implement the <=3D> operator and return an int. Furthe= r, the int value you return is normalized to -1, 0, 1 within the engine. Th= is ensures that someone could not repurpose the > operator to pull somethin= g out of a queue, for instance. (They could still repurpose >> to do so, bu= t since the shift left and shift right operators are not used in the contex= t of boolean algebra often in PHP, that's far less dangerous.) A future sco= pe that I plan on working on is actually having an Ordering enum that must = be returned by the <=3D> overload instead, that even more explicitly define= s what sorts of states can be returned from this overload. > > A lot of years of language design experience have been invested into oper= ator overloading across various languages. I wanted to at least try to take= advantage of all this experience when writing this RFC. It's why I say tha= t PHP will end up with the most restrictive operator overloads of any langu= age I'm aware of. There will still be pain points (returning union types is= not an easy thing to eliminate without full compile time type resolution),= but as far as buggy or problematic code, there's a lot about this RFC that= works to prevent it. > > A determined programmer can still create problems, but I find this (perso= nally) an uncompelling argument against the feature. There are *many* featu= res in PHP that a determined programmer can create problems with. The __get= , __set, __call, and __callStatic magic methods can actually allow you to o= verload the *assignment* operator for certain contexts. The __toString magi= c method can already be used to mutate the object through a simple concaten= ation. The ArrayAccess interface forces you to deal with the union of *all*= types (mixed), even when that doesn't make sense. And these are just the P= HP features that in some way already interact with operators and objects in= special circumstances. > > Jordan