Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:116676 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 95645 invoked from network); 17 Dec 2021 17:35:06 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 17 Dec 2021 17:35:06 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id C4B8018053D for ; Fri, 17 Dec 2021 10:37:51 -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-f43.google.com (mail-lf1-f43.google.com [209.85.167.43]) (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 ; Fri, 17 Dec 2021 10:37:51 -0800 (PST) Received: by mail-lf1-f43.google.com with SMTP id d10so6458147lfg.6 for ; Fri, 17 Dec 2021 10:37:51 -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=2XTo/ddZ57Dndbx4fijr5BK577tqcAnUIx6XrlrD+08=; b=ThCExqCe0LTfWWNO0SqNJhqXaQrC08V3PQf03VuP3NmfI1j2gIy64dgggOWMOcsIVl xYqMzcM19404ibAzqg8Wyg6yZpH0Tar0sWdRwroP+G9iIT/38abV99oyer4VkpFszDtQ pE1JYSfndiXzPL7bVZTsBJfqCHVMkMsBlMXKlIbUEQel7pjmrCWO+zRR797dlK9zFrpW IbKr3JbYfWlNRCG5xtGWCaZSqSOR8MqZE430NtdYA/rLvhQ2Pzn4eEf+7naorlpGPZkX eql18tNWjTSbxKXBT9P1rQGband6Pq/38yINc/jn3Mo2NN5L+Ta5ZIjcqQoBMFbFrm9t nG8g== 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=2XTo/ddZ57Dndbx4fijr5BK577tqcAnUIx6XrlrD+08=; b=jHfgvvthKe1iRWoao5woiaqZd38h+3Z0pTq6WizstUqCKFP9ZfHjqfu2OhfafvroJ/ uQjRwW2eZD/2dFW5jcOondmGSz9g1fZrUiCjWtD8BQRrskwgI9wEaeaDIpxijiP6/maM Vwdi0KdO9UEQS82hZHsjUG5olre5p6EmBE/ng0zYbKSHaspgMNNIzHI4yFwJSKYF+/3G gahSEgExLSkYEg+wUua4LLUw6E8afWKuWFa5+3+EvNyR9U7JwdnoGwc2aeVd2TEzAsnX c9qnzDJsj1qn/QUC5+MTwBXUUiM1XLFQCXxf4BI50XzzvTHbR7/r7COQUr99PjQvlpE/ neEw== X-Gm-Message-State: AOAM531szNIR17USNL68cmw3qczDgVgWsUydT8DyC3Xx76ODU20pIrYA Qv1HXBumuhhhOJkP3GefguAmGQEm6rufUoiuCLJgRA4C X-Google-Smtp-Source: ABdhPJwrH4tEtPq3uhliTEAIlS51B5w6asp5VBefhhy7bGd+D9gOI+/h3lYDQMqG92c5YGLBVvoelh0uS0JNLh6GPX0= X-Received: by 2002:a19:750f:: with SMTP id y15mr3966616lfe.258.1639766269888; Fri, 17 Dec 2021 10:37:49 -0800 (PST) MIME-Version: 1.0 References: <44b3fb4b-4693-1639-c8c0-5e17296c196e@gmail.com> <4b58c011-ed87-ba87-201d-0cf8e4116c6f@processus.org> In-Reply-To: Date: Fri, 17 Dec 2021 10:37:38 -0800 Message-ID: To: Matt Fonda Cc: PHP internals Content-Type: multipart/alternative; boundary="000000000000080d1a05d35bd6f6" Subject: Re: [PHP-DEV] [RFC] User Defined Operator Overloads (v0.6) From: jordan.ledoux@gmail.com (Jordan LeDoux) --000000000000080d1a05d35bd6f6 Content-Type: text/plain; charset="UTF-8" On Fri, Dec 17, 2021 at 9:43 AM Matt Fonda wrote: > Hi Jordan, > > Thanks for the RFC. I have a couple questions: > > Suppose I have classes Foo and Bar, and I want to support the following > operations: > > - Foo * Bar (returns Foo) > - Bar * Foo (returns Foo) > > If I understand correctly, there are three possible ways I could implement > this: > > a) Implement the * operator in Foo, accepting a Foo|Bar, and use the > OperandPosition to determine if I am doing Foo * Bar or Bar * Foo and > implement the necessary logic accordingly. > b) Implement the * operator in Bar, accepting a Foo|Bar, and use the > OperandPosition to determine if I am doing Foo * Bar or Bar * Foo and > implement the necessary logic accordingly. > c) Implement the * operator in Foo, accepting a Bar (handles Foo * Bar > side); Implement the * operator in Bar, accepting a Foo (handles Bar * Foo > side) > > Is this understanding correct? If so, which is the preferred approach and > why? If not, can you clarify the best way to accomplish this? > You are correct in your understanding. All three of these would accomplish what you want, but would have varying levels of maintainability. Which you choose would depend on the specifics of the Foo and Bar class. For instance, if the Bar class was one that you didn't ever expect to use on its own with operators, only in combination with Foo, then it would make sense to use option 1. The inverse would be true if Bar was the only one you ever expected to use with operators on its own. The better way, in general, would be for Foo and Bar to extend a common class that implements the overload in the *same* way for both. In most circumstances, (but not all), if you have two different objects used with each other with operators, they should probably share a parent class or be instances of the same class. Like I said, this isn't always true, but for the majority of use cases I would expect it is. > Next, suppose I also want to support int * Foo (returns int). To do this, > I must implement * in Foo, which would look like one of the following > (depending on which approach above) > > public operator *(Foo|int $other, OperandPos $pos): Foo|int { ... } > public operator *(Foo|Bar|int $other, OperandPos $pos): Foo|int { ... } > > Now, suppose I have an operation like `42 * $foo`, which as described > above, should return int. It seems it is not possible to enforce this via > typing, is that correct? i.e. every time I use this, I am forced to do: > > $result = 42 * $foo; > if (is_int($result)) { > // can't just assume it's an int because * returns Foo|int > } > In general I would say that returning a union from an operator overload is a recipe for problems. I would either always return an int, or always return an instance of the calling class. Mostly, this is because any scalar can be easily represented with a class as well. Jordan --000000000000080d1a05d35bd6f6--