Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:109379 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 95702 invoked from network); 28 Mar 2020 10:57:45 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 28 Mar 2020 10:57:45 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 2B5C81804D0 for ; Sat, 28 Mar 2020 02:23:07 -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=-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-f67.google.com (mail-lf1-f67.google.com [209.85.167.67]) (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 ; Sat, 28 Mar 2020 02:23:00 -0700 (PDT) Received: by mail-lf1-f67.google.com with SMTP id j188so9844831lfj.11 for ; Sat, 28 Mar 2020 02:23:00 -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=moyDkHahlMk2D+ASMwptZajae0O6nOhwKAmiyS4rHj0=; b=OWwSACKpSTki5kGPALPxJdEKzkFP48DqCl6ZZkRYzwsiWEjrJYylrg7pnhEmRYtVUr pwRMxfifOJkLk1PsHpbSsaDibkR9YT5NAWpbBh4WmOaoxiK0Uz+ygt6lzMD+OcB++zpu n6ZsRMeCrrde/8TeHCsdGGOVa+dcCEaeithCSHBDc1920ojo0C0DZUKklMeld5VhIbb8 zYnDgYqY03Q5pLegZWlaUntnqMuIYLYlz+De0KWVAjoaeifE/8d9gzaVfblNSegWbhuF yA/734RYbfH6NZufgXOc4I6PZKIGlxDaqPBP1YqjzNu3muGbMA9XW//OtxH+W7gIC9L6 lsHA== 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=moyDkHahlMk2D+ASMwptZajae0O6nOhwKAmiyS4rHj0=; b=eEBgOjgeBHzV+MIyE8P4RLU69kOasIvp5OSJukxKlS3a8q5a2YYpeZQCO/P8bSa4wv eKHFMHdhEXbC//J5rBVnf7XH8TElMoOh3XkikmAeUXDOOYRiDMINOqAmVuf+3sxrvqny ZoLc2BguT1iHzlFyxDTGdwTrpoeRpIlVk7Y5ywwTmAz+DVkFRlmYmatGSHmwUc01mTBm C3hrUd9DzPMl2wRSqBC+ZIlOLZ1S1+1zmGb0khUjgJLn32gdwG88hExReoCOslyDGmT3 OsWgt72UNex4hfwBm18A+hsVvLQ7pkFOoEKa6c5IB/Norsaa4ScCGaRL1ezPBxHUBlHK Q55w== X-Gm-Message-State: AGi0PuZqQUmiF3m79JEys/OmavsLs8N3f1nO31W50pvtAX9oDWib43FW jk1mPYrfwYSZiiyDNGVvIrJQNraPH9MUcWaAHRQ= X-Google-Smtp-Source: APiQypKq58QSXuTa8bBeMN0NlQX4ehlbb48bIIql1tn+QDcARNHuOla9jc3F3mx/aHAg2d700pte7/MjKtycPwvRuio= X-Received: by 2002:ac2:5edc:: with SMTP id d28mr2204546lfq.59.1585387375980; Sat, 28 Mar 2020 02:22:55 -0700 (PDT) MIME-Version: 1.0 References: <003701d6013c$9afe9750$d0fbc5f0$@gmx.de> <7a83f950a31d94d5ff2307ac8219db3b7b6482b6.camel@schlueters.de> In-Reply-To: <7a83f950a31d94d5ff2307ac8219db3b7b6482b6.camel@schlueters.de> Date: Sat, 28 Mar 2020 10:22:44 +0100 Message-ID: To: =?UTF-8?Q?Johannes_Schl=C3=BCter?= Cc: PHP internals , jan.h.boehmer@gmx.de Content-Type: multipart/alternative; boundary="00000000000060738405a1e6c375" Subject: Re: [PHP-DEV] [VOTE] Userspace operator overloading From: arnold.adaniels.nl@gmail.com (Arnold Daniels) --00000000000060738405a1e6c375 Content-Type: text/plain; charset="UTF-8" > > > On Mon, 2020-03-23 at 18:58 +0100, jan.h.boehmer@gmx.de wrote: > > Hi internals, > > > > I have opened voting on > > https://wiki.php.net/rfc/userspace_operator_overloading, which allows > > users to overload operators in their own classes. > > > > I consider operator overlaoding in general a good feature (while PHP's > overload for + on arrays is weird) > > However I don't like this design. > > Consider this case: Some library provides a type A without overloads. I > then create a type B with overload: > > class B { > static public __add($lhs, $rhs) { > if ($lhs instanceof A) ... > elseif($rhs instanceof A) ... > else error > } > } > > as I want my type's addition to commutative I handle this with some if > (probably dispatching. Now I can invoke it: > > new A() + new B(); // calls B::__add() > new B() + new A(); // calls B::__add() as well > > Now the maintainer of A implements the feature request "A should allow > addition with integers", I update my library and suddenly weird things > happen. > > new A() + new B(); // calls A::__add() and explodes, as A doesn't know > B > new B() + new A(); // calls B::__add() works as before > > Now we could establish the best practice that one type's operator calls > the other type's operator in case it can't handle a type. However that > is no good option as it will lead to infinite recursion if neither type > can handle both operands. > > > The issue is that by forcing type declarations as part of the class, as > members, this forms a closed set, but for many cases a strict closed > set isn't what one wants. For mathematical types having operators > working with integers (and other numeric values) is essential. > Communativity often also is required. So a true closed set doesn't > work, for an open set can't be created easily in today's PHP. Thus the > RFC tries to tie this together, but this will fall apart and then cause > legacy and BC reasons preventing future improvement. > > I believe the pre-requisit is having some form of function overloading, > where operator functions for specific argument types can be defined. In > https://news-web.php.net/php.internals/108425 Andrea created an idea, > which is probably "ugly" but has less usage restrictions. I think > spending time on function overloading (I believe, without proving it, > this can be done with very little cost for non-overlaoded cases - by > adding a flag "overloaded" along visibility flags and check that along > with the visibility check, only in case of an overload to the > "expensive" check, which still is cheaper done in the engine than > if/else chains in userspace) and then take up operator overloading > again, rather than this smart but limited approach. (For whoever does > that: spend time in C++ and its function resolution rules incl. ADL, > not to copy, but to learn) > > johannes > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > > This issues become even more apparent when sequencing operations like `$a + $b + $c - $d`. Trying left, then trying right, will make it very difficult to determine the outcome of such a statement. The arguments against type hinting for operator methods, assume the "try left/right" method. Instead, type hinting should be applied to determine which method should be used. If both or neither methods are applicable, an error must be thrown. With class inheritance, you also don't want to rely on the order of the operands. If you're the creator of a library, that's out of your hands. If both the parent and child class overwrite the operation, and both accept the operands, then the child class should always be used. It's a -1 for me. I would vote in favor of an RFC for operator overloading without the "try left, try right" behavior. Arnold --00000000000060738405a1e6c375--