Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:116691 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 7649 invoked from network); 21 Dec 2021 00:53:58 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 21 Dec 2021 00:53:58 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id B8BA21804F8 for ; Mon, 20 Dec 2021 17:57:31 -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=-2.1 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 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-f42.google.com (mail-lf1-f42.google.com [209.85.167.42]) (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 ; Mon, 20 Dec 2021 17:57:31 -0800 (PST) Received: by mail-lf1-f42.google.com with SMTP id x7so1279379lfu.8 for ; Mon, 20 Dec 2021 17:57:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=7LrLoqzG+G5enXad5+5Jn2jTV6oUgeuiNnRqlY/Q9s4=; b=n4jKGO+yCrPv6I9vhfrurKbWnuZVmxWt2o4cRN6kkVGaQX5ELg1PCPafR/g3UORYAg swa2xDAAleaIuer7SzMQFF+NGcKEbZslZRnBaxNBoCF2tPYrI0QHbwtuAurwKMZTLFDd QjucZVYtM0RAropwbX8y4ij85GTmdjThnAaZurqJ5Ch3uPO++PhzwY3JRbWqJ7WB561Q wPt+GL8Tzqm/G/S+COcL5A9lJBFUE2aZKK5RUonBYylhjiAkpbIasXy3drL2/9nV2ENZ niarfe/tGsnSaoyEx+OUS0FAmjIsES+VS37WgAvpGgPR5JPkhSwJt6y/BCEtHZiQV5Xn umuA== 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; bh=7LrLoqzG+G5enXad5+5Jn2jTV6oUgeuiNnRqlY/Q9s4=; b=yo104hfFitqcSgcdK/V2PsIRDWR8iqIXvduJumJE99fV96mHnCzgQqUkcFSB9uwNT5 J9z4DfV5+gW4sJQhpCDet5oAcTe9MCj5yxTziXCW6YR0zp2ehDv8JYNaVIx3CpB1XkP0 hVyL3YqlHQtBMXcmePVn1GU7YOljYDZXp5ki7mlF0mTJ0stgHqQiZvG5rlFO2SyEtiET zkj7yenREVsnyLYosat238QvBPUaIvFlkKkHjHRp9aojrebsSdCr+bS5gt4GaYz3Yl3l zKp/KKjEzUTrQty0xTV1w0oGruC22SdBHq+WnRNzFfiPjookZ1s8OTc8EqulJ30vXmgV 1NPA== X-Gm-Message-State: AOAM530/7Cefz+KQQ5jGkfvOUlh9Dbn4HZqJvu+zLSEvEYlzaZx8g8JZ w73bzzAyU6EIv9AZ5ZiVVSuAI09Al5alMQv6oQQ= X-Google-Smtp-Source: ABdhPJw7Jy+S8ZTXzqHrGMQZlMlT4tfqnKEBRKiSUFIBFouVqBg8gu8g7rqLStvMctNXv/lxUU/auMoME1bk9YzGIYI= X-Received: by 2002:a05:6512:2355:: with SMTP id p21mr957872lfu.640.1640051849542; Mon, 20 Dec 2021 17:57:29 -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: Mon, 20 Dec 2021 17:57:16 -0800 Message-ID: To: Andreas Hennings Cc: Dan Ackroyd , Stanislav Malyshev , PHP internals Content-Type: multipart/alternative; boundary="000000000000e7c01505d39e5377" Subject: Re: [PHP-DEV] [RFC] User Defined Operator Overloads (v0.6) From: jordan.ledoux@gmail.com (Jordan LeDoux) --000000000000e7c01505d39e5377 Content-Type: text/plain; charset="UTF-8" On Mon, Dec 20, 2021 at 4:43 PM Andreas Hennings wrote: > > 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 discussion about it: https://stackoverflow.com/questions/1552260/rules-of-thumb-for-when-to-use-operator-overloading-in-python One of the interesting things here is that *most* of the warnings for Python users discussed at the link are actually *designed* to not be issues within this RFC. That's on purpose of course, I tried to think about how some of the design issues in Python could be improved. In Python, the +, +=, and ++ operators are implemented independently. In this RFC, you may only overload the + operator, and then the VM handles the appropriate surrounding logic for the other operators. For instance, with ++$obj or $obj++, you want to return either a reference or a copy, depending 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 += works similarly, with the ZVAL's being assigned automatically and a subordinate call. This vastly reduces the surface for inconsistency. Another warning that is discussed is around overloading the == operator. A big reason for this is that the Python overloads do NOT require the == overload to return a particular type. Because of this, overloading the == operator can result in situations in Python where it is difficult to compare objects for equality. However, in this RFC the == 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 boolean value, ensuring that the operator cannot be co-opted for other purposes easily. Additionally, the != and == cannot be independently implemented in this RFC, but can in Python. In Python the inequality operators can be implemented independently: >, >=, <=, <. They *also* are not required to return a boolean value. In this RFC, independent overloads for the different comparisons are not provided. Instead, you must implement the <=> operator and return an int. Further, the int value you return is normalized to -1, 0, 1 within the engine. This ensures that someone could not repurpose the > operator to pull something out of a queue, for instance. (They could still repurpose >> to do so, but since the shift left and shift right operators are not used in the context of boolean algebra often in PHP, that's far less dangerous.) A future scope that I plan on working on is actually having an Ordering enum that must be returned by the <=> overload instead, that even more explicitly defines what sorts of states can be returned from this overload. A lot of years of language design experience have been invested into operator 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 that PHP will end up with the most restrictive operator overloads of any language 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 (personally) an uncompelling argument against the feature. There are *many* features in PHP that a determined programmer can create problems with. The __get, __set, __call, and __callStatic magic methods can actually allow you to overload the *assignment* operator for certain contexts. The __toString magic method can already be used to mutate the object through a simple concatenation. 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 PHP features that in some way already interact with operators and objects in special circumstances. Jordan --000000000000e7c01505d39e5377--