Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:122904 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id 0F99D1A009C for ; Wed, 3 Apr 2024 00:16:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1712103435; bh=9H/AVxzFrcBEAybICqIwViN29oUaIxK/jLbbFfOtSNE=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=Qa3ROCkajCSnfUphnthgYy3Dch3wJFl9XncP1eWknCmaxwCsmWzcZGKepek3ptMq3 ZnMzlVCa1ZGajlvaiiSOXln8nX2XMQq80hnpMi0CK4KD95PUZb2jUpsMgI2eGsVQub TgXQ5XzNPAx1zeokZT8bp9A3MD+P6bhD/MmgezaL5MvB6CzFKovZj4Ie4p3kmkqt7q C5rucBJfEZ2yDQZqCCJSb74DzkYBtKPDpXjhkVn8jdG8AZidk8TI7Ku2vf5gBCmT1k IBwvWj/hRCiB0dMMz2y4F7AkVLe3zL2Gmw0Gg246rdW38a3NMo1TI5rbte9NGAhwfy tQsTtCnKCiySQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 864D11804DE for ; Wed, 3 Apr 2024 00:17:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-pg1-f178.google.com (mail-pg1-f178.google.com [209.85.215.178]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 3 Apr 2024 00:17:13 +0000 (UTC) Received: by mail-pg1-f178.google.com with SMTP id 41be03b00d2f7-5dc949f998fso3781718a12.3 for ; Tue, 02 Apr 2024 17:16:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1712103404; x=1712708204; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=9H/AVxzFrcBEAybICqIwViN29oUaIxK/jLbbFfOtSNE=; b=NepnKKtzmWecqXB5qwRlmJ84/cW7GFeUtV/SeL307H7dV1+wQqH6gHY7xsAbxXrdPK 0aqouveM7lblbmCeDS43LGmvVzrsN8wkX7VnAZkYVoxuVIMJgtHSfUsljzmuNkynHnrT RIbNuHIdAZIWIDITNJsc5ICUGKaEOPpFYtdp9OuZNlFaSB1BFoLjULouDRgqqOro0wUb EyD0K0jSjA4IKAPSNbjpKG2CLJpV9n8gzRa3QqmQbvDLkLi3yvxQM5HD+sc4iAvTtI2T rYyqb+v+UIcV0UqVKovSLIjiC8gROGQYWD1HZDqzwF/6FZvBSHpaGQeySMOVueKIoOG7 Aq+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712103404; x=1712708204; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=9H/AVxzFrcBEAybICqIwViN29oUaIxK/jLbbFfOtSNE=; b=H86MWyyDVarOpiAxp9Q18xdmsr9fSrm6ASuOPPsfvo9mXpQ3GcgoMn0YTB/zFbIzaP yrl3R4GxU7RhRcCfXbkZH/ARXCKN/3M9fyB3vaR6AQsu7IfWZrgFY0iKBYiWdls4EL2q J3drBtZfyP/I/f3nG+JqrvECRQYqDadRGy69xYyR0N42jXza+GNYBdWms2lpkj+aDIZW 9YXNFjmpIGgg7GyPyU0UGEuggYIB/lm+D49W1hUSZGDS6iB0WpaYbSFTQX0aduWPLr21 fgDwvMw/naLjUXKIceHvc5w33RBC2M1oFLbQRaN0QeC02E4qu7Fn86MhXh5+e6o7RIfy l/Ew== X-Forwarded-Encrypted: i=1; AJvYcCV4rdufrUqfqjzhTIXARsanHCF8/syESlx7YJI6sFok8ncEKy/gp4XvZ7PVABU++dS0PvSpKXBsfhzE3pLmVmbwWwKIngESjg== X-Gm-Message-State: AOJu0Yz4Vu8A62WFAb1wC9g/TDbr/HJG494PN75gLqJEyXFjWb/YyI0d g/HxMl9FpM2x+ttSWGHxqrnCxAARZ1zZx6Fnf6Zl+2aoD6Q32JP+Vwrfg0Ab6SU1rCxCrcjA4sb dhn8CsmOGsZQBpmLl63l6Vhb7hh4= X-Google-Smtp-Source: AGHT+IHq0qw04fIKKWX+j3GlT7cohFLX7wFcnJYuRT/+5mzOnZVRJm8su/8PeSa7ssVzam/934Bigj2NED2KZR7K0sg= X-Received: by 2002:a17:90a:880f:b0:29c:7537:afbc with SMTP id s15-20020a17090a880f00b0029c7537afbcmr11932769pjn.31.1712103404484; Tue, 02 Apr 2024 17:16:44 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 References: <4F094EDA-5058-407D-AF39-06FD934FDE1F@sakiot.com> <68CF373E-6ABF-4471-8992-813B4BA1B508@sakiot.com> <904197f4-afb5-401e-9e17-7a655c5449d0@alec.pl> <655FEA80-9AB4-4AAD-A310-70ED968C97A2@sakiot.com> In-Reply-To: Date: Tue, 2 Apr 2024 17:16:30 -0700 Message-ID: Subject: Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath To: Saki Takamachi Cc: Lynn , Aleksander Machniak , php internals Content-Type: multipart/alternative; boundary="0000000000003e415706152623c2" From: jordan.ledoux@gmail.com (Jordan LeDoux) --0000000000003e415706152623c2 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Tue, Apr 2, 2024 at 5:05=E2=80=AFPM Jordan LeDoux wrote: > > > On Tue, Apr 2, 2024 at 4:50=E2=80=AFPM Saki Takamachi w= rote: > >> >> The two use cases at issue here are when the div and pow's exponent are >> negative values. So how about allowing only these two methods to optiona= lly >> set `$scale` and `$roundMode` ? >> >> - The constructor takes only `$num` and always uses implicit scaling. >> There is no option for the user to specify an arbitrary scale. >> - `$scale`: If specified, use that value, otherwise use `10`. The scale >> specified here is added to the scale of the left operand and used as the >> scale of the result. In other words, `(new Number('0.01')->div('3', 2))` >> results in `'0.0030' // scale =3D 2 + 2 =3D 4`. >> - `$roundMode`: Specifies the rounding method when the result does not >> fit within the scale. The initial value is `PHP_ROUND_TOWARD_ZERO`, whic= h >> matches the behavior of the BCMath function. That is, just truncate. >> - If lucky enough to get the result within the scale, apply the implicit >> scale to the result. In other words, if calculate `1 / 2`, the resulting >> scale will be `1`, even if scale is `null` or specify a value such as `2= 0` >> for scale. >> - The result of a calculation with operator overloading is the same as i= f >> the option was not used when executing the method. >> >> However, I'm not sure if naming it `$scale` is appropriate. >> >> Also, since `BCMath\Number` is not made into a final class, there is a >> possibility of implementing an inherited class in userland. Regarding th= is, >> is it better to make the calculation method a final method, or to use a >> function overridden by the user when executing from the opcode? >> >> > The issue is that, presumably, this method will be used within the > operator overload portion of the class entry in C. If it is allowed to be > overridden, then this RFC is sort of providing a stealth operator overloa= d > to PHP developers. As much as I am for operator overloads having written = an > RFC for it, and as much as I find the arguments generally against it > lacking, I am not in favor of doing it that way with a kind of... unspoke= n > capability to overload the basic math operators in userland. I very much > like the feature, but I also think it should be intentionally and > specifically designed, which is why I spent a long time on it. I do not g= et > a vote for RFCs, but I would vote against this if I could just for that > reason IF the calculation methods were not private, the class was not > final, AND the function entry was used in the operator overload. > > And operator overloads are also the place where what you outlined above > gets murky. I think what you outlined is very close to a good final desig= n > for just the method usage side, but the operator usage side CANNOT provid= e > a scale or a rounding mode. That should be taken into consideration, > because allowing this object to be used with operators is probably the > single largest benefit this RFC will provide to PHP developers. > > What I ended up doing was that the VALUE of the object was immutable, but > the other information was not immutable. That has its own downsides, but > does allow for very explicit control from the developer at the section of > code using the class, but also avoids creating copies of the object or > instantiating a new object for every single "setting" change during > calculations. > > Jordan > I should clarify, the portion of your outline that I feel is not sufficient for the operator overload use case is that there is no way to use both operator overloads AND a scale other than 10 + left operand scale. Jordan --0000000000003e415706152623c2 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
On Tue, Apr 2, 2024 at 5:05=E2=80=AFP= M Jordan LeDoux <jordan.ledou= x@gmail.com> wrote:


On Tue, Apr 2, 2024 at 4:5= 0=E2=80=AFPM Saki Takamachi <saki@sakiot.com> wrote:

The two use cases at issue here are when the div and pow's exponent are= negative values. So how about allowing only these two methods to optionall= y set `$scale` and `$roundMode` ?

- The constructor takes only `$num` and always uses implicit scaling. There= is no option for the user to specify an arbitrary scale.
- `$scale`: If specified, use that value, otherwise use `10`. The scale spe= cified here is added to the scale of the left operand and used as the scale= of the result. In other words, `(new Number('0.01')->div('3= ', 2))` results in `'0.0030' // scale =3D 2 + 2 =3D 4`.
- `$roundMode`: Specifies the rounding method when the result does not fit = within the scale. The initial value is `PHP_ROUND_TOWARD_ZERO`, which match= es the behavior of the BCMath function. That is, just truncate.
- If lucky enough to get the result within the scale, apply the implicit sc= ale to the result. In other words, if calculate `1 / 2`, the resulting scal= e will be `1`, even if scale is `null` or specify a value such as `20` for = scale.
- The result of a calculation with operator overloading is the same as if t= he option was not used when executing the method.

However, I'm not sure if naming it `$scale` is appropriate.

Also, since `BCMath\Number` is not made into a final class, there is a poss= ibility of implementing an inherited class in userland. Regarding this, is = it better to make the calculation method a final method, or to use a functi= on overridden by the user when executing from the opcode?


The issue is that, presumably, this me= thod will be used within the operator overload portion of the class entry i= n C. If it is allowed to be overridden, then this RFC is sort of providing = a stealth operator overload to PHP developers. As much as I am for operator= overloads having written an RFC for it, and as much as I find the argument= s generally against it lacking, I am not in favor of doing it that way with= a kind of... unspoken capability to overload the basic math operators in u= serland. I very much like the feature, but I also think it should be intent= ionally and specifically designed, which is why I spent a long time on it. = I do not get a vote for RFCs, but I would vote against this if I could just= for that reason IF the calculation methods were not private, the class was= not final, AND the function entry was used in the operator overload.
=

And operator overloads are also the place where what yo= u outlined above gets murky. I think what you outlined is very close to a g= ood final design for just the method usage side, but the operator usage sid= e CANNOT provide a scale or a rounding mode. That should be taken into cons= ideration, because allowing this object to be used with operators is probab= ly the single largest benefit this RFC will provide to PHP developers.

What I ended up doing was that the VALUE of the object= was immutable, but the other information was not immutable. That has its o= wn downsides, but does allow for very explicit control from the developer a= t the section of code using the class, but also avoids creating copies of t= he object or instantiating a new object for every single "setting"= ; change during calculations.

Jordan

I should clarify, the portion= of your outline that I feel is not sufficient for the operator overload us= e case is that there is no way to use both operator overloads AND a scale o= ther than 10=C2=A0+ left operand scale.

Jordan
=
--0000000000003e415706152623c2--