Re: [PHP-DEV] [PHP-Dev] Versioned Packagers (Iteration IV)
On Wed, Jul 10, 2024 at 1:08 PM Michael Morris wrote: > > > I'm in no rush - though it might not seem that way. I don't see this being > able to land before PHP 10. I'm pessimistic about the scope of these > changes. It can be done - and pieces have often been discussed before, but > they peter out. If they are to be solved some amount of stupid bulldog > tenacity will be needed. I think I'm stupid enough to provide that, but I > need to do it without being annoying. > > In any event these threads have already shown me a great deal of what I > need to learn in order to get to an effective final form, whatever that is. > The point of people asking multiple times to wait until any other time of year is not because anyone is worried you are trying to get it in right away, it's because doing this kind of freeform "I don't know what I don't know" discussion is unkind to all of the experts on the list who CAN tell you "well, what you don't know is X". Most of them probably won't even respond at this time of year, even if they did read, which they probably didn't. > > >> >> >1. Import Maps - These would be prepared by hand or by a package manager >> >like composer. >> >> As Larry mentioned, there was a proposal for this a while ago, but not >> much enthusiasm, since it's so easy to implement in userland, and doing so >> means we don't have to include all the possible options someone might want. >> >> >> > it will be able to detect symbols the autoload >> >system cannot: functions and constants. >> >> Autoloading functions and constants isn't blocked by autoloaders being >> procedural, it's blocked by the unfortunate decision made many years ago >> that a function call like "strlen" dynamically falls back to meaning >> "\strlen", rather than being resolved once at compile-time like class >> names. > > >> So far, nobody's quite cracked how that should interact with autoloading. >> Don't expect this to be easy. >> > > At worst this is the sort of "unfortunate decision" that can be eschewed > in the PHP module files to make them easier to work with. But I really do > need a list of these things we'd love to do but can't because of reasons. > > That's your job as the proposer. :) > >> >2. Packages - Packages load differently and can effectively monkey-type >> the >> >code of an existing package on the fly in much the same way that >> namespaces >> >themselves work with symbol names as a flat string replace. >> >> This is an interesting - but extremely complex - problem, and the one >> I've been urging you to focus on if you're really up for the challenge. It >> probably needs quite a deep dive into how the language works to find out >> what assumptions it's going to break. (If you're just going to talk about >> configuration, and not the actual implementation, don't expect much >> enthusiasm.) >> > > I need to know where to start, beyond cloning the PHP source code repo - > which I have. Any advice on where to look would be appreciated. > Try to change something, compile, then debug a test file with it. That's how I went from "has only done basic C" to "wrote almost all of the implementation of operator overloads" in a few months. Once you start on that, you'll be able to ask more specific questions that are more likely to get a specific and quick response. You'll want to know "when do we use this macro" and so on. You can also reference all the documentation that has been built for people who are getting into learning the PHP source: https://www.phpinternalsbook.com/index.html > >> > Existing code >> >can be loaded into packages, but also an outline for writing packages >> that >> >have privacy modifiers to their members - i.e. protected class SomeClass >> {} >> >> This part seems interesting, as long as it's not tied heavily into other >> changes; existing code using /** @internal */ should ideally need minimal >> changes to make use of it. >> >> >> >> >3. Modules - Files which are code first instead of template first. >> >> If by "template first" you mean "you have to write > repeat my earlier "meh". I'm pretty sure it's also been discussed before, >> and dropped when it met with that general reaction. >> >> The name "modules" implies something more, so maybe I should reserve >> judgement. Having both "packages" and "modules" sounds pretty confusing >> though. >> > > The largest thrust of modules is to step forward with changes that are > desirable but impossible to implement because of BC breaks brought on by > unfortunate design decisions like the one mentioned previously. Likely > these will be visited on a case by case basis. For another is the need of > classes to have the function keyword all over the place. > > It could end up that things like package privacy can only be supported in > the modules. As to the difference, since it meanders all of the place > here's the defs I'm going with - A module is a file. A package is a > collection of files. > So then the purpose of modules, to you,
Re: [PHP-DEV] [PHP-Dev] Versioned Packagers (Iteration IV)
On Tue, Jul 9, 2024 at 11:42 PM Mike Schinkel wrote: > [snip] > My one useful takeaway from your email — except that I already knew that — > was the need to figure out how PHP can handle multiple symbol tables. > Beyond that, your take your own advice and spare us (me) from your contempt > and condescension as they are not good looks on anyone. > > While Larry was very blunt (and I don't really fault him for that either), that should not be your only takeaway. The short version was that he was telling you, and the other people in this thread, to stop pontificating and to do something that resembles developing/researching a solution. A lot of the people who actually have experience working on the engine are literally ignoring this conversation right now (and may come back to it next month) because it's just too much noise and nonsense right when we're near feature freeze. Your focus and intent to drive this discussion towards trying to duplicate composer reduces its usefulness. I get that you do not like PSR-4/composer/whatever. I honestly cannot wade through the 15,000-ish words you've sent in these threads to nail down the specifics. But I know for a fact that an attempt to redesign composer is: 1. Orthogonal to PHP modules (they have nothing to do with each other from a design perspective). 2. Doomed to failure. Your one useful takeaway, that Larry gave you specific steps for, is to focus on the feature the original proposer of the thread was trying for, instead of continuing to derail it into composer-related nonsense. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Allow int type argument to BCMath function
On Tue, Jul 9, 2024 at 10:47 AM Tim Düsterhus wrote: > Hi > > On 7/8/24 11:36, Jordan LeDoux wrote: > > I suspected the same thing when I was doing my arbitrary precision > library, > > but I actually have yet to find a test case in all my unit tests where > this > > happens when converting to a string. You can see this here: > > > > https://3v4l.org/Ud8Cn > > PHP emits the shortest possible representation that roundtrips, so the > precision loss indeed does not happen when converting from float, but > rather when converting to float / when the implicit rounding happens > during the calculation. > > Nevertheless the inherent rounding error of floats and an arbitrary > precision maths library do not mix: Users should not be encouraged to > mindlessly pass a float, but rather work with strings all the time or > explicitly perform the necessary conversion as appropriate for their use > case - which of course is easier with strict_types enabled because then > the conversion would need to be made explicit with a cast. > > Best regards > Tim Düsterhus > Yes, absolutely agree that arbitrary precision math should not be done with floats, and developers should not be encouraged to use floats. However for the specific case of type-coercion into the argument of a `bcadd` or similar call, the detailed string conversion issues do not happen, which is all I was saying. Integers ALSO have a maximum precision, detailed by the `PHP_INT_MAX` constant, which varies by system and install (mainly on whether 64-bit integers are available). My point was not that floats or integers are sufficient, but that the entry point into an arbitrary precision calculation often comes from numbers that are stored as ints and floats. If we accept ints, and don't ask the developer to explicitly cast to string, I think we should do the same for floats. Both or neither. I can see the argument against accepting either, I can see the argument for accepting either. I do not understand the argument for accepting one but not the other. Jordan
Re: [PHP-DEV] [PHP-Dev] Versioned Packagers (Iteration IV)
On Mon, Jul 8, 2024 at 2:42 AM Rowan Tommins [IMSoP] wrote: > > > On 8 July 2024 04:25:45 CEST, Jordan LeDoux > wrote: > >I think it's strange that this discussion has driven deep down the tangent > >of versioning... > [...] > >Things like separating global scope between importer and importee, managed > >visibility of symbols and exports from modules/packages, allowing for > >separate autoloaders for things which are called or included via an > import, > >etc. Those are the things that the language itself can do. > > > >All this other stuff feels like a distraction. > > I agree. I wrote most of the below a couple of days ago, but I don't think > it posted correctly, so apologies if some people see it twice: > > Autoloading is just a way to load files later, by the engine telling you > when a class is first needed. PHP does not, and should not, make any > assumptions about how files are laid out on disk; an autoloader doesn't > actually need to load any files at all, and if it does, it uses the same > include or require statements which have been in PHP for decades. > > Likewise, installing packages and defining version schemes is a completely > separate problem space that can probably be served by a few small tweaks to > Composer once the language provides the underlying functionality. > > The core of the problem you seem to want to solve is this: if you have two > files foo_1.php and foo_2.php, which both define a class \Acme\Foo, how do > you load both of them, so that you end up with two differently named > classes? > > In JS, that's easy, because functions and object constructors (and > "classes") exist as objects you can pass around as variables, they don't > need to know their own name. In PHP, everything is based on the idea that > functions and classes are identified by name. You can rewrite the name in > the class declaration, and in direct references to it, but what about code > using ::class, or constructing a name and using "new $name", and so on? How > will tools using static analysis or reflection handle the renaming - e.g. > how does DI autowiring work if names are in some sense dynamic? > > You've also got to work out what to do with transitive dependencies - if I > "import 'foo_1.php' as MyFoo", but Foo in turn has "import 'guzzle_2.php' > as MyGuzzle", what namespace do all Guzzle's classes get rewritten into? > What about dependencies that are specifically intended to bridge between > packages, like PSR-7 RequestInterface? > > My advice: start with the assumption that something has already installed > all the files you need into an arbitrary directory structure, and something > is going to generate a bunch of statements to load them. What happens next, > in the language itself, to make them live side by side without breaking? If > we get a solid solution to that (which I'm skeptical of), we can discuss > how Composer, or the WordPress plugin installer, would generate whatever > include/import/alias/rewrite statements we end up creating. > > Regards, > -- > Rowan Tommins > [IMSoP] > Rowan Tommins > [IMSoP] > I think it could be done somewhat simply (relative to the other things that have been discussed) if the engine reserved a specific namespace for imported symbols internally. Something like: `\__Imported\MyImportStatement` Where the `\__Imported` namespace is reserved and throws a parser error if it occurs in code anywhere, and `MyImportStatement` corresponds to an application importing the code using something like `import MyPackage as MyImportStatement;` Then, all symbols which are loaded into the global space as a result of the import are actually rewritten into the hidden namespace the engine actually uses under the hood, and any uses from the import statement in the application code which has the import would reference the symbols in the prefixed namespace. This would not be trivial however. The engine code which supports this would need to keep track of a kind of "context" for each file, based on what namespace the file was included from. For instance, if an autoload occurs inside the package that was loaded into `MyImportStatement`, the engine would need to be aware that the code being executed is defined in that namespace, REGARDLESS of whether it was a class, function, or statement, and load ALL symbols that are created as a result into the rewritten namespace. It would also need to translate in the other direction for `use` statements inside the package, since it would not know ahead of time what rewritten namespace it would actually be loaded in. However, this is the simplest solution I see that doesn't involve writing a second PHP engine just for this sort of thing. Jordan PS: For those unaware,
Re: [PHP-DEV] [RFC] [Discussion] Allow int type argument to BCMath function
On Sun, Jul 7, 2024 at 8:19 PM Saki Takamachi wrote: > Hi Juliette, > > > Hi Saki, > > > > Just wondering: why `int|string` instead of `float|string` ? > > In my experience, floats are the more pertinent type for which to use > the BCMath extension. > > > > Smile, > > Juliette > > Since floating point numbers always contain a certain amount of error, I > believe that they are not suitable as arguments for BCMath. > > For example, 0.285 becomes 0.284999... in floating point. From the > perspective of arbitrary precision math, there is no universally agreeable > way to properly handle values like this: there will always be people who > want to treat it as 0.285, and people who want to treat it as 0.284999 > > Therefore, I believe BCMath should not accept floats as arguments. > > Regards, > > Saki I suspected the same thing when I was doing my arbitrary precision library, but I actually have yet to find a test case in all my unit tests where this happens when converting to a string. You can see this here: https://3v4l.org/Ud8Cn Jordan
Re: [PHP-DEV] [PHP-Dev] Versioned Packagers (Iteration IV)
On Wed, Jul 3, 2024 at 5:18 PM Michael Morris wrote: > Hello all. Hitting reset again as the primary problem at hand has become > clear. Let's recap it. > > Autoloading is great for loading packages, but it can't load different > versions of the same package at the same time. Why would you want to do > that? > > When you don't have full control of the code. > > For example, consider Drupal. It is running Twig at some version of 3 at > the moment. Suppose Twig 4 is introduced with significant backward > compatibility breaks (Not saying the authors would do such a thing) but > also wonderful features. > > If you're writing a Drupal extension you might want to use this new Twig. > This is possible if you are willing to monkey-type the package - that is, > have a code package traverse over the entire package and change all > instances of `namespace Twig` in the files to `namespace NewTwig`. You can > then use the package at the namespace of \NewTwig. > > This is painful, but the pain factor increases if multiple extension > developers choose to do the same thing. Each extension using its own Twig > library is going to incur a performance hit. > > One upshot of this is I've noted that major package distributors, like > Symfony, take BC into account with major releases - and may not develop new > features or change things in those releases out of fear of people not > wanting to upgrade. > > Now don't get me wrong, changing things just because is a bad thing. If a > BC can be avoided it should be. But having a mechanism to move forward is > important. > > In some ways versioning packages is like static typing variables. It > doesn't seem important at all until you are faced with a problem only it > can solve, or faced with a problem created by dynamic typing of variables. > > What can be done in the engine? > > Well first off, recognize that autoloading isn't going to work with a > versioned package scheme. Autoloaders, regardless of their resolution > schema be it PSR-0, PSR-4, or BobbysFirstAutoloader-Scheme can only have > one symbol per package, set by the namespace. > > Can PHP support multiple packages without rewriting the whole engine? I > think so, but it isn't trivial, and the side effects need to be cordoned > off so that those who need this complexity can have it while the beginning > and intermediate coders can ignore it just like they ignore strict > comparison operators and strict typing unless a library they are trying to > use foists it on them. > > This is why I advocate a new keyword for this - import. Import's behavior > is most similar to require_once, but it doesn't have to be the same. Since > it is a new entrypoint into the engine the way the engine considers the > code can be different - whether slightly different or radically different > is a debate for another time. I'm going to stick with only those changes > that make sense in the context of package links. > > Let's start with the simplest problem, importing this file. > > namespace A; > function foo() { echo 'Hi'; } > > To review, if we require_once this file we'll find the function at > \A\foo(). If our current file uses the same namespace we can just use foo() > > At its root import would do the same. `import "file.php"` would do the > same as a require_once assuming there's no difference between the file > structure rules for import - again there is opportunity here, but it's not > a requirement. > > If that's all it does, it's pointless. However, import can alias. > > import 'file.php' as B; > > Now we have \B\foo(); This makes it relatively easy to have two different > versions of the package running since in our own code we can always > reference the foo in the B namespace. But while that allows limited package > versioning, it doesn't solve the multiple extensions wanting to use the new > stuff problem outlined above. > > So we have to call out the version in code, like so. > > import 'file.php v1.0.0'; > > A simple space separates the version from the file. If the filename has a > space, well \ characters aren't just for namespaces. > > Now for the first real behavior difference between import and > require_once, even if we aren't doing anything fancy. Import cares about > the namespace it's invoked from. Require_once does not. To illustrate > this behavior he's some pseudocode - we are including the file.php given > earlier > > namespace D; > require_once 'file.php'; > > \A\foo(); // Hi. > > import 'file.php'; > > \D\A\foo(); // Hi. > > See that? The namespace of the calling file is prepended to the namespace > contained in the import. > > Why? What's the value here? I'll explain. > > Now, let's suppose we do have two versions of file.php. So in addition to > the above, elsewhere in the code this happens > > namespace C; > import 'file.php v2.0.0' > > A\foo(); // Welcome, since version 2 echoes welcome. Remember your > namespace resolution rules - this import is actually at: >
Re: [PHP-DEV] [RFC]I'd like to see the RFCs that deprecate the FFI non-static approach start voting
On Sat, Jul 6, 2024 at 1:09 AM chopins xiao wrote: > The reason I'm not so polite is because I'm so angry. Firstly, the > Deprecate functions with overloaded signatures RFC's approach to FFI > recommendations is unfounded, and secondly, the PR commit( > https://github.com/php/php-src/commit/4acf0084dcd63ec369a610ec966db33f322694c8) > has not been voted on by the RFC, and the implementation is very simple and > crude, and does not solve the problem that FFI's API is not so elegant (At > the very least, there are shortcomings such as complicated API calls, mixed > use of multiple types of functions, and reduced performance). > There are so many masters,I don't understand why it was merged. The commit > implementation was not voted on, and it is possible to withdraw it first. > > Very unfortunate. Might have a solid technical case, but you: 1. Called someone who contributed to the project with actual code stupid because they didn't do what you'd prefer. 2. Called the implementation they provided "simple and crude". 3. Asked about this on GitHub and were told it was voted on, but are bringing this anyway: https://github.com/php/php-src/issues/14608 4. Opened this ML thread with a request/demand to revert the commit simply because you want to talk about your proposal. 5. Did all of the above without any indication that you could provide a non-"simple and crude" implementation since you are apparently better at it than everyone else who contributes. Regardless of the technical merits, you're not going to win many discussions like that. Jordan
Re: [PHP-DEV] Re: [RFC] [Discussion] Fix up BCMath Number Class / Change GMP bool cast behavior
On Tue, Jul 2, 2024 at 4:06 AM Saki Takamachi wrote: > Hi all, > > > Hi internals, > > > > Created a follow-up RFC for the BCMath\Number class. This RFC also > contains proposed changes to GMP's bool cast. I have proposed similar > changes to BCMath, so for procedural efficiency I have combined them into > the same RFC. > > > > Note that although they are combined into one RFC, these votes are taken > independently. > > > > https://wiki.php.net/rfc/fix_up_bcmath_number_class > > > > Regards, > > > > Saki > > > Added changes to RFC. It is a proposal to remove all rounding during > calculations due to convenience issues and the fact that the functionality > is "excessive" to begin with. > > To be precise, it will have the same truncation behavior as the existing > BCMath function, making it impossible for users to change this behavior > during calculations. If the user wants to perform rounding, they must > always use the `round()` method. > > Regards, > > Saki This seems positive to me. Rounding being explicit makes more sense. Jordan
Re: [PHP-DEV] Iteration III: Packages (was Re: [PHP-DEV] [Initial Feedback] PHP User Modules - An Adaptation of ES6 from JavaScript)
On Mon, Jul 1, 2024 at 11:09 AM Mike Schinkel wrote: > > > and I'm fairly certain after keeping up with the thread that it is > almost universally not what people want. Most people just want the toolbox > be "finished" so to speak, not get a completely new one in addition that > has no compatibility with the old one. > > I get it. I am no longer proposing an alternative to the autoloader. PHP > developers are comfortable with autoloading and that is that. > > But that does not mean that I cannot tell you and others the emperor has > no clothes in hopes that people eventually see that there can be better > alternatives. > > -Mike I'm not sure that constantly reiterating a point that everyone already knows but simply disagrees with is productive for the list, considering that the objection boils down to "but I don't like it" instead of "here are the concrete technical drawbacks". All of the objections you had seemed to be from the perspective "but what if the developer is only allowed 100 files on disk and only uses notepad to edit the code?" I don't think those are technical drawbacks personally, I think those are developers that need to at least start programming like they are living in 2005. Jordan
Re: [PHP-DEV] [RFC] Operator Overrides -- Lite Edition
On Fri, Jun 28, 2024 at 12:55 PM Rob Landers wrote: > > > 3. The private/protected distinction is fairly meaningless for the > functions that implement overloads, because the privacy of the function is > ignored completely when it is executed to evaluate an operator. > > > Hmm. I like the idea of protected, because it gives a structure to it that > is apparent and usable right from the IDE. You just “fill in the blanks” or > stick with the default behavior. > I do not understand how the visibility has any impact on the usability you are seeking to provide. 4. The `static` distinction is also fairly meaningless, as in PHP there is > no situation possible where an operator overload can occur WITHOUT it > operating on objects themselves. > > > For this, that is the wrong approach. The actual behavior is on the type, > not the instance. The object instances may not even know their value, they > merely represent the value. > A GMP object instance that does not know its value? What are you even talking about? Can you show me some code explaining what you mean? I had literally months of this argument for the operator overloads RFC, and studied the overload implementations in six other languages as part of writing that RFC, I feel like I understand this topic fairly well. But I do not understand what you are saying here. > 6. The `comparable` function you propose doesn't actually have an operator > it corresponds to. There is no operator in PHP for "is the left value > comparable with the right value". There are operators for comparisons > themselves, which I assume you meant, but a bool is insufficient as a > return type for that. > > > In the engine, there’s just a compare function for internal overrides. So > we just check that everyone agrees that the two objects are comparable and > then pass it on to “business as usual.” > I'm aware of how the compare handler for class entries and zend_compare interact. What I am saying is that your design is insufficient for <=>. You cannot return `false` from this method to mean uncomparable, and `true` to mean comparable. The zend_compare function can validly return 0 or -1, with the -1 being used for both less than OR greater than because the operands are reordered to always be a less than comparison. Then 1, which normally is used for greater than, is used to mean uncomparable. If you alter GMP so that the compare handler directly calls the class entry for this "comparable" function, you will be mixing multiple return semantic meanings, assuming you can construct a way to make the values normalize. If you implemented "comparable" in the way you are describing, $obj1 == $obj2 would ALWAYS be true, no matter what their values are, completely changing the meaning of the equality operator for GMP. As you are proposing this without any genuine expectation you can pass it, this will be the last energy I will invest into helping. Jordan
Re: [PHP-DEV] [RFC] Operator Overrides -- Lite Edition
On Fri, Jun 28, 2024 at 10:47 AM Rob Landers wrote: > Hello internals, > > I'd like to introduce a new RFC: > https://wiki.php.net/rfc/operator_overrides_lite which extends the GMP > extension to support a limited set of operator overriding to developers. > It's designed to be limited and relatively simple, while still being quite > powerful. It would only be available if you have the GMP extension > installed and enabled, but would allow for creating powerful unit libraries > (such as representing money, duration, etc). > > I'm very interested in your feedback! > > This was initiated from a discussion in another thread: > https://externals.io/message/123872 > > Thanks for your time, > > Rob Landers > You probably have not actually looked at implementing this yet, so let me give you some advice: 1. You probably are not yet aware that operands get reordered, or their ordering is not guaranteed, when a comparison occurs. This is because there is no op code (currently) for Greater Than or Greater Than Or Equal. Instead the comparison is reordered so that the operands are swapped and a Less Than or a Less Than Or Equal is performed. This is perfectly acceptable until you need to determine whether the left or right operand's function needs to be called, such as with objects. 2. The fact that the signature uses `mixed` for the typing removes a lot of the safety features the previous RFC had, and makes a lot of the concerns that stopped that RFC worse. In PHP currently, an object used with any non-comparison operand results in a TypeError. In the previous proposal, this behavior was preserved *even for objects which implement overloads* unless they specifically listed the type as accepted in the overload definition. What this did is ensure that anything OTHER than a TypeError guaranteed the developer that they were dealing with an operator overload that they could go inspect. 3. The private/protected distinction is fairly meaningless for the functions that implement overloads, because the privacy of the function is ignored completely when it is executed to evaluate an operator. 4. The `static` distinction is also fairly meaningless, as in PHP there is no situation possible where an operator overload can occur WITHOUT it operating on objects themselves. 5. Your voting choices actually constitute something that is not allowed for RFCs. A 'yes' vote allows operator overloads for GMP, a 'no' vote changes GMP to `final`. There is no option here to leave PHP as it currently is, which is what a 'no' vote should mean. 6. The `comparable` function you propose doesn't actually have an operator it corresponds to. There is no operator in PHP for "is the left value comparable with the right value". There are operators for comparisons themselves, which I assume you meant, but a bool is insufficient as a return type for that. There's probably more, but this is a start for you to make some improvements and changes. However, I had to warn you before you put in too much effort that I am fairly certain this RFC has very nearly zero chance of passing. Jordan
Re: [PHP-DEV] [Initial Feedback] PHP User Modules - An Adaptation of ES6 from JavaScript
On Thu, Jun 27, 2024 at 2:41 PM Jim Winstead wrote: > On Thu, Jun 27, 2024, at 2:14 PM, Jordan LeDoux wrote: > > On Thu, Jun 27, 2024 at 12:53 PM Jim Winstead > wrote: > > > On Wed, Jun 26, 2024, at 7:15 PM, Michael Morris wrote: > > PHP User Modules are php files that are brought into the runtime through a > new parser that is able to generate faster and more concise runtime code by > removing support for problematic features and imposing a strict mode by > default. They focus on PHP as a language and not as a template engine. > > > I think the problem I have with this proposal is calling these "PHP User > Modules". Here's an admittedly uncharitable rephrase of this: > > "NewLanguage User Modules are NewLanguage files that are brought into the > PHP runtime through a new parser that may theoretically be able to generate > faster and more concise runtime code by implementing a different language > based on much of the syntax from PHP. This new language does not prioritize > its use as a template language for HTML." > > > Do you feel that Phar is a separate language? Is PHP no longer PHP if the > @ error suppression is removed? I'm really unclear about the point you are > making here, even if I ignore the "uncharitable" rephrase. > > > If I read through the 11 bullet points under "User Module Files" in the > original proposal, I see two that are actually related to modules and most > of them are just lopping off features from the PHP language in ways both > small (no need for instead of '::', '->', and '\'). > > The angle I am coming at this from is improving the developer experience > around "packages" or "modules" or whatever you want to call them, and so > much of this proposal doesn't seem to be about that. > > I could have made that point in other ways, and I'm sorry that my first > attempt came off as insulting. It really concerned me when I already saw > discussion about taking this off-list and going into the weeds on technical > details when the problem that is being addressed by this proposal is > extremely unclear to me. > > Jim > Ah, yes, THAT'S a fair point. While the idea of optimizing the engine/parser for modules has merit as part of a user modules proposal, I agree that many of the specifics proposed here feel pretty scatter-shot and unclear. The scoping operator change I simply ignored, as that feels to me like just asking "I would like to program in Node" and there's no clear benefit to changing the scoping operator outlined, while there is a clear detriment to eliminating the concatenation operator entirely. Mostly I ignored that aspect of it, because I assumed that all the people capable of implementing this proposal would just refuse stuff like that outright, and that the inclusion of it would guarantee the RFC fails, so no point in worrying. But the broader question you are presenting about the focus and goals of the proposal, and how the specifics relate to that, is actually a question that I share. Jordan
Re: [PHP-DEV] Overriding GMP objects
On Thu, Jun 27, 2024 at 2:35 PM Rob Landers wrote: > > > On Thu, Jun 27, 2024, at 06:07, Saki Takamachi wrote: > > > I agree with Gina. Being able to change the class of a computed result of > an inherited child class causes several problems. > > The points raised in the `BCMath\Number` discussion can be summarized as > follows. > > - If it is possible to perform calculations on parent Class and child > Class, what should the resulting class be? > > > Ask the class what it wants to be? > > - Multiplying the distance class and the speed class should give you the > time class. > > > That would depend on the library’s implementation. > > - Similarly, multiplying two distance classes together should yield an > area class. > > > See above. > > - If only child classes have a property that should be specified in the > constructor, how do you determine the value of this property in the result > class? Perhaps it is possible to determine the value of the property, but > in that case the commutativity of the computation should be lost. > > > This can be handled via the child class in static methods, per the library > specifications. > How is the library supposed to do that in the absence of operator handler functions that can be overridden, or at least called when an operator is encountered? Jordan
Re: [PHP-DEV] Overriding GMP objects
On Thu, Jun 27, 2024 at 2:14 PM Rob Landers wrote: > On Thu, Jun 27, 2024, at 05:39, Gina P. Banyard wrote: > > On Wednesday, 26 June 2024 at 18:24, Rob Landers > wrote: > > Hello internals, > > I've had this little library for a while ( > https://github.com/withinboredom/time), mostly as a place to experiment > with the quirks of PHP and take it in weird places. Anyway, I've been > experimenting with "strongly typed time" in attributes for a while now. At > this point, it's a little weird but doable to use something like this: > > #[MyAttribute(units: StandardSecond, amount: 5)] > > ... which is less than ideal. What I would really like is this: > > #[MyAttribute(5 * StandardSecond)] > > PHP doesn't support operator overloading, which, from the last RFC > attempt, probably won't for quite a long time. Thus, I started > experimenting with extending the \GMP class, which is perfectly allowed > since it isn't final. For those that don't know, GMP implements operator > overloading such that a GMP number times an int results in a new GMP number. > > Surprisingly, I can get this to work, but I end up with a GMP number -- > with the right value -- but not the right type. Hence this email. In > essence, I am attempting to "back-door" my way into having operator > overloading. > > I would like to add static protected methods to the GMP class that are > called for operations. In the event all objects are base-GMP objects, no > behavior will change. > > > No, GMP not being final was a mistake, mainly due to it the first > conversion from resources to opaque objects. > I was intending on making the class final via an RFC because no one > extends it, as it is pointless (checked also on private codebases via > Exakat). > AND This whole back-door idea was explicitly shut down in the BCNumber RFC > that got accepted for 8.4. > > > Oops, I extended it :p (pun not intended) > > In all seriousness, I actually find it a little weird but the weirdness > can be tucked away (check the readme file) for an ergonomic usage. It still > needs fleshing out, but for any kind of units library, it is an amazing > accident. I’d argue for keeping it or even embracing it. > > — Rob > I don't, that's why I pushed to include operator overloads. In fact, one of the libraries I was going to build (and have already partially built) was a units library that automatically handled unit conversions, multiplications, etc. by keeping track of everything in SI base units and providing different value classes for different combinations of SI base units. If you want to look at how I did that, I can email you the repo for that code directly, though I haven't touched it in a LONG time because it's mostly useless without operator overloads. Jordan
Re: [PHP-DEV] [Initial Feedback] PHP User Modules - An Adaptation of ES6 from JavaScript
On Thu, Jun 27, 2024 at 12:53 PM Jim Winstead wrote: > On Wed, Jun 26, 2024, at 7:15 PM, Michael Morris wrote: > > PHP User Modules are php files that are brought into the runtime through a > new parser that is able to generate faster and more concise runtime code by > removing support for problematic features and imposing a strict mode by > default. They focus on PHP as a language and not as a template engine. > > > I think the problem I have with this proposal is calling these "PHP User > Modules". Here's an admittedly uncharitable rephrase of this: > > "NewLanguage User Modules are NewLanguage files that are brought into the > PHP runtime through a new parser that may theoretically be able to generate > faster and more concise runtime code by implementing a different language > based on much of the syntax from PHP. This new language does not prioritize > its use as a template language for HTML." > > Do you feel that Phar is a separate language? Is PHP no longer PHP if the @ error suppression is removed? I'm really unclear about the point you are making here, even if I ignore the "uncharitable" rephrase. Jordan
Re: [PHP-DEV] [Initial Feedback] PHP User Modules - An Adaptation of ES6 from JavaScript
On Thu, Jun 27, 2024 at 11:13 AM Deleu wrote: > Who would build it is an extremely key aspect of making changes to PHP. > Ideas are hard enough to survive the RFC process when there's already an > implementation. Finding a sponsor to work on this would be the first step. > > ... > I like the idea but I'm a bit skeptical until we have some buy-in from > someone that could actually get this implemented. > > -- > Marco Deleu > Perhaps, though a conversation like this is helpful. Some rather complicated RFCs do get approved/voted on before an implementation is done when contributors who are familiar with the Zend engine get on board early. Conversely, there are some extremely thoroughly implemented complicated RFCs that get rejected because most voters don't participate in discussion until voting is actually started. Something as broad as this probably requires an off-list discussion with key active contributors, because participation on list is so hit-and-miss. Jordan
Re: [PHP-DEV] Overriding GMP objects
I am interested to see what people say to this. One of the primary reasons I was given by no voters on my operator overload RFC was that it was not useful enough to justify the complexity. Since then however we have had a steady stream of people on list presenting their use cases that have run into issues, and proposing hacks and workarounds. On Wed, Jun 26, 2024 at 10:25 AM Rob Landers wrote: > > - should we revisit operator overloading instead of me hacking my way into > it? > The primary reason I decided not to revisit the RFC with changes or updates was that the conversations I had with voters led me to believe that this was fundamentally unproductive to pursue. I would be happy to bring it again if that changes, but I will not get involved in working on this feature again unless I'm convinced the sentiment of voters has changed, or at least has become changeable. Jordan
Re: [PHP-DEV] [RFC] [discussion] Correctly name the rounding mode and make it an Enum
On Wed, Jun 19, 2024 at 12:16 PM Claude Pache wrote: > > Second, “TowardsPositiveInfinity” is just a mouthful synonym for “Up”. You > could just name it: > > Round::Up > > At this point, you may invoke either Hamming or Levenshtein and compare it > negatively with `Round::HalfUp`. Yes there is a risk a confusion (and I do > think that such a name is suboptimal for this reason), but the confusion is > not just caused by the short Levenshtein distance. That brings to the most > important part of my review. > > This is completely incorrect. "Up" is needlessly ambiguous. As evidence, I will quote from the CURRENT documentation for PHP: "PHP_ROUND_HALF_UP Rounds num away from zero when it is half way there, making 1.5 into 2 and -1.5 into -2" https://www.php.net/manual/en/function.round.php Clearly it is not "just a synonym", as the current PHP (incorrectly) equates "up" with "away from zero". It's the difference between rounding "up" in magnitude, and rounding "up" in value. Any discussion about "Hamming distance" utterly pales in the face of the reality that developers will be confused because we have trained them for 20 years to expect something else. People wanting to tab-complete faster is not a good argument in my opinion for doing something that will actively cause bugs and confusion about semantical meaning. "Up" and "Down" do not belong in a mathematical description of rounding where negative numbers exist, unless that term is consistent and WIDELY agreed on. However, to cause even FURTHER confusion, OTHER languages (such as the python function `round_up`) use "Up" to mean exactly what you are saying here: towards positive infinity. The fact that this is not a consistent terminology across languages that support rounding, AND the fact that PHP has for decades used "Up" to mean "Away from zero" makes this a complete non-started in my eyes. If there is ONE improvement to be made with this RFC, it is to completely remove "up" and "down" from the rounding terminology. Jordan
Re: [PHP-DEV] [RFC] [discussion] Correctly name the rounding mode and make it an Enum
On Sun, Jun 2, 2024 at 2:27 PM Jorg Sowa wrote: > > It should also be noted that ceil/floor is very English specific > terminology that may not be immediately obvious to non-English speakers, > thus my preference for using some variation of towards positive/negative > infinity. > > This statement is subjective in my opinion. For me, it's the contrary, > that's why I'm opposing introducing new terms to the PHP replacing ones > that already exist (ceil()/floor()). I don't have the data on such modes in > other programming languages, but I checked the data in Google Trends: > > https://trends.google.com/trends/explore?q=round%20toward%20positive%20infinity,ceiling%20math,round%20positive%20infinity,towards%20positive%20infinity=en > > Far more people search for `ceiling` than `round toward positive infinity` > or `round positive infinity`. Of course, I may be wrong by choosing > incorrect search phrases, but it's also good to see some data/examples that > changing this in PHP is for the better. > Well, probably plenty of people searching for "ceiling" who are remodeling their house so that statistic is probably completely useless. --- In terms of rounding, towards negative/positive infinity and "up" or "down" are almost always synonyms. There IS a difference (in general) between the terms "round towards positive infinity" and "ceil" however. They are rounding in the same direction, however "ceil" usually means "round towards positive infinity regardless of the value" and "round towards positive infinity" usually means "round towards positive infinity when it is unclear which direction is closer". For instance (typical behavior meaning): Ceil: 2.1 -> 3 Positive Infinity: 2.1 -> 2 Ceil: 2.5 -> 3 Positive Infinity: 2.5 -> 3 Ceil: -2.1 -> -2 Positive Infinity: -2.1 -> -2 Ceil: -2.5 -> -2 Positive Infinity: -2.5 -> -2 Ceil: -2.8 -> -2 Positive Infinity: -2.8 -> -3 If the behavior of that mode is to ALWAYS round regardless of the value of the remainder, then it should remain ceil IMO. It's a pretty well understood behavior in many programming languages. However, "HALF_TOWARDS_POSITIVE_INFINITY" is a different behavior, and should not be called ceil. The bigger issue is that "HALF_UP" and "HALF_DOWN" are utterly and completely incorrectly named. Those absolutely should be changed to something sensible, and is FAR more important IMO than this discussion about ceil. Jordan
Re: [PHP-DEV] [RFC] [Vote] Type Guards for Classes
On Thu, May 16, 2024 at 1:32 PM Patrik Václavek wrote: > Introduction > * > > This RFC proposes a new feature in PHP: type guards for classes (or > interfaces). This feature aims to simplify and standardize the process of > verifying that a variable is an instance of a specific class, enhancing > code readability and reducing boilerplate code. > > Motivation > * > > Currently, in PHP, to ensure that a variable is an instance of a specific > class, developers need to use the `instanceof` operator and manually throw > an exception if the check fails. This results in repetitive boilerplate > code scattered throughout the codebase. A new syntax, `(ClassName) > $variable`, is proposed to streamline this process by performing an > instanceof check and throwing a `TypeError` if the variable is not an > instance of the specified class. > > Proposal > *** > > Introduce a new type guard syntax for classes: > > ```php > (Foo) $variable; > ``` > > This syntax will internally perform the following operations: > > 1. Check if `$variable` is an instance of `Foo`. > 2. If the check fails, throw a `TypeError` with a message indicating the > expected and actual types. > > Example: > Consider the following class definition: > > ```php > class Foo { >// class definition > } > ``` > > To ensure a variable is an instance of `Foo`, instead of writing: > > ```php > if (!$variable instanceof Foo) { > throw new TypeError('Expected instance of Foo, got ' . > gettype($variable)); > } > ``` > > Developers can use the new type guard syntax: > > ```php > (Foo) $variable; > ``` > > Backward Compatibility > *** > > This feature introduces new syntax and does not affect existing code. It > is fully backward-compatible, as it does not modify or deprecate any > existing functionality. > Since this throws, I'm struggling to understand how this would replace any usages of `instanceof` other than `if (!($var instanceof Foo)) throw new TypeError();` Also, this is not an RFC with a page I can look at OR something in a vote, so the subject line is a bit of a lie. But now that I've gotten my grumps out of the way, better class specific syntax is in general something that I think is positive and worth exploring. Jordan
Re: [PHP-DEV] Proposal: Arbitrary precision native scalar type
On Sat, Apr 27, 2024 at 11:04 PM Alexander Pravdin wrote: > > All builtin functions that currently accept float also accept decimal. > So users don't need to care about separate function sets, and PHP > developers don't need to maintain separate sets of functions. If any > of the parameters is decimal, they return decimal. Float parameters > are converted to decimals implicitly according to the conversion rules > mentioned above. > > So, as I mentioned months ago, this is the reason that having actually looked into implementing things like this, I was interested in using a library. Proposing this is fine. But doing a fully custom implementation that includes this? You're going to implement `sin` and `cos` and `atan` for 128-bit decimals? When we could use an open source library that has a compatible license instead and is proven to work for these already instead, likely with better performance as well? This is likely to be more work than doing a type backed by a library while also being less capable. I know that your shift in proposal here is not aimed at me, and also I'm not a voter so in that sense it doesn't matter. But if this is what the proposal ends up being, I'll probably just continue on the research for an actual arbitrary precision implementation based on MPFR instead of helping with this implementation. Jordan
Re: [PHP-DEV] Incorrect terminology usage for rounding modes of round()
On Sun, Apr 14, 2024 at 9:50 AM Tim Düsterhus wrote: > > I don't think it should be in a namespace. The name is sufficiently > unique and clear. Without a broader concept for the namespace, we > probably should not introduce one. > > +1 For this, I don't think a namespace is necessary. Though I will note that "Mathematics" is absolutely an American English term as well as British English, even though "Maths" is not. This will also make it easier for me to do one of the smaller improvements I've been pondering proposing: adding some brand new rounding modes: - Half Alternating - Half Random - Stochastic Jordan
Re: [PHP-DEV] Native decimal scalar support and object types in BcMath - do we want both?
On Mon, Apr 8, 2024 at 12:23 PM Rowan Tommins [IMSoP] wrote: > > As I mentioned in the discussion about a "scalar arbitrary precision > type", the idea of a scalar in this meaning is a non-trivial challenge, as > the zval can only store a value that is treated in this way of 64 bits or > smaller. > > > Fortunately, that's not true. If you think about it, that would rule out > not only arrays, but any string longer than 8 bytes long! > > The way PHP handles this is called "copy-on-write" (COW), where multiple > variables can point to the same zval until one of them needs to write to > it, at which point a copy is transparently created. > > > The pointer for this value would fit in the 64 bits, which is how objects > work, but that's also why objects have different semantics for scope than > integers. Objects are potentially very large in memory, so we refcount them > and pass the pointer into child scopes, instead of copying the value like > is done with integers. > > > Objects are not the only thing that is refcounted. In fact, in PHP 4.x and > 5.x, *every* zval used a refcount and COW approach; changing some types to > be eagerly copied instead was one of the major performance improvements in > the "PHP NG" project which formed the basis of PHP 7.0. You can actually > see this in action here: https://3v4l.org/oPgr4 > > This is all completely transparent to the user, as are a bunch of other > memory/speed optimisations, like interned string literals, packed arrays, > etc. > > So, there may be performance gains if we can squeeze values into the zval > memory, but it doesn't need to affect the semantics of the new type. > I have mentioned before that my understanding of the deeper aspects of how zvals work is very lacking compared to some others, so this is very helpful. I was of course aware that strings and arrays can be larger than 64 bits, but was under the impression that the hashtable structure in part was responsible for those being somewhat different. I confess that I do not understand the technical intricacies of the interned strings and packed arrays, I just understand that the zval structure for these arbitrary precision values would probably be non-trivial, and from what I was able to research and determine that was in part related to the 64bit zval limit. But thank you for the clarity and the added detail, it's always good to learn places where you are mistaken, and this is all extremely helpful to know. This probably relates quite closely to Arvid's point that for a lot of > uses, we don't actually need arbitrary precision, just something that can > represent small-to-medium decimal numbers without the inaccuracies of > binary floating point. That some libraries can be used for both purposes is > not necessarily evidence that we could ever "bless" one for both use cases > and make it a single native type. Honestly, if you need a scale of less than about 15 and simply want FP error free decimals, BCMath is perfectly adequate for that in most of the use cases I described. The larger issue for a lot of these applications is not that they need to calculate 50 digits of accuracy and BCMath is too slow, it's that they need non-arithmetic operations, such as sin(), cos(), exp(), vector multiplication, dot products, etc., while maintaining that low to medium decimal accuracy. libbcmath just doesn't support those things, and creating your own implementation of say the sin() function that maintains arbitrary precision is... challenging. It compounds the performance deficiencies of BCMath exponentially, as you have to break it into many different arithmetic operations. To me, while being 100x to 1000x more performant at arithmetic is certainly reason enough on its own, the fact that MPFR (for example) has C implementations for more complex operations that can be utilized is the real selling point. The ext-stats extension hasn't been maintained since 7.4. And trig is critical for a lot of stats functions. A fairly common use of stats, even in applications you might not expect it, is to generate a Gaussian Random Number. That is, generate a random number where if you continued generating random numbers from the same generator, they would form a normal distribution (a bell curve), so the random number is weighted according to the distribution. The simplest way to do that is with the sin() and cos() functions (picking a point on a circle). But a lot of really useful such mathematics are mainly provided by libraries that ALSO provide arbitrary precision. So for instance, the Gamma Function is another very common function in statistics. To me, implementing a bundled or core type that utilizes MPFR (or something similar) is as much about getting access to THESE mathematical functions as it is the arbitrary precision aspect. Jordan
Re: [PHP-DEV] Native decimal scalar support and object types in BcMath - do we want both?
On Sun, Apr 7, 2024 at 2:45 PM Rowan Tommins [IMSoP] wrote: > On 07/04/2024 20:55, Jordan LeDoux wrote: > > > I have been doing small bits of work, research, and investigation into > > an MPDec or MPFR implementation for years, and I'm likely to continue > > doing my research on that regardless of whatever is discussed in this > > thread. > > > I absolutely encourage you to do that. What I'm hoping is that you can > share some of what you already know now, so that while we're discussing > BCMath\Number, we can think ahead a bit to what other similar APIs we > might build in the future. The below seems to be exactly that. > > > > > Yes. BCMath uses fixed-scale, all the other libraries use > > fixed-precision. That is, the other libraries use a fixed number of > > significant digits, while BCMath uses a fixed number of digits after > > the decimal point. > > > That seems like a significant difference indeed, and one that is > potentially far more important than whether we build an OO wrapper or a > "scalar" one. > > By a "scalar" value I mean a value that has the same semantics for reading, writing, copying, passing-by-value, passing-by-reference, and passing-by-pointer (how objects behave) as the integer, float, or boolean types. As I mentioned in the discussion about a "scalar arbitrary precision type", the idea of a scalar in this meaning is a non-trivial challenge, as the zval can only store a value that is treated in this way of 64 bits or smaller. However, the actual numerical value that is used by every single one of these libraries is not guaranteed to be 64 bits or smaller, and for some of them is in fact guaranteed to be larger. The pointer for this value would fit in the 64 bits, which is how objects work, but that's also why objects have different semantics for scope than integers. Objects are potentially very large in memory, so we refcount them and pass the pointer into child scopes, instead of copying the value like is done with integers. Both this and the precision/scale question are pretty significant design questions and choices. While the arbitrary precision values of these libraries will not fit inside a zval, they are on average smaller than PHP objects in memory, so it may not be a significant problem to eagerly copy them like we do with integers. However, if that is not the route that is taken, they could end up having scoping semantics that are similar to objects, even if we don't give them a full class entry with a constructor, properties, etc. This is part of the reason that, for example, the ext-decimal implementation which uses the MPDec library represents these numbers as an object with a fluent interface. > > > So, for instance, it would not actually be possible without manual > > rounding in the PHP implementation to force exactly 2 decimal digits > > of accuracy in the result and no more with MPDec. > > > The current BCMath proposal is to mostly choose the scale calculations > automatically, and to give precise control of rounding. Neither of those > are implemented in libbcmath, which requires an explicit scale, and > simply truncates the result at that point. > > That's why I said that the proposal isn't really about "an OO wrapper > for BCMath" any more, it's a fairly generic Number API, with libbcmath > as the back-end which we currently have available. So thinking about > what other back-ends we might build with the same or similar wrappers is > useful and relevant. > > In general I would say that libbcmath is different enough from other backends that we should not expect any work on a BCMath implementation to be utilized in other implementations. It *could* be that we are able to do that, but it should not be something people *expect* to happen because of the technical differences. Some of the broader language design choices would be transferable though. For instance, the standard names of various calculation functions/methods are something that would remain independent, even with the differences in the implementation. > > > The idea of money, for instance, wanting exactly two digits would > > require the implementation to round, because something like 0.0013 > > has two digits of *precision*, which is what MPDec uses, but it has 8 > > digits of scale which is what BCMath uses. > > > This brings us back to what the use cases are we're trying to cover with > these wrappers. > > The example of fixed-scale money is not just a small niche that I happen > to know about: brick/money has 16k stars on GitHub, and 18 million > installs on Packagist; moneyphp/money has 4.5k stars and 45 million > installs; one has implementations based on plain PHP, GMP, and BCMath; > the other has a hard dependency on BCMath.
Re: [PHP-DEV] Native decimal scalar support and object types in BcMath - do we want both?
On Sun, Apr 7, 2024 at 8:27 AM Rowan Tommins [IMSoP] wrote: > > > On 7 April 2024 15:38:04 BST, Saki Takamachi wrote: > >> In other words, looking at how the efforts overlap doesn't have to mean > abandoning one of them, it can mean finding how one can benefit the other. > > > >I agree that the essence of the debate is as you say. > >However, an argument must always reach a conclusion based on its purpose, > and combining two arguments with different purposes can make it unclear how > to reach a conclusion. > > Well, that's the original question: are they actually different purposes, > from the point of view of a user? > > I just gave a concrete suggestion, which didn't involve "combining two > arguments", it involved splitting them up into three projects which all > complement each other. > > It feels like both you and Jordan feel the need to defend the work you've > put in so far, which is a shame; as a neutral party, I want to benefit from > *both* of your efforts. It really doesn't matter to me how many mailing > list threads that requires, as long as there aren't two teams making > conflicting designs for the same feature. > > Regards, > Rowan Tommins > [IMSoP] > Eh, my first reply wasn't really about defending anything. It was to inform. I have been doing small bits of work, research, and investigation into an MPDec or MPFR implementation for years, and I'm likely to continue doing my research on that regardless of whatever is discussed in this thread. Rowan, my point wasn't so much that a discussion like this one is pointless, it was that MOST of the people who actually vote on RFCs don't reply at all to internals, so a discussion like this actually does not help anyone understand the opinion of MOST of the people that actually need to be convinced. We hope the discussion is representative of the people who do not engage with it, but we don't know for sure. In any case, an alternative implementation using MPDec/MPFR probably can't be done until 9.0 at the earliest, but Saki's improvements to BCMath are ready to merge now, essentially. > Is there anything in the proposal which would actually be different if it was based on a different library Yes. BCMath uses fixed-scale, all the other libraries use fixed-precision. That is, the other libraries use a fixed number of significant digits, while BCMath uses a fixed number of digits after the decimal point. So, for instance, it would not actually be possible without manual rounding in the PHP implementation to force exactly 2 decimal digits of accuracy in the result and no more with MPDec. The idea of money, for instance, wanting exactly two digits would require the implementation to round, because something like 0.0013 has two digits of *precision*, which is what MPDec uses, but it has 8 digits of scale which is what BCMath uses. Jordan
Re: [PHP-DEV] Native decimal scalar support and object types in BcMath - do we want both?
On Sat, Apr 6, 2024 at 4:07 AM Barney Laurance wrote: > Hello, > > There are currently two proposals being discussed - *native decimal > scalar type support* and *Support object type in BCMath* > > I've been getting involved in the discussion for the BCMath proposal, but > not paying as much attention to the native decimal thread. > > But these seem like very similar things, so I'm wondering whether or not > it makes sense to do both at once. They both seem like ways to represent > and calculate with arbitrary precision decimal numbers. > > I'm not sure if they have distinct use cases. Are there some tasks where > people would likely prefer one, and different tasks where they would prefer > the other? Or should PHP internals choose just one of these options instead > of potentially releasing both? It doesn't seem like a good idea to have two > directly competing features for the same use case in one PHP release, > unless there's a reason to favor each one in a different situation. > > Best wishes, > > Barney > The scalar arbitrary precision discussion is for an implementation that would be in the range of 100x to 1000x faster than BCMath. No matter what improvements are made to BCMath, there will still be strong arguments for it, and until someone actually puts together an RFC, the BCMath library is the only thing around. Internals is just volunteers. The people working on BCMath are doing that because they want to, the people working on scalar decimal stuff are doing that because they want to, and there's no project planning to tell one group to stop. That's not how internals works (to the extent it works). Jordan
Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath
On Sat, Apr 6, 2024 at 6:45 AM Rowan Tommins [IMSoP] wrote: > On 06/04/2024 07:24, Saki Takamachi wrote: > > Take a look at the methods shown below: > ``` > protected static function resultPropertyRules(string $propertyName, > mixed $value1, mixed $value2): mixed {} > ``` > > This method determines which operand value to use in the result after > calculation for a property that the user has defined by extending the > class. > > > While this is an intriguing idea, it only solves a narrow set of use > cases. For instance: > > - The class might want different behaviour for different operations; e.g. > Money(42, 'USD') + Money(42, 'USD') should give Money(84, 'USD'); but > Money(42, 'USD') * Money(42, 'USD') should be an error. > > - Properties might need to interact with each other; e.g. Distance(2, > 'metres') + Distance(2, 'feet') could result in Distance(2.6096, 'metres'); > but if you calculate one property at a time, you'll end up with Distance(4, > 'metres'), which is clearly wrong. > > The fundamental problem is that it ignores the OOP concept of > encapsulation: how an object stores its internal state should not define > its behaviour. Instead, the object should be able to directly define > behaviour for the operations it supports. > > If only there had been a feature that carefully considered how all those things would interact. Oh well. Okay, then please tell me in which use cases inheritance rather than > composition is the right choice? For the "Money" example, I've already > showcased how it would be broken and I can't think of any example where > inheritance would be superior to composition. > > Yes, my example is dumb, but nevertheless it showcased that the native > and unchangeable operations would be unsound for child classes with > custom properties, because the operations would not be able to correctly > fill in the custom properties. > No, like I said, I disagree, but I don't get a vote AND it's not something I would actually vote no over if I could, so it's not something I'm willing to put the effort into in that way. I was voicing my disagreement to make sure it was part of the discussion but I wasn't trying to put the effort into actually changing the design of the RFC, which I understand is a little unsatisfactory to some. As it is, this RFC will be useful to some for sure, but my library will ignore it. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath
On Fri, Apr 5, 2024 at 1:00 PM Tim Düsterhus wrote: > Hi > > On 4/5/24 21:42, Saki Takamachi wrote: > > The only solution I can think of at the moment is to impose the > constraint that > > when computing operator overloading, if the operands are both objects, > they must > > be of the exact same class. > > Even that would allow for confusing behavior: > > class MyNumber extends Number { > private $importantMetadata; > > public function doSomething() { > $this->importantMetadata = random_int(1, 100); > } > } > > $a = new MyNumber(5); > $a->doSomething(); > $b = new MyNumber(10); > $b->doSomething(); > > $what = $a + $b; > > What should be the value of $what->importantMetadata be? The property is > private, so as a user adding two of MyNumber would not even be able to > manually fix it up with the correct value, thus requiring the addition > of a "fixup" method that fixes the internal state of the object, > possibly even lacking the necessary information to properly fix up the > state, because it does not know which operations lead to the state. > > Best regards > Tim Düsterhus > That is an absurd example. Why would anyone use inheritance for that class design? If what you are arguing is "if you look at use cases where composition is clearly the correct choice then inheritance causes problems", then I'm not sure what the point of the discussion is. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath
On Fri, Apr 5, 2024 at 12:42 PM Saki Takamachi wrote: > > The only solution I can think of at the moment is to impose the constraint > that when computing operator overloading, if the operands are both objects, > they must be of the exact same class. > > When calculating using a method, it is clear which object should be > prioritized, so there is no risk of breaking down even if the method > accepts objects of different classes as arguments. It would be possible to > unify the behavior of the methods with operator overloading, but this would > be undesirable because the arguments would be contravariant. > > This is something that there are established solutions for actually. It's called Polymorphic Handler Resolution. This essentially means that when you have two objects used with operators, if they share a parent class or a class structure, the newest descendant is given priority. For example, if you have class A as the parent, then class B and class C as children: A + B = B, because it is a child class of A B + A = B, because it is a child class of A B + C = B, because neither are direct descendants C + B = C, because neither are direct descendants If we add the requirement that they must either be the same class as you suggested, OR one must be a descendant of the other, then we eliminate the B + C issue entirely, which makes sense for a BCMath object. How this would actually be implemented in C is that both operands would be checked for inheritance. If they are different classes and one is not the descendant of the other, it would error. If they are different classes and one IS the descendant of the other, then the handler for the descendant would be called, and that handler would always return an instance of itself. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath
On Fri, Apr 5, 2024 at 2:48 AM Tim Düsterhus wrote: > Hi > > Your `Money` example would allow for unsound and/or non-sense behavior, > such as: > > $fiveEuros = new Money(5, 'EUR'); > $tenDollars = new Money(10, 'EUR'); > > $what = $fiveEuros + $tenDollars; > > What would you expect to be in $what? A `BcMath\Number(15)`? > > > > The BcMath\Number class *should* absolutely be final, as a number is a > number is a number. Allowing extension just to be able to write > $number->isPrime() instead of isPrime($number) will allow for very > confusing code, such as the example above, with no way to work around it > in userland. It also makes interoperability between two different > libraries that expect their own extensions to work very painful. > > Consider the following example: > > class PrimalityTestingNumber extends Number { > public function isPrime(): bool { } > } > > class ParityTestingNumber extends Number { > public function isEven(): bool { } > public function isOdd(): bool { } > } > > If I now want to create a function to check whether a number is an even > prime, I need to do something like this: > > function isEvenPrime(Number $n) { > return (new PrimalityTestingNumber($n))->isPrime() && (new > ParityTestingNumber($n))->isEven(); > } > > This use case would be much better solved in a generic way using > something like this "Extension Methods" proposal: > https://externals.io/message/118395#118395 > > Well, since they are both in Euros, I would expect 15, but I expect that was a typo considering the variable name and it was meant to be 10 USD. As I said, you can accomplish the same through composition. For a money class, you'd likely need an extended method that checks the currency first, and then makes a call to the actual calculation method, which is essentially what the composing class would do as well, something like `addCurrency()`. Frankly, I don't think that making it final actually makes the API more resistant to errors, but it's also not something I care about enough to really fight for it on this RFC. I think it's the wrong choice, because the one example that I pulled up in this discussion does not constitute the entire breadth of use cases for this type of object, and I find myself extremely hesitant to suggest that we have thought of and considered all the various use cases that developers might have, or how they might be impacted by making the entire class final. Making it final will not reduce errors in my opinion, it will just make internals feel like those errors are less "our fault". A composed class does not somehow prevent the accidental error of mixing currencies, it just moves where that error would occur. Forcing composition drastically reduces the usability of the operator overloads, which I am opposed to, and I do not believe that this is being given the same kind of consideration. Once the class is forced to be composed, it can no longer be used as part of any kind of extensions either. I mentioned that I have a library that adds arbitrary precision functions for trigonometric functions (among others), to extend BCMath (and ext-decimal). A library that is solely focused on additional arbitrary precision math features should be the first in line to use this RFC, but I can tell you that if this class is final, I won't even update my library to use it at all, because there will be no point. The reason I did not mention MY use case is because I don't think many PHP developers are out there maintaining their own complicated trigonometric extensions to BCMath, so I don't think it's a good example of a common use case. Making it final also breaks with how other internally provided classes have been done in the past, many with no discernable issues. I do not see any mailing list discussions about the problems with DateTime being open for extension. If you want an actual answer about how a Money class would actually work in practice, it would likely be something like this: ``` // $val1 and $val2 are instances of the Money class with unknown currencies $val1Currency = $val1->getCurrency(); $val2Currency = $val2->getCurrency(); $val1 = $val1->convertToCommonCurrency(); $val2 = $val2->convertToCommonCurrency(); // perform the necessary calculations using operators $answer = $answer->convertToCurrency($userCurrency); ``` I would expect that most applications dealing with money are converting to a common calculation currency prior to actually doing any calculations, instead of relying on the conversion magically happening inside their calculation methods. So, your argument leaves me entirely unmoved. However, as I said, while this makes the RFC essentially useless to me, I don't think it's worth rejecting the RFC over, so I'll leave it at that. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath
On Thu, Apr 4, 2024 at 2:19 PM Barney Laurance wrote: > > I don't think it will be possible to make a good Money class as a child of > this. BcNum is a read-only class, so if the constructor of BcNum is final > then the child class won't be able to take the currency as a constructor > param, and won't be able to protect the invariant that currency must be > initialized. If the constructor of BcNum were made non-final then BcNum > wouldn't be able to protect the invariant of the numeric value always being > initialized once the constructor has returned. And it should be > straightforward to make a good money class as a composition of BcNum and a > currency enum or string. > > The RFC does not list the constructor as final, and I would not expect it to. > There's probably not any good use case for a subclass to add properties, > unless perhaps the subclass developers are willing do do away with some of > the checks that would normally be done on a value object by the PHP runtime > to keep it valid (maybe replacing them with static analysis checks). But > there are lots of reasonable use cases for subclasses to add methods, even > if they're effectively syntax sugar for static methods with a BcNum typed > param. > > I literally just provided in the quote you are replying to a good use case for a subclass. You can do the same thing with composition yeah, and that might even be better to a lot of people, but I don't think this RFC should take a position AGAINST subclasses and in favor of composition. > Having just written that I've now checked the behavior of DateTime - see > https://3v4l.org/5DQZg . The constructor of that isn't final, so a child > class can replace it with an empty constructor. But if it does that and > leaves the value uninitialized then it blows up on a call to `format`. > That's probably not something we should emulate. DateTimeImmutable behaves > the same way. > Why not? Writing something like that obviously does not work, and the error would be immediately apparent. Is it possible to create something that will error? Of course. That's not an error that needs to be aggressively guarded against, because the feedback is rapid and obvious. Jordan
Re: [PHP-DEV] Proposal: Arbitrary precision native scalar type
On Thu, Apr 4, 2024 at 2:28 PM Rowan Tommins [IMSoP] wrote: > > > I haven't followed the discussion in the other thread, but I'm not sure > what the use case would be for a "fixed scale decimal" that followed > those rules. > > As mentioned before, the use case I've encountered is money > calculations, where what people want to fix is the smallest unit of > account - e.g. €0.01 for practical currency, or €0.0001 for detailed > accounting / trading. > > If I write $total = 1.03_d2; $perPerson = $total / 2; I want a result of > 0.51_d2 or 0.52_d2 - that's why I specified a scale of 2 in the first > place. > Well, firstly most of the financial applications that I've worked in (I work for a firm that writes accounting software right now) do not calculate intermediate steps like this with fixed precision, or even have an interest in doing so. They generally want maximum precision that is computationally reasonable, and then round it according to their preferred method at the end. Doing the calculations as you are suggesting would introduce a maximum error of several cents/pence/etc. after only two or three calculations, which is utterly useless for most applications that deal with money. Truly "fixed-precision" is not something that decimal should even try to be, in my opinion. The use cases where you CANNOT simply round the result at the end to fit your display output or your storage location are very minimal. > If I want an accurate result of 0.515_d3, I would just specify 1.03_d, > since the scale hasn't had any effect on the result. > > If I want a lossless split into [0.51_d2, 0.52_d2] I still need a > function to exist somewhere, whether you spell that $total->split(2), or > decimal_split($total, 2), etc. So it seems safer to also have > $total->div(2, Round::DOWN) or decimal_div($total, 2, Round::DOWN) and > have $total / 2 give an error. > I mean, what you are describing is how such OBJECTS are designed in other languages like Python, but not scalars. Python also has (almost completely unrestricted) userland operator overloading, which PHP does not, which further makes the comparison a little murky. This kind of precision restriction isn't something you would place on an individual value, it's something you would place on all calculations. That's why in Python this is done with a global runtime setting using `getContext().perc` and `getContext().rounding`. A particular value having a precision of X doesn't imply anything concrete about a calculation that uses that value necessarily. > Possibly, it could only error if the result doesn't fit in the scale, so > that this would be fine: $total = 11.00_d2; $perPerson = $total / 2; > assert($perPerson === 5.50_d2) > > Or possibly, it would just be an error to perform division on a fixed > scale decimal, but allowed on a variable-fixed scale decimal. > Maybe we're just not understanding each other. Are you opposed to the idea of doing this as a scalar? It certainly feels that way. This feels more like an argument in favor of doing object-like numerics for this. I suppose that isn't really that strange either, because as I noted such a value will almost certainly need to be refcounted because it will not fit into the 64 bits available for a zval no matter what underlying library is used to perform the math. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath
On Thu, Apr 4, 2024 at 1:59 PM Barney Laurance wrote: > Hi again, > > On 27/03/2024 00:40, Saki Takamachi wrote: > > Do we also need `toFloat` and `toInt` functions? Seems like using explicit > functions will be safer than casting. > > For toInt I'd expect an exception if the value is outside the range of > possible ints. For toFloat it might be nice to have a flag > argument to give the developer the choice of having it throw if the value is > outside the range of floats or return INF or -INF, > or possibly the user should just check for infinite values themselves. > > I was thinking about those features too. However, I'm concerned that > proposing too many features will complicate the RFC and make it difficult to > get it approved. > > Coming back to this point, I think these are basic features that people > would expect to be there - I think I would find just slightly frustrating > to start learning how to use a class like this and then > find that it doesn't have these functions. Casting and calling `intval` or > `floatval` all feel like slightly awkward workarounds that shouldn't be > needed in a greenfield project. We know that the string > inside the object is always a numeric string, so it should be easier to > parse it as an int than to parse it as a date or a JSON document. Code > doing the latter should stand out as odd looking. > > > The class cannot guarantee that it can return a value in the type you request however, so the way that is handled would need to be decided. The value can easily be outside of the range of an int. Should it return a float silently in that case for `toInt()`? What if the value is beyond the range of a float? That would be a very rare situation, as floats can represent extremely large numbers (with very reduced accuracy), but I would expect it to throw an exception if that happened. Ideally an exception that I could catch and ignore, since I can almost surely deal with that error in most situations. What about a number that is so small that it can't fit in a float? Similar situation, though I expect it would occur slightly more often than a number being too large to fit in a float, even though it would also be rare. I think these helper functions belong in the RFC, but they aren't quite straightforward, which is what I think Saki was alluding to. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath
On Wed, Apr 3, 2024 at 7:31 PM Saki Takamachi wrote: > > Thanks, I agree with you that it works a little differently than the > existing BCMath function, so it needs to be well-documented. > > I have summarized the discussion so far, made some corrections, and > updated the RFC. I would be happy if you could check it out. > It looks pretty good. It should probably give specific guidelines on how "no scale provided" works for addition, subtraction, multiplication, division, and exponentiation. The section now doesn't make it clear that the returned scale will behave differently for addition (the current example) than for division. Jordan
Re: [PHP-DEV] Proposal: Arbitrary precision native scalar type
On Mon, Mar 18, 2024 at 1:35 PM Rowan Tommins [IMSoP] wrote: > > Where things get more complicated is with *fixed-precision* decimals, > which is what is generally wanted for something like money. What is the > correct result of decimal(1.03, precision: 2) / 2 - decimal(0.515, 3)? > decimal(0.51, 2)? decimal (0.52, 2)? an error? And what about decimal(10) / > 3? > > If you stick to functions / methods, this is slightly less of an issue, > because you can have decimal(1.03, 2)->dividedBy(2, RoundingMode::DOWN) == > decimal(0.51, 2); or decimal(1.03, 2)->split(2) == [ decimal(0.52, 2), > decimal(0.51, 2) ] Example names taken directly from the brick/money > package. > > At that point, backwards compatibility is less of an issue as well: make > the new functions convenient to use, but distinct from the existing ones > I came back to this discussion after my last reply on the BCMath as an object thread, because we went through a very similar discussion there with regard to operators. I think that, roughly, the fixed precision should be defined on the scalar itself: 1.234_d3 1.234 is the value, _d makes it a decimal type, and 3 shows that this value has a precision of 3. (Actually, it has a SCALE of 3, since precision is significant digits, and also includes the integer portion). But when it comes to fixed-precision values, it should follow rules very similar to those we discussed in the BCMath thread: - Addition and subtraction should return a value that is the largest scale/precision of any operands in the calculation. - Division and multiplication should return a value that is the sum of the scale/precision of any operands + 2 or a default (perhaps configurable) value if the sum is small, to ensure that rounding occurs correctly. Near zero, floats have about 12-ish decimal digits of accuracy, and will return their full accuracy for example. - Pow is extremely difficult to work with if you allow a decimal in the exponent. The libraries we have discussed previously handle this difficulty, but the precision needed often depends on what the calculation is for, so I'm not entirely sure what the best way to handle this with operators would be. Minimally, probably the same as division and multiplication. But if we have scalar decimal types, we need something like that _d12 to denote a decimal scalar with a scale/precision of 12. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath
On Tue, Apr 2, 2024 at 5:43 PM Saki Takamachi wrote: > > If make a class final, users will not be able to add arbitrary methods, so > I think making each method final. Although it is possible to completely > separate behavior between method and opcode calculations, this is > inconsistent and confusing to users and should be avoided. > Right, if a class is not final but has only final methods (including > constructor) and no protected properties then it allows people to extend it > but not break any encapsulation or (I think) impose any more BC > requirements on the maintainer (unless we care about conflicting with > method names of child classes when updating). It lets people just do > something a bit like adding 'extension methods' in C#. I like it. People > could write e.g. `$bcChildNumber->isPrime()` instead of > `BcNumberUtils::isPrime($bcNumber)` Yeah, I suspect the most common child class will be something like "Money" that additionally has a parameter denoting what currency the value is in, since that is by far the most common use case for arbitrary precision math in PHP. Making the calculation methods final should do fine in my opinion. > How about setting the `$scale` and `$roundMode` that I mentioned earlier > in the constructor instead of `div` and `pow`? By doing so, we can use any > scale when calculating with opcodes. If we want to specify a different > scale for each calculation, you can do it using methods. > Or would it be more convenient to have a method to reset `$scale` and > `$roundMode`? It is immutable, so when reset it returns a new instance. > I think that having it be an optional part of the constructor and having a method to modify it is probably sufficient to help with operator overloads. Importantly, it still needs to take that setting and use it intelligently depending on the operation as we've discussed, but that should cover the use cases I was imagining. The exact behavior should be very clearly documented and explained though, as this is a different way of interacting with BCMath than the functions. It's better I think, because it takes advantage of the fact that this will be state-aware, which the functions aren't, and is one of the largest benefits of using objects. Also, to address an earlier question you had Saki, the term used should be "scale". Scale is the total number of digits to the right of the decimal point. Precision is the total number of significant digits. The BCMath C library works on scale, I believe, so that should carry over here. Most other arbitrary precision libraries in C use precision. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath
On Tue, Apr 2, 2024 at 5:05 PM Jordan LeDoux wrote: > > > On Tue, Apr 2, 2024 at 4:50 PM Saki Takamachi 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 optionally >> 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 = 2 + 2 = 4`. >> - `$roundMode`: Specifies the rounding method when the result does not >> fit within the scale. The initial value is `PHP_ROUND_TOWARD_ZERO`, which >> 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 `20` >> for scale. >> - The result of a calculation with operator overloading is the same as if >> 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 this, >> 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 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 arguments 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 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 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 you outlined above > gets murky. I think what you outlined is very close to a good final design > for just the method usage side, but the operator usage side CANNOT provide > 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
Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath
On Tue, Apr 2, 2024 at 4:50 PM Saki Takamachi 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 optionally > 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 = 2 + 2 = 4`. > - `$roundMode`: Specifies the rounding method when the result does not fit > within the scale. The initial value is `PHP_ROUND_TOWARD_ZERO`, which > 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 `20` > for scale. > - The result of a calculation with operator overloading is the same as if > 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 this, > 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 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 arguments 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 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 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 you outlined above gets murky. I think what you outlined is very close to a good final design for just the method usage side, but the operator usage side CANNOT provide 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
Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath
On Tue, Apr 2, 2024 at 10:24 AM Jordan LeDoux wrote: > > > On Tue, Apr 2, 2024 at 3:12 AM Lynn wrote: > >> >> I'm inexperienced when it comes to maths and the precision here, but I do >> have some experience when it comes to what the business I work for wants. >> I've implemented BCMath in a couple of places where this kind of precision >> is necessary, and I found that whenever I do divisions I prefer having at >> least 2 extra digits. Would it make sense to internally always just store a >> more accurate number? For things like >> additions/multiplications/subtractions it could always use the highest >> precision, and then for divisions add like +3~6 or something. Whenever you >> have numbers that have a fraction like `10.5001` it makes sense to set it >> to 4, but when you have `10` it suddenly becomes 0 when implicitly setting >> it. >> >> For the following examples assume each number is a BcNum: >> When doing something like `10 * 10. * 10.0` I want the end >> result to have a precision of at least 9 so I don't lose information. When >> I do `((10 / 3) * 100) * 2` I don't want it to implicitly become 0, because >> the precision here is important to me. I don't think using infinite >> precision here is a reasonable approach either. I'm not sure what the >> correct answer is, perhaps it's just "always manually set the precision"? >> > > In my library, if the scale is unspecified, I actually set the scale to 10 > OR the length of the input string, including integer decimals, whichever is > larger. Since I was designing my own library I could do things like that as > convention, and a scale of 10 is extremely fast, even with the horrifically > slow BCMath library, but covers most use cases (the overwhelmingly common > of which is exact calculation of money). > > My library handles scale using the following design. It's not necessarily > correct here, as I was designing a PHP library instead of something for > core, AND my library does not have to deal with operator overloads so I'm > always working with method signatures instead, AND it's possible that my > class/method design is inferior to other alternatives, however it went: > > 1. Each number constructor allowed for an optional input scale. > 2. The input number was converted into the proper formatting from allowed > input types, and then the implicit scale is set to the total number of > digits. > 3. If the input scale was provided, the determined scale is set to that > value. > 4. Otherwise, the determined scale at construction is set to 10 or the > implicit scale of "number of digits", whichever is larger. > 5. The class contained the `roundToScale` method, which allowed you to > provide the desired scale and the rounding method, and then would set the > determined scale to that value after rounding. It contained the `round` > method with the same parameters to allow rounding to a specific scale > without also setting the internal determined scale at the same time. > 6. The class contained the `setScale` method which set the value of the > internal determined scale value to an int without mutating the value at all. > 7. All mathematical operation methods which depended on scale, (such as > div or pow), allowed an optional input scale that would be used for > calculation if present. If it was not present, the internal calculations > were done by taking the higher of the determined scale between the two > operands, and then adding 2, and then the result was done by rounding using > the default method of ROUND_HALF_EVEN if no rounding method was provided. > > Again, though I have spent a lot of design time on this issue for the math > library I developed, my library did not have to deal with the RFC process > for PHP or maintain consistency with the conventions of PHP core, only with > the conventions it set for itself. However, I can provide a link to the > library for reference on the issue if that would be helpful for people that > are contributing to the design aspects of this RFC. > > > The current assumption is that a Number always holds a single value. How > if we made it so that it held two values? They are the numerator and the > denominator. > > Again, my experience on the issue is with the development of my own > library on the issue, however in my case I fully separated that kind of > object into its own class `Fraction`, and gave the kinds of operations > we've been discussing to the class `Decimal`. Storing numerators and > denominators for as long as possible involves a completely different set of > math. For instance, you need an algorithm to determine the Greatest Common > Factor and the Least Common
Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath
On Tue, Apr 2, 2024 at 3:12 AM Lynn wrote: > > I'm inexperienced when it comes to maths and the precision here, but I do > have some experience when it comes to what the business I work for wants. > I've implemented BCMath in a couple of places where this kind of precision > is necessary, and I found that whenever I do divisions I prefer having at > least 2 extra digits. Would it make sense to internally always just store a > more accurate number? For things like > additions/multiplications/subtractions it could always use the highest > precision, and then for divisions add like +3~6 or something. Whenever you > have numbers that have a fraction like `10.5001` it makes sense to set it > to 4, but when you have `10` it suddenly becomes 0 when implicitly setting > it. > > For the following examples assume each number is a BcNum: > When doing something like `10 * 10. * 10.0` I want the end > result to have a precision of at least 9 so I don't lose information. When > I do `((10 / 3) * 100) * 2` I don't want it to implicitly become 0, because > the precision here is important to me. I don't think using infinite > precision here is a reasonable approach either. I'm not sure what the > correct answer is, perhaps it's just "always manually set the precision"? > In my library, if the scale is unspecified, I actually set the scale to 10 OR the length of the input string, including integer decimals, whichever is larger. Since I was designing my own library I could do things like that as convention, and a scale of 10 is extremely fast, even with the horrifically slow BCMath library, but covers most use cases (the overwhelmingly common of which is exact calculation of money). My library handles scale using the following design. It's not necessarily correct here, as I was designing a PHP library instead of something for core, AND my library does not have to deal with operator overloads so I'm always working with method signatures instead, AND it's possible that my class/method design is inferior to other alternatives, however it went: 1. Each number constructor allowed for an optional input scale. 2. The input number was converted into the proper formatting from allowed input types, and then the implicit scale is set to the total number of digits. 3. If the input scale was provided, the determined scale is set to that value. 4. Otherwise, the determined scale at construction is set to 10 or the implicit scale of "number of digits", whichever is larger. 5. The class contained the `roundToScale` method, which allowed you to provide the desired scale and the rounding method, and then would set the determined scale to that value after rounding. It contained the `round` method with the same parameters to allow rounding to a specific scale without also setting the internal determined scale at the same time. 6. The class contained the `setScale` method which set the value of the internal determined scale value to an int without mutating the value at all. 7. All mathematical operation methods which depended on scale, (such as div or pow), allowed an optional input scale that would be used for calculation if present. If it was not present, the internal calculations were done by taking the higher of the determined scale between the two operands, and then adding 2, and then the result was done by rounding using the default method of ROUND_HALF_EVEN if no rounding method was provided. Again, though I have spent a lot of design time on this issue for the math library I developed, my library did not have to deal with the RFC process for PHP or maintain consistency with the conventions of PHP core, only with the conventions it set for itself. However, I can provide a link to the library for reference on the issue if that would be helpful for people that are contributing to the design aspects of this RFC. > The current assumption is that a Number always holds a single value. How if we made it so that it held two values? They are the numerator and the denominator. Again, my experience on the issue is with the development of my own library on the issue, however in my case I fully separated that kind of object into its own class `Fraction`, and gave the kinds of operations we've been discussing to the class `Decimal`. Storing numerators and denominators for as long as possible involves a completely different set of math. For instance, you need an algorithm to determine the Greatest Common Factor and the Least Common Multiple in such a class, because there are a lot of places where you would need to find the smallest common denominator or simplify the fraction. Abstracting between the `Fraction` and `Decimal` so that they worked with each other honestly introduced the most complex and inscrutable code in my entire library, so unless fractions are themselves also a design goal of this RFC, I would recommend against it. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath
On Sat, Mar 30, 2024 at 5:09 PM Saki Takamachi wrote: > Hi Jordan, > > Your opinion may be reasonable given the original BCMath calculation > order. That is, do you intend code like this? > > Signature: > ``` > // public function __construct(string|int $number) > // public function getNumber(?int $scale = null): string > ``` > > Add: > ``` > // public function add(Number|string|int $number): string > > $num = new Number('1.23456'); > $num2 = new Number('1.23'); > > $add = $num + $num2; > $add->getNumber(); // '2.46456' > $add->getNumber(1); // ‘2.4' > > $add = $num->add($num2); > $add->getNumber(); // '2.46456' > $add->getNumber(1); // '2.4' > ``` > > Div: > ``` > // public function div(Number|string|int $number, int $scaleExpansionLimit > = 10): string > > > // case 1 > $num = new Number('0.0001'); > $num2 = new Number('3'); > > $div = $num / $num2; // scale expansion limit is always 10 > $div->getNumber(); // '0.3' > > $div = $num->div($num2, 20); > $div->getNumber(); // '0.333' > $div->getNumber(7); // ‘0.333' > > > // case 2 > $num = new Number('1.11'); > $num2 = new Number('3'); > > $div = $num->div($num2, 3); > $div->getNumber(); // '0.370' > $div->getNumber(7); // ‘0.370' > ``` > > Since the scale can be inferred for everything other than div, a special > argument is given only for div. > > Regards. > > Saki Something like the signature for `getNumber()` in this example would be a decent solution. Operations which have ambiguous scale (of which truly only div is in the BCMath library) should *require* scale in the method that calls the calculation, however for consistency I can certainly see the argument for requiring it for all calculation methods. The issue is how you want to handle that for operator overloads, since you cannot provide arguments in that situation. Probably the most sensible way (and I think the way I handled it as well in my library) is to look at both the left and right operand, grab the calculated scale of the input for both (or the set scale if the scale has been manually set), and then calculate with a higher scale. If internally it produces a rounded result, the calculation should be done at `$desireScale + 2` to avoid compound rounding errors from the BCMath library and then the implementation. If the result is truncated, the calculation should be done at `$desiredScale + 1` to avoid calculating unnecessary digits. So we have multiple usage scenarios and the behavior needs to remain consistent no matter which usage occurs, and what order the items are called in, so long as the resulting calculation is the same. **Method Call** $bcNum = new Number('1.0394567'); // Input scale is implicitly 7 $bcNum->div('1.2534', 3); // Resulting scale is 3 $bcNum->div('1.2534'); // Implicit scale of denominator is 4, Implicit scale of numerator is 7, calculate with scale of 8 then truncate **Operators** $bcNum = new Number('1.0394567'); // Input scale is implicitly 7 $bcNum / '1.2534'; // Implicit scale of denominator is 4, Implicit scale of numerator is 7, calculate with scale of 8 then truncate This allows you to perhaps keep an input scale in the constructor and also maintain consistency across various calculations. But whatever the behavior is, it should be mathematically sound, consistent across different syntax for the same calculation, and never reducing scale UNLESS it is told to do so in the calculation step OR during the value retrieval. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath
On Wed, Mar 27, 2024 at 12:08 AM Aleksander Machniak wrote: > On 27.03.2024 01:03, Saki Takamachi wrote: > >> $num = new BcNum('1.23', 2); > >> $result = $num + '1.23456'; > >> $result->value; // '2.46456' > >> $result->scale; // ?? > > > > In this case, `$result->scale` will be `'5'`. I added this to the RFC. > > I'm not sure I like this. Maybe we should be more strict here and treat > the $scale in constructor (and later withScale()) as the actual scale > for all operations. > > For addition, it absolutely should expand scale like this, unless the constructor also defines a default rounding type that is used in that situation. All numbers, while arbitrary, will be finite, so addition will always be exact and known based on inputs prior to calculation. Treating scale like this isn't more strict, it's confusing. For instance: ``` $numA = new Number('1.23', 2); $numB = new Number('1.23456', 5); $expandedScale1 = $numA + $numB; // 2.46456 $expandedScale2 = $numB + $numA; // 2.46456 $strictScale1 = $numA + $numB; // 2.46 assuming truncation $strictScale2 = $numB + $numA; // 2.46456 ``` I ran into this same issue with operand ordering when I was writing my operator overload RFC. There are ways you could do the overload implementation that would get around this for object + object operations, but it's also mathematically unsound and probably unexpected for anyone who is going to the trouble of using an arbitrary precision library. Addition and subtraction should automatically use the largest scale from all operands. Division and multiplication should require a specified scale. Because of this, I'm not entirely sure that specifying a scale in the constructor is actually a good thing. It is incredibly easy to create situations, unless the implementation in C is VERY careful, where the operand positions matter beyond the simple calculation. Multiplication is commutative, but division is not. This would almost certainly lead to some very difficult to track down bugs. Putting scale in the constructor is similar to some of the examples of "possible misuse cases of operator overloading" that I had to go over when I was making my RFC. We definitely want to avoid that if possible for the first number/math object that has operator overloads. Jordan
Re: [PHP-DEV] Supporting object types in BCMath
On Sun, Mar 17, 2024 at 5:05 PM Saki Takamachi wrote: > Hi Jordan, > > > Using a BCNum inside a loop is the use case, where every loop would > result in memory allocation for a new object, as well as the overhead of > the constructor, etc. > > > > Granted, only people who REALLY know what they are doing should be doing > this. Though my library which essentially IS a wrapped for BCMath that is > upgradeable if you install other extensions (like ext-decimal) does support > both, I suggest using primarily immutables in my docs. > > > > That said, the C library itself for BCMath is insanely inefficient as > far as arbitrary precision math goes, so I would suggest that people don't > get their hopes up too much on the performance front. > > I just sent an email, and you're right about performance. Therefore, the > point of this proposal seems to be simply to improve convenience. > > Regards. > > Saki I've done a lot of performance tuning on my arbitrary precision library, and will simply state for everyone here that I think the amount of development effort involved in improving performance of the BCMath library is almost certainly going to see a return on your effort that is not worth it. There have been discussions over the last year on possibly working on bundling a new arbitrary precision C library and providing something that is performant enough to be generally useful in core, but that's not even at the RFC stage, just investigations. I wouldn't say that improving BCMath is a waste of time, but there is also probably lower hanging fruit once you get past things like Saki has here. DevEx improvements. Jordan
Re: [PHP-DEV] Supporting object types in BCMath
On Sat, Mar 16, 2024 at 8:39 AM Saki Takamachi wrote: > Hi Barney, > > Thanks, that's what I was starting to worry about too. It seems like a > good idea to support only immutability, as you say earlier in your proposal. > > Regards. > > Saki Using a BCNum inside a loop is the use case, where every loop would result in memory allocation for a new object, as well as the overhead of the constructor, etc. Granted, only people who REALLY know what they are doing should be doing this. Though my library which essentially IS a wrapped for BCMath that is upgradeable if you install other extensions (like ext-decimal) does support both, I suggest using primarily immutables in my docs. That said, the C library itself for BCMath is insanely inefficient as far as arbitrary precision math goes, so I would suggest that people don't get their hopes up too much on the performance front. Jordan
Re: [PHP-DEV] Feature request: https://github.com/php/php-src/issues/13301
On Tue, Feb 6, 2024 at 11:19 AM Arvids Godjuks wrote: > On Tue, 6 Feb 2024 at 19:14, Larry Garfield > wrote: > > Thank you Larry for this interesting summary - didn't remember there was > quite a bit a discussion around the topic prior. > > I lean on the "we have exceptions, just leave it be" side out of practical > reasons - the vast majority of OO code has standardized around the approach > and interoperability is high. It makes using code that's out there super > easy and predictable - almost nobody uses the "return false|0|-1" out there > (at least I haven't used code like that except the PHP's stdlib, and even > that has been changing little by little). It makes error handling > predictable, and considering the type of code we mostly write in PHP - most > of the time we leave the catching to the global top-level handler or > sentry/bugsnag/etc libraries. > Consistency is the word I want to highlight here. For better or for worse - > it's the method the PHP ecosystem arrived at and it's the predominant one. > Introducing a distinctly different method of error handling is going to > bring in wrappers around libraries that convert errors to one style or the > other, the application code can end up using different ways of error > handling, etc, etc. My approach is to grab a different language aka "the > right tool for the job" if I want to build things differently, that's why > we have so many programming languages and not just a few :) > > I'd put resources into optimising the VM and php engine to handle the > exceptions better and if there are improvements to be had there - do those > maybe? (I suspect JIT is also going to influence this a lot going forward). > > Sincerely, > Arvīds Godjuks > When what you have is a situation where a function or block of code goes "I know something fixable went wrong, but only the block above me in the execution stack knows what to do about it", Exceptions are extremely overkill. But they are the only "sane" option in PHP in a lot of situations. PHP simply doesn't have a language level structure to handle this VERY COMMON situation. The fact that people have standardized on Exceptions for this is not a point in favor of Exceptions. It is a sign of how much extra performance and semantic correctness we COULD provide to the language by improving this area of error handling. I don't know if the OP of this email thread was referring to this situation. It was honestly very difficult for me to follow what they were even asking for given the language barrier. But I am 1000% behind the problem space that Larry is describing. Exceptions are not a solution to that problem, they are duct tape. Jordan
Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs
On Mon, Dec 25, 2023 at 8:19 AM Kévin Dunglas wrote: > > On Sun, Dec 24, 2023 at 10:44 PM Jordan LeDoux > wrote: > >> >> >> On Sat, Dec 23, 2023 at 12:34 PM Kévin Dunglas wrote: >> >>> Hello and Merry Christmas! >>> >>> One of the main features of FrankenPHP is its worker mode, which lets you >>> keep a PHP application in memory to handle multiple HTTP requests. >>> >>> Worker modes are becoming increasingly popular in the PHP world. Symfony >>> (Runtime Component), Laravel (Octane), and many projects based on these >>> frameworks (API Platform, Sulu...) now support a worker mode. >>> >>> In addition to FrankenPHP, projects such as RoadRunner and Swoole provide >>> engines supporting worker modes. >>> >>> According to benchmarks, worker modes can improve the performance of PHP >>> applications by up to 15 times. >>> In addition to FrankenPHP, which is basically a SAPI for Go's integrated >>> web server, a new generation of SAPIs is currently under development. >>> Several SAPIs written in Rust (including one by the RoadRunner team) are >>> currently under development. >>> >>> These SAPIs, along with existing SAPIs, could benefit from a shared >>> infrastructure to build worker modes. >>> >>> >>> >>> The FrankenPHP code is written and should be easy to move around in PHP >>> itself, to enable other SAPIs to use it. >>> >>> In addition to sharing code, maintenance, performance optimization, etc., >>> the existence of a common infrastructure would standardize the way worker >>> scripts are created and provide a high-level PHP API for writing worker >>> scripts that work with all SAPIs that rely on this new feature. >>> >>> SAPIs will still have to handle fetching requests from the web server and >>> pausing the worker to wait for new requests (in FrankenPHP, we use >>> GoRoutines for this, in Rust or C, other primitives will have to be >>> used), >>> but almost everything else could be shared. >>> >>> For reference, here's the FrankenPHP code I propose to integrate into >>> libphp: >>> https://github.com/dunglas/frankenphp/blob/main/frankenphp.c#L245 >>> >>> The public API is documented here: >>> https://frankenphp.dev/docs/worker/#custom-apps >>> >>> I'd like to hear what the community thinks about this. Would you be >>> interested in this functionality in PHP? Should I work on an RFC? >>> >>> If there's interest, I can work on a patch. >>> >>> Cheers, >>> -- >>> Kévin Dunglas >>> >> >> Much like Larry, I'm curious what sort of scope you imagine for this. Are >> you imagining something that is geared specifically towards HTTP requests, >> or would this be a more generic "PHP Application Worker" that might be >> spawned to handle other types of applications? Could we have a worker >> listen to a specific port and respond to or handle all requests on that >> port/device? >> >> Jordan >> > > Ho Jordan, > > Yes, the scope I imagine is geared specifically towards HTTP requests. > Something more generic than common primitives for SAPIs and a shared public > API to handle HTTP requests with a long-running PHP worker script will be > hard to do outside of SAPIs because they depend on a lot of external > concerns such as the programming language the SAPI is using. > So you want to introduce a SAPI that doesn't work with any of the existing HTTP solutions people use that only supports HTTP requests? Or am I misunderstanding something? This sounds a bit like you want to merge in a tool that is designed for your personal product directly into core. FrankenPHP may be incredible and awesome, but the world runs on Apache and Nginx for HTTP requests. Jordan
Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs
On Sat, Dec 23, 2023 at 12:34 PM Kévin Dunglas wrote: > Hello and Merry Christmas! > > One of the main features of FrankenPHP is its worker mode, which lets you > keep a PHP application in memory to handle multiple HTTP requests. > > Worker modes are becoming increasingly popular in the PHP world. Symfony > (Runtime Component), Laravel (Octane), and many projects based on these > frameworks (API Platform, Sulu...) now support a worker mode. > > In addition to FrankenPHP, projects such as RoadRunner and Swoole provide > engines supporting worker modes. > > According to benchmarks, worker modes can improve the performance of PHP > applications by up to 15 times. > In addition to FrankenPHP, which is basically a SAPI for Go's integrated > web server, a new generation of SAPIs is currently under development. > Several SAPIs written in Rust (including one by the RoadRunner team) are > currently under development. > > These SAPIs, along with existing SAPIs, could benefit from a shared > infrastructure to build worker modes. > > > > The FrankenPHP code is written and should be easy to move around in PHP > itself, to enable other SAPIs to use it. > > In addition to sharing code, maintenance, performance optimization, etc., > the existence of a common infrastructure would standardize the way worker > scripts are created and provide a high-level PHP API for writing worker > scripts that work with all SAPIs that rely on this new feature. > > SAPIs will still have to handle fetching requests from the web server and > pausing the worker to wait for new requests (in FrankenPHP, we use > GoRoutines for this, in Rust or C, other primitives will have to be used), > but almost everything else could be shared. > > For reference, here's the FrankenPHP code I propose to integrate into > libphp: https://github.com/dunglas/frankenphp/blob/main/frankenphp.c#L245 > > The public API is documented here: > https://frankenphp.dev/docs/worker/#custom-apps > > I'd like to hear what the community thinks about this. Would you be > interested in this functionality in PHP? Should I work on an RFC? > > If there's interest, I can work on a patch. > > Cheers, > -- > Kévin Dunglas > Much like Larry, I'm curious what sort of scope you imagine for this. Are you imagining something that is geared specifically towards HTTP requests, or would this be a more generic "PHP Application Worker" that might be spawned to handle other types of applications? Could we have a worker listen to a specific port and respond to or handle all requests on that port/device? Jordan
Re: [PHP-DEV] Proposal: Arbitrary precision native scalar type
On Fri, Dec 15, 2023 at 12:59 PM Arvids Godjuks wrote: > > > On Fri, 15 Dec 2023 at 22:32, Jordan LeDoux > wrote: > >> On Fri, Dec 15, 2023 at 12:14 AM Robert Landers > > >> wrote: >> >> > >> > nobody will likely ever try this again, at least in the foreseeable >> > future. With comments like that, there is simply no way forward. >> > There's no convincing (at least via email) and by that point, it's too >> > late anyway, they already voted but didn't even show up for the >> > discussion that happened for weeks. Literally wasting everyone's time. >> > The only way we'd ever get something like this passed is if someone >> > proposes an RFC that prevents people from voting based on >> > political/personal reasons and restricts voting "no" to technical >> > reasons only; or some voters reopen one of the original RFC's for a >> > revote and leave it in the "Pending Implementation" section as needing >> > an implementation. >> > >> > The fact that people can and do vote "no" for no other reason than >> > they "don't like it" or they "don't want to use it" leaves a bad taste >> > in my mouth. >> > >> >> Okay, so I'm probably the most affected by this, considering we're >> discussing my proposal which was declined and I spent over 400 hours of >> work on it prior to the vote. So please understand where I'm coming from >> when I say this: I firmly believe that people should be allowed to vote no >> on an RFC simply because they feel that it "doesn't belong in PHP". That >> is >> a voter taking a position on what the language is for, how it should be >> designed from a more broad perspective, and I think it's important to have >> that in order to maintain a productive language that does its job well. >> >> The main issue I have discovered through this experience is that some >> people have difficulty or lack the experience necessary to separate an >> opinion about the language design philosophy from what would be personally >> useful to *them*. That is a problem, but it's a problem that is just part >> of working collaboratively with humans. It's not unique to this group, to >> PHP, or to this situation. >> >> The reason, for everyone else reading, that this is relevant to the >> current >> discussion about a scalar decimal type is that this is likely to face some >> similar pushback. This email will go out to hundreds of people, but only a >> few are going to reply, and most of the people currently participating in >> this discussion do not have voting rights, so this RFC if it's worked on >> will have to be developed without the feedback of the people who actually >> decide whether it goes into the language. >> >> A scalar decimal type will be extremely useful for certain types of >> applications, foundationally critical to other types of applications, and >> completely unused for others. A big part of writing this RFC would be >> explaining to the people who do not work on any applications that benefit >> why it would be good to include it in the language anyway. >> >> A scalar decimal type would create a hard dependency on libmpdec, which I >> also expect to be something that needs to be addressed. MPDec is licensed >> under the Simplified BSD License. I *think* it could be bundled if needed, >> but it couldn't be relicensed with the PHP License itself. >> >> Jordan >> > > Jordan has highlighted good points that probably should be addressed and > in general, I think, this project will take a while, so I would settle in > for the long haul here and think things through and reach out to people who > actively work and maintain the PHP core. There have been recent instances > of people fitting in and passing things and then regretting the way it was > done (*cought* readonly rfc *cought* ). > > As for the idea itself - I fully support it. A decimal type would be > invaluable in quite a lot of places and a lot of PHP apps are handling > money and other precise numbers that really would benefit from a proper > decimal type (right now in most cases people just do it with integers or > use libraries like brick/money, but that's only a subset covered). > This is really adding a new type into the engine, so this is going to be a > big undertaking and this probably will require the work to go into PHP 9 > because extensions probably are going to be affected and will need to be > upgraded to handle the new type. Especially PDO and database drivers. This > is far from a small project.
Re: [PHP-DEV] Proposal: Arbitrary precision native scalar type
On Fri, Dec 15, 2023 at 12:14 AM Robert Landers wrote: > > nobody will likely ever try this again, at least in the foreseeable > future. With comments like that, there is simply no way forward. > There's no convincing (at least via email) and by that point, it's too > late anyway, they already voted but didn't even show up for the > discussion that happened for weeks. Literally wasting everyone's time. > The only way we'd ever get something like this passed is if someone > proposes an RFC that prevents people from voting based on > political/personal reasons and restricts voting "no" to technical > reasons only; or some voters reopen one of the original RFC's for a > revote and leave it in the "Pending Implementation" section as needing > an implementation. > > The fact that people can and do vote "no" for no other reason than > they "don't like it" or they "don't want to use it" leaves a bad taste > in my mouth. > Okay, so I'm probably the most affected by this, considering we're discussing my proposal which was declined and I spent over 400 hours of work on it prior to the vote. So please understand where I'm coming from when I say this: I firmly believe that people should be allowed to vote no on an RFC simply because they feel that it "doesn't belong in PHP". That is a voter taking a position on what the language is for, how it should be designed from a more broad perspective, and I think it's important to have that in order to maintain a productive language that does its job well. The main issue I have discovered through this experience is that some people have difficulty or lack the experience necessary to separate an opinion about the language design philosophy from what would be personally useful to *them*. That is a problem, but it's a problem that is just part of working collaboratively with humans. It's not unique to this group, to PHP, or to this situation. The reason, for everyone else reading, that this is relevant to the current discussion about a scalar decimal type is that this is likely to face some similar pushback. This email will go out to hundreds of people, but only a few are going to reply, and most of the people currently participating in this discussion do not have voting rights, so this RFC if it's worked on will have to be developed without the feedback of the people who actually decide whether it goes into the language. A scalar decimal type will be extremely useful for certain types of applications, foundationally critical to other types of applications, and completely unused for others. A big part of writing this RFC would be explaining to the people who do not work on any applications that benefit why it would be good to include it in the language anyway. A scalar decimal type would create a hard dependency on libmpdec, which I also expect to be something that needs to be addressed. MPDec is licensed under the Simplified BSD License. I *think* it could be bundled if needed, but it couldn't be relicensed with the PHP License itself. Jordan
Re: [PHP-DEV] Proposal: Arbitrary precision native scalar type
On Tue, Dec 12, 2023 at 4:29 PM Jordan LeDoux wrote: > > > On Tue, Dec 12, 2023 at 3:05 PM Erick de Azevedo Lima < > ericklima.c...@gmail.com> wrote: > >> Oh, I just realized that I used the wrong word, so let me rephrase that: >> >> What's the name of the library you're talking about? Maybe the *pros* of a >> core implementation can be highlighted if we can see the limitations of a >> user-land approach. >> >> Best, >> Erick >> >> > My library is Fermat: https://github.com/JordanRL/Fermat > > Mine is the ONLY one that I'm aware of that even attempts to support > complex mathematical operations in PHP. However, there are other arbitrary > precision math libraries that are more limited in scope. > > Other similar math libraries: > > markrogoyski/math-php: The closest in terms of features compared to Fermat > brick/math: The most widely installed PHP math library on Packagist (due > to being a dependency of several other widely used packages). Has extremely > limited features for complex arbitrary precision functions. > > MPDecimal (the underlying C library that we have discussed using here) has > extensions and functions for things like sine and cosine. Even just > exposing those would make writing algorithms for things like 3i^(2+5i) > much, much faster. > > The problem is that there's no point in using arbitrary precision numbers > unless you're using the spaces after the decimal. I think we can all agree > on that. No matter how good the implementation, floats are always going to > be faster if you're unconcerned about rounding errors and such. > > So if you're writing an arbitrary precision library and you want to > support the next obvious operation beyond add, subtract, multiply, and > divide, you probably naturally choose exponents. Except, calculating A^B > where both A and B have *arbitrary precision* and where the result will > also have *arbitrary precision* means that you cannot rely on things like > the `pow()` function. So you have to implement your own. Except > implementing decimal exponents means you *really* need to implement `exp()` > first, since all of the efficient algorithms rely on transforming A^B into > C*e^D. Except the most efficient ways of doing *that* really work best if > you have access to trig functions. And *ALL* your calculations in the > middle can't be losing precision, otherwise there's no point in doing your > own implementation, so that means all of these functions need to have > implementations as well. > > This rabbit hole is *so* insidious that the BCMath library simple says > "fuck it" and limits you to only using integers for your exponents. That's > basically pointless though if the reason you need arbitrary precision > numbers is something like a statistics application for instance, which PHP > *also* lacks support for since the one extension that used to provide > statistics functions is no longer maintained and hasn't been updated since > I think 7.4. > > If we get scalar decimals that only support add, subtract, multiply, and > divide, that's a huge improvement. But if we can take this opportunity to > tackle *at least* the trig functions as well, that will enable a LOT of new > userland code that is very messy and very slow right now. > > Jordan > Apologies, I just realized that you were asking about the libraries that implemented rationals with complex operations. I don't have THOSE libraries handy unfortunately. Even my library converts to decimal first. Jordan
Re: [PHP-DEV] Proposal: Arbitrary precision native scalar type
On Tue, Dec 12, 2023 at 3:05 PM Erick de Azevedo Lima < ericklima.c...@gmail.com> wrote: > Oh, I just realized that I used the wrong word, so let me rephrase that: > > What's the name of the library you're talking about? Maybe the *pros* of a > core implementation can be highlighted if we can see the limitations of a > user-land approach. > > Best, > Erick > > My library is Fermat: https://github.com/JordanRL/Fermat Mine is the ONLY one that I'm aware of that even attempts to support complex mathematical operations in PHP. However, there are other arbitrary precision math libraries that are more limited in scope. Other similar math libraries: markrogoyski/math-php: The closest in terms of features compared to Fermat brick/math: The most widely installed PHP math library on Packagist (due to being a dependency of several other widely used packages). Has extremely limited features for complex arbitrary precision functions. MPDecimal (the underlying C library that we have discussed using here) has extensions and functions for things like sine and cosine. Even just exposing those would make writing algorithms for things like 3i^(2+5i) much, much faster. The problem is that there's no point in using arbitrary precision numbers unless you're using the spaces after the decimal. I think we can all agree on that. No matter how good the implementation, floats are always going to be faster if you're unconcerned about rounding errors and such. So if you're writing an arbitrary precision library and you want to support the next obvious operation beyond add, subtract, multiply, and divide, you probably naturally choose exponents. Except, calculating A^B where both A and B have *arbitrary precision* and where the result will also have *arbitrary precision* means that you cannot rely on things like the `pow()` function. So you have to implement your own. Except implementing decimal exponents means you *really* need to implement `exp()` first, since all of the efficient algorithms rely on transforming A^B into C*e^D. Except the most efficient ways of doing *that* really work best if you have access to trig functions. And *ALL* your calculations in the middle can't be losing precision, otherwise there's no point in doing your own implementation, so that means all of these functions need to have implementations as well. This rabbit hole is *so* insidious that the BCMath library simple says "fuck it" and limits you to only using integers for your exponents. That's basically pointless though if the reason you need arbitrary precision numbers is something like a statistics application for instance, which PHP *also* lacks support for since the one extension that used to provide statistics functions is no longer maintained and hasn't been updated since I think 7.4. If we get scalar decimals that only support add, subtract, multiply, and divide, that's a huge improvement. But if we can take this opportunity to tackle *at least* the trig functions as well, that will enable a LOT of new userland code that is very messy and very slow right now. Jordan
Re: [PHP-DEV] Proposal: Arbitrary precision native scalar type
On Tue, Dec 12, 2023 at 1:26 PM Larry Garfield wrote: > On Tue, Dec 12, 2023, at 1:03 PM, G. P. B. wrote: > > > The issue is that I don't think having arbitrary precision decimals as a > > core language feature is a necessity compared to rational types. > > A cast from rational to float wouldn't produce a large round trip, > whereas > > trying to figure out arbitrary precision is more difficult. > > But in any case, having a declare/INI or whatever that changes the > > behaviour of the engine/language is not a good design choice. > > I don't have strong feelings about arbitrary precision decimals either > way, but I do strongly agree with this point. Having the language behavior > (including the precision of numbers) change with an ini setting is > long-understood to be a bad idea, and we've been trying to phase it out. A > decimal feature that relies on a language-affecting ini setting is just not > going to fly these days, IMO, and rightly so. > > I am curious, GB, if you're proposing an actual `rational` type, which > stores values internally as just numerator and denominator separately until > some point when it renders down to a float (eg, on print)? That sounds > neat, though I am nowhere near expert enough in that area to say what ugly > edge cases that might run into. > > --Larry Garfield > I agree that an INI setting or declare is wrong for this. The ugly edge cases on a native rational type tend to be in complex algorithms, which many libraries deal with by converting the rational to a float or decimal for those complex algorithms and just avoiding the issue. (Algorithms like `sin()`, `atan()`, or `exp()`). It's not an unsolveable problem if you really want rational types. There are libraries that do it. But unless there's someone here volunteering, it's probably a non-starter, as that's something I won't touch. Jordan
Re: [PHP-DEV] Proposal: Arbitrary precision native scalar type
On Tue, Dec 12, 2023 at 1:00 PM Robert Landers wrote: > > Hey Gina, > > > GMP supports operator overloading > > GMP kinda-sorta-most-of-the-time supports operator overloading. > Sometimes ... it doesn't. I implemented a field library in PHP (for > work a couple of years ago) and occasionally, overloading would cast > things back to float/int and break the math. I don't have access to > that code, so I don't have any examples readily available (and the > fact that an extension can do overloading but we can't in user-land is > a whole different can of worms which made this library ridiculously > hard to work with -- we rewrote everything in Scala and never looked > back). Needless to say, if I were to go into a project that required > GMP, I wouldn't trust the overloading. > > Just my 2¢ > I tried not to bring that up in this discussion because it would probably sound bitter/unhelpful, but the lack of userland operator overloading is definitely something that makes a native decimal scalar more necessary. Voters have repeatedly rejected userland operator overloads. The last proposal was mine, and most of the people who voted not told me that they didn't have any real problems with the design, they just don't like operator overloads. Things like ext-decimal and GMP are always going to be clunky and annoying to use without them though. It's one of the reasons I considered writing my own implementation of a decimal scalar for core after my operator overload RFC was declined. The use case for a scalar decimal type is much stronger since nothing like it can be remotely implemented in userland at all. (I know from experience, I wrote from scratch the most comprehensive arbitrary precision math library in PHP.) Jordan
Re: [PHP-DEV] Proposal: Arbitrary precision native scalar type
On Wed, Dec 6, 2023 at 10:36 PM Alex Pravdin wrote: > Hello internals, > > > This is the second round of the discussion regarding arbitrary precision > scalar type integration into PHP. The previous part: > https://marc.info/?l=php-internals=168250492216838=2 was initiated by > me before deep diving into the work with decimals in PHP. After 6 months > of > working, I would like to update my proposal taking into account my > experience and the previous discussion. > All builtin functions that currently accept float also accept decimal. So > users don't need to care about separate function sets, and PHP developers > don't need to maintain separate sets of functions. If such functions get > the decimal parameter, they return decimal. If they have more than one > float parameter and mixed float and decimal passed, decimals converted to > float by default. If "default_decimal" or "as_decimal" used, float is > converted to decimal with the warning. > > You are going to run into some very difficult corners on this one. For the last... 8 years i guess? I have been working on an arbitrary precision library for PHP in userland. It utilizes BCMath, ext-decimal, and GMP, depending on what is installed and what kind of operation you are performing. So, the functions that currently accept floats include functions such as `sin()` or `atan()`. These functions are not at all trivial to do to arbitrary precision. In fact, the VAST majority of the work I have done on my library has been to handle cases like "What do I do if the user wants 2.921 ** 4.293810472934854?" or "How will I guarantee the precision that the user requested for `tan()` in an efficient way?" Now, libmpdec is going to actually have implementations for most of this stuff that you can call directly, but if the PHP function `sin()` isn't capable of *outputting* a `decimal`, then this isn't really that much of an improvement over the current situation. I mean, it's still something I would support, but that's the area where some help from the engine goes a VERY long way. You're probably also going to need a way for a user to grab certain constants to a given precision. I would think e and pi at the least. I have a lot of experience working on this problem space in PHP, and am definitely willing to help. I looked into doing a libmpdec PHP integration several years ago, but decided that voters were unlikely to give it a fair shot, and so decided against it. If you're willing to try and roll the ball up the hill though, I'll definitely help you. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Change the edge case of round()
On Mon, Oct 23, 2023 at 4:14 AM Saki Takamachi wrote: > Hi, internals > > I would like to start the discussion for my RFC "Change the edge case of > round()”. > https://wiki.php.net/rfc/change_the_edge_case_of_round < > https://wiki.php.net/rfc/adding_bcround_bcfloor_bcceil_to_bcmath> > > Regards. > > Saki > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > > I think this makes much more sense if PHP programmers had internal access to the float type in PHP, but that's not the case. You cannot choose between float representations, you cannot easily examine the mantissa bits directly. In the absence of stuff like that, I think the argument to treat PHP floats as if they were decimals for the purposes of rounding is much stronger. That said, this sort of 'intelligent' rounding certainly introduces a large number of edge cases. Additionally, if PHP programmers expect decimal rounding to "just work", then it feels like anywhere that it doesn't work the way they think it should is a bug, which isn't necessarily true. I'm unsure whether or not this change actually improves anything. Is it more correct from a technical perspective? Absolutely. Does it provide a benefit for PHP programmers? That I am much less certain about. Jordan
Re: [PHP-DEV] Discussion - PHP with distributed programming features.
On Sat, Oct 28, 2023 at 4:35 PM juan carlos morales < dev.juan.mora...@gmail.com> wrote: > > > El El sáb, 28 de oct. de 2023 a la(s) 19:25, Jordan LeDoux < > jordan.led...@gmail.com> escribió: > >> >> >> On Sat, Oct 28, 2023 at 10:54 AM juan carlos morales < >> dev.juan.mora...@gmail.com> wrote: >> >>> >>> >>> What I mean is more about … migrating a running php instance to another >>> node or another php instance, in fact your php code is running, suddenly >>> we >>> Need to move to another node, how to do it? >>> >> >> This seems less like a discussion about a PHP feature and more like you >> asking internals for tech support at work, honestly. As far as I know, >> there isn't a way to do what you're asking, because you can accomplish the >> same thing much easier by designing your application better to make API >> calls to services, which is what people have already suggested. The PHP way >> to handle the root cause of your problem (too many resources being used on >> a single machine) is to divide the application into services and use APIs, >> often through sockets, the delegate work to those services. >> >> There are also other ways of handling this common problem in web >> application architecture. You can break up the request into multiple >> requests on the client side so that the user sees progress happen in >> chunks. You can use tools like RabbitMQ or other queuing services to >> perform certain long-running tasks asynchronously. You can use more >> powerful hardware or provision more capable nodes. >> >> In fact, several of these actually fall under the Actor/Object or >> Dataflow model of implementing Distributed Programming. What PHP does not >> support is the Distributed Shared Memory model of implementing Distributed >> Programming (which is what you are asking about apparently) because doing >> so would almost certainly make PHP worse at the things it is well suited >> for, would massively complicate the work of maintaining and developing the >> language for the contributors to the language, and would be a massive >> undertaking to implement in the first place. >> >> PHP has distributed programming features. In fact, all of the suggestions >> you have received so far ARE ways of doing distributed programming >> features. But internals is not your, or my, or anyone else's personal tech >> support channel, and personally it feels like you haven't explained what it >> is you want to discuss with internals about improving or changing PHP's >> support for distributed programming. Are you interested in working on an >> RFC to clone a PHP process onto a remote box? I can't imagine that would >> get much support here, or be something that is very simple to do. >> >> Jordan >> > >> > Hello Jordan, thanks for the reply. When I read you, I have the feeling > that you are a little angry about my question, please dont. > > It is a very honest question, that do belong to the internals, because if > PHP does not have a way to do it, I would like to think a way to do it > (despite the fact someone believes is useful or not, it is just me). > > So again, thanks!, dont get mad :D, and I will come back later on this > topic, in a more clear way, maybe I am not expressing myself clearly. > > Regards > I'm not angry at all, I just wanted to focus in on a discussion that is relevant to the internals mailing list. Most of the ideas here, including the ones I've proposed, come from our own experiences and there's nothing wrong with that. But I didn't see anything that looked like a discussion and I wanted to be clear about what I think this list is for, and what kind of discussions might be productive. I don't think that what you are talking about would be very useful, because I expect that it would be complicated for very little benefit. But if you think this is a way to improve the language, then I would listen. I just wasn't hearing that. It is also possible I am not understanding very well. Jordan
Re: [PHP-DEV] Discussion - PHP with distributed programming features.
On Sat, Oct 28, 2023 at 10:54 AM juan carlos morales < dev.juan.mora...@gmail.com> wrote: > > > What I mean is more about … migrating a running php instance to another > node or another php instance, in fact your php code is running, suddenly we > Need to move to another node, how to do it? > This seems less like a discussion about a PHP feature and more like you asking internals for tech support at work, honestly. As far as I know, there isn't a way to do what you're asking, because you can accomplish the same thing much easier by designing your application better to make API calls to services, which is what people have already suggested. The PHP way to handle the root cause of your problem (too many resources being used on a single machine) is to divide the application into services and use APIs, often through sockets, the delegate work to those services. There are also other ways of handling this common problem in web application architecture. You can break up the request into multiple requests on the client side so that the user sees progress happen in chunks. You can use tools like RabbitMQ or other queuing services to perform certain long-running tasks asynchronously. You can use more powerful hardware or provision more capable nodes. In fact, several of these actually fall under the Actor/Object or Dataflow model of implementing Distributed Programming. What PHP does not support is the Distributed Shared Memory model of implementing Distributed Programming (which is what you are asking about apparently) because doing so would almost certainly make PHP worse at the things it is well suited for, would massively complicate the work of maintaining and developing the language for the contributors to the language, and would be a massive undertaking to implement in the first place. PHP has distributed programming features. In fact, all of the suggestions you have received so far ARE ways of doing distributed programming features. But internals is not your, or my, or anyone else's personal tech support channel, and personally it feels like you haven't explained what it is you want to discuss with internals about improving or changing PHP's support for distributed programming. Are you interested in working on an RFC to clone a PHP process onto a remote box? I can't imagine that would get much support here, or be something that is very simple to do. Jordan
Re: [PHP-DEV] Custom object equality
On Mon, Oct 23, 2023 at 10:20 AM Dik Takken wrote: > On 23-10-2023 18:34, Larry Garfield wrote: > > > > Jordan's RFC explained in detail why interfaces are not viable, which is > why we have to use magic methods (with or without a special keyword) > instead: > > > > > https://wiki.php.net/rfc/user_defined_operator_overloads#why_not_interfaces > > > > (Seriously, it has an extensive FAQ. It's one of the more detailed and > supported RFCs we've seen.) > > > > Yes, I know the RFC, it's a great piece of work! The use of interfaces > as mentioned in this RFC is however completely different from what > Pierre and I are talking about. If I understand Pierre correctly, that > is. The suggestion to include interfaces simply meant to allow freedom > of choice. Choice between using an operator (`==`) or calling the > equivalent method on the object (`->equals()`). That may get more people > on board with operator overloading. > > Regards, > Dik > > I don't quite follow. The interface would cause the engine to use the result of an `equals()` function on the object if it implements an interface as part of `zend_compare`? Internally there is no `==` function, there is only the equivalent of `<=>`. To implement it ONLY for `==` would require a trapdoor of some kind in the `do_operation` handler that would also affect the way the existing extensions work, such as the `DateTime` class which implements a custom handler for the `compare` handler on the zend class entry. This might be easier to do once a few comparison improvements to separate "comparable" and "equatable" are done, but the PR I submitted two years ago to handle that got kind of mired in bike shedding about the implementation and I lost interest in continuing to push it. Implementing the compare handler for an overload requires adding two new entries to ZEND_AST_BINARY_OP because the `>` and `<` comparisons have to be preserved in the AST in order to call the correct object handler. THAT requires updating OpCache and JIT since all such comparisons are currently reordered to use `<`, and though I spent quite a while looking at it, I think Dmitry might be the only person that could really implement that fully. At least, I never found anyone that had the expertise to actually help me with it. Jordan
Re: [PHP-DEV] Custom object equality
On Thu, Oct 19, 2023 at 12:14 AM Pierre wrote: > > Maybe I don't master english enough and I can speak to strictly > sometime. If an operator overload RFC that doesn't have any blind spot > or weird edge case happens, I'd be happy to see it pass, at least it > would close bike shedding around this topic and life would continue > happily. > > I can't vote, but if I could, I wouldn't vote against a proper, robust, > and easy to debug for developers operator overload RFC, I would simply > abstain, because even if I personally don't like it, lots of people want > it and I'm simply one among millions of PHP users, I don't want anyone > to be frustrated. > > The most important thing in my previous message I wanted to say was that > the "~" symbol refers to something "approximate" in many contexts, in my > opinion it's not the right choice for an equality operator. My opinion > is either go for a full-on proper operator overload or simply don't. > > Regards, > > -- > > Pierre > > I tried to make sure this was clear, but I will say it explicitly just to make sure: I am not at all criticizing you, I was just saying that the opinion you expressed is one that is shared by many voters so it cannot be simply dismissed, and that I disagree with it personally. Jordan
Re: [PHP-DEV] Custom object equality
On Wed, Oct 18, 2023 at 6:03 AM Pierre wrote: > Le 18/10/2023 à 14:50, someniatko a écrit : > > Hi internals, > > > > This approach allows combining > > - no BC break - `~=` is a new syntax which is unavailable in older PHP > > versions > > - explicitly showing an intent that objects are compared using a custom > > comparison, rather than standard PHP one > > - allow to skip writing boilerplate equals() methods which just forward > > equals() to the nested objects > > - standardize such comparisons on the language level > > > > Of course how exactly this operator looks may be changed, `~=` is just an > > example. > > > > WDYT? > > I'm not fond of operator overloading, I actually quite hate it, I like > the expressiveness of an equals() method. > > I would very much prefer to have a set of standard interfaces such as > Comparable { compareTo($other): int } or Equatable { equals($other): > bool; } which the standard API and userland libraries could make use of. > > In all cases, I don't like the ~= choice because in my mind it literally > translates to "is approximately/barely/maybe comparable to". > > By the way, please do not use abbreviations such as WDYT, I'm not a > native english speaker and I don't know all abbreviations, I had to > duckduckgo' it. > > Regards, > > -- > > Pierre > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > > While I (obviously) appreciate the goal of the proposal here since I wrote the gigantic operator overload RFC the last time it was proposed, I do not support this idea here for one very simple reason: it is a clunky, work-around implementation to try and get the benefits of operator overloads without actually doing it. The need to control comparisons is real and obvious. So long as voters are categorically opposed to actual operator overloads no matter the implementation, as represented here by you Pierre but by no means a position that only you hold, I don't think we should be looking for ways to get the functionality through hacks like this. It may get passed in the short term and get PHP developers the equality comparison control that objects desperately need, but it makes all future improvements almost impossible to do. someniatko: If voters don't want operator overloads, then voters don't get the features of operator overloads. It's very much that simple. If you want this feature, try and change minds (ha ha good luck). "Operator overloads don't fit a language like PHP"... despite the fact that Python is the language most like PHP in many ways and has some absolutely crazy operator overloads. "Operator overloads make operators impossible to understand"... despite the fact that this is already the case with existing operators and magic methods. "There is no use case"... despite the fact that this gets suggested by a different person like clockwork AT LEAST every version because it is something they would use. Honestly I would give up on advocating for operator overloads someniatko and just move to a language that has them like Python. That's what I did. Your sanity will thank me. Jordan
Re: [PHP-DEV] Why did fibers get added to php core over something more fleshed out like swoole?
On Thu, Oct 12, 2023 at 6:00 PM Lanre Waju wrote: > It sometimes seems as though certain choices may not align with the best > interests of the PHP community. I would appreciate it if you could > provide insights into why this might not be the case. > > To find out why Fibers was done instead of something like Swoole, I'd suggest reading the mailing list discussions on those. That was a discussion that DID happen on list, and you can read about it there without us rehashing it for no particular reason. The way you ended this email though is very "guilty until proven innocent", and I think it's unlikely you're going to get many responses based on the way you phrased this and the implied accusation it entails. This is coming from someone who has their own reservations about how PHP voting is conducted. It's a discussion that very few people want to have because of how drawn out and heated it is likely to be, and the fact that a significant number of people don't see any problem with the current system. Trying to start that conversation with "it seems obviously broken, prove me wrong" sounds like just about the worst framing that discussion could have if you want it to be productive. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Adding bcround, bcfloor and bcceil to BCMath
On Thu, Oct 12, 2023 at 11:32 AM Pierre Joye wrote: > Hi Jordan > > On Fri, Oct 13, 2023, 1:24 AM Jordan LeDoux > wrote: > >> >> >> On Thu, Oct 5, 2023 at 5:27 AM Saki Takamachi wrote: >> >>> Hi, Pierre >>> >>> In fact, I predict that many use cases will be covered by GMP. >>> >>> Still, I think that there may be cases where calculation functions like >>> mainframe BCD are required, such as when calculating money. >>> >>> I am unable to decide whether it is correct to deprecate BCMath and only >>> use GMP. >>> >>> I'd like to hear other people's opinions as well. >>> >>> Regards. >>> >>> Saki >>> >> >> GMP cannot be used in any reasonable way to implement things like sin() >> or cos(). It is *technically* possible, but not at all reasonable. >> > > it is the reason I mentioned mpfr, > https://www.mpfr.org/mpfr-current/mpfr.html#Miscellaneous-Functions > > the challenge I noticed in a couple of threads recently is the mixup of > radically different usages, like financial numbers with basic ops (+/- > eventually *//) and others. > > they cannot use the same tools, most of the times. However there are libs > with different types or mode of operations, which could be a better fit > than what we do now. > > It is not an easy research and priorities need to be clear. > > BCMath is one of the worst and slowest implementations of arbitrary >> precision decimals. >> > > what I was trying to express :) > > > best , > I believe MPFR is what is used by ext-decimal. The only thing that makes ext-decimal a somewhat difficult replacement for BCMath is that one of them uses precision and the other uses scale. (Total accurate digits versus total significant digits.) Fermat has implementations for both BCMath and ext-decimal, while also using GMP. It is much more difficult to control the number of accurate digits in ext-decimal than in BCMath, but ext-decimal is literally hundreds of times faster. I think, however, that Rudi (the author of ext-decimal) was against including ext-decimal in core. But if you want an alternate implementation for arbitrary precision decimals, it is certainly the place that someone should start. Jordan
Re: [PHP-DEV] [VOTE] Increasing the default BCrypt cost
On Wed, Oct 4, 2023 at 5:08 PM wrote: > Also the poll for increasing from cost 11 to cost 12 should be a 2/3 > majority to get cost 12. Since the poll for increasing from cost 10 to cost > 11 is a 2/3 majority. You can think of this as a 2/3 majority poll to > increase to cost 11 followed by a 2/3 majority poll to increase to cost 12. > > That's not how voting works in the PHP project. The 2/3 is for whether or not the feature change should be made at all. In the case that there are multiple implementations or variations, the choice between those is usually simple majority. People can and do vote no on the main 2/3 vote if they feel that only one of the implementations/variations are acceptable. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Adding bcround, bcfloor and bcceil to BCMath
On Thu, Oct 12, 2023 at 11:24 AM Jordan LeDoux wrote: > > > On Thu, Oct 5, 2023 at 5:27 AM Saki Takamachi wrote: > >> Hi, Pierre >> >> In fact, I predict that many use cases will be covered by GMP. >> >> Still, I think that there may be cases where calculation functions like >> mainframe BCD are required, such as when calculating money. >> >> I am unable to decide whether it is correct to deprecate BCMath and only >> use GMP. >> >> I'd like to hear other people's opinions as well. >> >> Regards. >> >> Saki >> > > GMP cannot be used in any reasonable way to implement things like sin() or > cos(). It is *technically* possible, but not at all reasonable. Now, PHP > doesn't natively support trig functions for anything other than normal > floats, but things like that are exactly the extended capability that my > PHP math library adds. This is required for most statistics, which now HAVE > to be done in PHP itself since the ext-stats extension hasn't been updated > since... I think 7.1? > > BCMath is one of the worst and slowest implementations of arbitrary > precision decimals. It absolutely should be replaced. I have explored > creating a new extension to do just this in fact for the express purpose of > deprecating and replacing the bundled BCMath. But GMP, as it is implemented > currently, is not a replacement at all. > > Jordan > Take a look at the ext-decimal extension if you are interested in replacing BCMath. It honestly is almost a drop-in replacement. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Adding bcround, bcfloor and bcceil to BCMath
On Thu, Oct 5, 2023 at 5:27 AM Saki Takamachi wrote: > Hi, Pierre > > In fact, I predict that many use cases will be covered by GMP. > > Still, I think that there may be cases where calculation functions like > mainframe BCD are required, such as when calculating money. > > I am unable to decide whether it is correct to deprecate BCMath and only > use GMP. > > I'd like to hear other people's opinions as well. > > Regards. > > Saki > GMP cannot be used in any reasonable way to implement things like sin() or cos(). It is *technically* possible, but not at all reasonable. Now, PHP doesn't natively support trig functions for anything other than normal floats, but things like that are exactly the extended capability that my PHP math library adds. This is required for most statistics, which now HAVE to be done in PHP itself since the ext-stats extension hasn't been updated since... I think 7.1? BCMath is one of the worst and slowest implementations of arbitrary precision decimals. It absolutely should be replaced. I have explored creating a new extension to do just this in fact for the express purpose of deprecating and replacing the bundled BCMath. But GMP, as it is implemented currently, is not a replacement at all. Jordan
Re: [PHP-DEV] [RFC] [Discussion] Add 4 new rounding modes to round() function
On Sun, Sep 3, 2023 at 5:51 AM Alexandru Pătrănescu wrote: > Hi! > > On Sun, Sep 3, 2023 at 3:14 PM Tim Düsterhus wrote: > > > > > The RFC mentions already has a section with regard to naming: > > > > > Why not the names PHP_ROUND_UP and PHP_ROUND_DOWN > > > > I generally agree with the argument in favor of the names you've chosen. > > However they are inconsistent with the existing 'PHP_ROUND_HALF_UP' / > > DOWN constants. > > > > I don't want to create extra work for you, but I wonder if additionally > > one of the following should be done: > > > > - Creating PHP_ROUND_HALF_AWAY_FROM_ZERO as an alias for > > PHP_ROUND_HALF_UP (and likewise for HALF_DOWN). > > > > > I believe consistency is important and using UP for "away from zero" and > DOWN for "towards zero" sounds good to me. That was so far used > consistently everywhere, as far as I'm aware. > Documentation is very clear about what they mean, and you can always think > that both positive infinity and negative infinity are up while zero is > down. > > Yes, we can have some extra constants for the four ones that contain "up" > or "down" with "away from zero" and "towards zero", but I find it > unnecessary. > As someone who maintains a math library in PHP that has its own expanded rounding implementation, I will politely disagree. Away from zero, towards zero, towards positive infinity, and towards negative infinity are completely and utterly unambiguous and provide the developer with precise control over what behavior they want. I don't see a reason to use something that we KNOW is ambiguous when we're designing it. This becomes even more important if we ever wanted to provide even more rounding modes. For instance, a PHP_ROUND_HALF_ALTERNATING would want to explicitly use positive and negative infinity as its directions most likely. (The purpose of a "half alternating" mode is to ensure that the introduced error by rounding many numbers doesn't have a directional bias by swapping between two modes that round in one direction and then the other.) I don't want to complicate this RFC, but I wouldn't mind adding a PHP_ROUND_STOCHASTIC mode later either. (This mode would round 1.7 to 2 for 70% of executions and 1 for 30% of executions. The purpose of this rounding mode is to ensure that if you averaged the same number being rounded over and over, it would average to your original unrounded number, and is used in many Machine Learning applications.) Jordan
Re: [PHP-DEV] Introducing 2 new modes to round function
On Fri, Jul 21, 2023 at 3:48 PM Jorg Sowa wrote: > Thank you for your suggestions. I added two remaining modes and I think > it's complete now. > > I changed the names to `PHP_ROUND_CEILING` and `PHP_ROUND_FLOOR` to be > consisted with rounding modes in number_format() function. I'm not sure > about `PHP_TOWARD_ZERO` and 'PHP_AWAY_FROM_ZERO` as in there it's > `ROUND_DOWN` and `ROUND_UP`, which I also find too vague. > > However, I could find names UP and DOWN in other documentations. And sadly > it refers to away from zero and toward zero, so there is big mismatch in > existing naming. > > > https://developer.apple.com/documentation/foundation/numberformatter/roundingmode/down > > https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/math/RoundingMode.html > I had to deal with this issue when I was doing the rounding modes for my math library in PHP. I ended up providing the following rounding modes: - Half Up (Positive Infinity) - Half Down (Negative Infinity) - Half Even - Half Odd - Half Zero - Half Infinity (Closest) - Half Random (50% chance of either direction) - Half Alternating (Each subsequent call to round alternates rounding direction) - Stochastic (Chance of direction based on proximity... i.e. 1.7 rounds to 2 70% of the time, and rounds to 1 30% of the time) The only reason I used "Half Up" and "Half Down" is because I also used "Half Zero" and "Half Infinity" so it was more clear there were differences. Stochastic is probably the one that sounds weirdest to most people, but is insanely useful for applications like Machine Learning. Jordan
Re: [PHP-DEV] pipes, scalar objects and on?
On Tue, Jul 18, 2023 at 8:05 AM Robert Landers wrote: > On Tue, Jul 18, 2023 at 3:18 PM Olle Härstedt > wrote: > > > > 2023-07-18 14:48 GMT+02:00, someniatko : > > > I am glad this topic arose! I was also planning to write on this topic > to > > > the internals mailing list, but have abandoned this idea, because I > feel it > > > might be inconvenient for the real active PHP developers on the list to > > > receive too many emails from the people which don't actively > participate in > > > the development itself. > > > > > > My interest in the pipe operator might seem a little non-standard - > > > basically what I'd really want to see is a **nullable** pipe operator! > > > > > > There is a popular library github.com/schmittjoh/php-option, which > has 250 > > > MILLION installations. Basically what it provides is a class-wrapper > of a > > > value of lack thereof: it's either `Some` or `None`. I also > maintain > > > a similar library > https://packagist.org/packages/someniatko/result-type > > > which fixes some shortcomings of the original one related to the static > > > analysis, but this is another story. Basically what the stats tell us > is > > > that such stuff is popular among the PHP community. > > > > > > In my eyes, it is actually semantically equivalent to the nullable PHP > > > types: `?Type`. And some operations provided by the lib, are actually > > > covered by PHP itself, which has multiple null-friendly operators: > > > `$option->getOrElse($defaultVal)` --> `$nullable ?? $defaultVal` > > > `$option->isEmpty()` --> `$nullable === null` > > > `$option->getOrThrow(new \Exception('blah'))` --> `$nullable ?? throw > new > > > \Exception('blah')` > > > > > > I'd like to use the arguably "more idiomatic" native PHP nullables, > rather > > > than a foreign-feeling userspace construct, if they were more > convenient. > > > > > > But there is a very important operation, `map()`, which is > unfortunately > > > not covered by the native PHP, which is `Option::map()`, and here is a > > > real-world example: > > > ``` > > > return $repository->getById($idFromHttpRequest) > > > ->map($serializer->serializeToJson(...)) // only executes when the > > > Option is Some, not None > > > ->map(fn (string $json) => new Response(status: 200, content: > $json)) > > > ->getOrElse(new Response(status: 404)); > > > ``` > > > > Ehm, wouldn't that be the same as a Pipe class that's configured to > > stop on null? > > > > public function getThing($id) { > > return new Pipe( > > $this->getData(...), > > $this->serializeData(...), > > $this->mapToResponse(...) > > ) > > ->stopOnEmpty() > > ->from($id) > > ->run(); > > } > > > > Wait, are you using map() for arrays or not? Looks like not. > > > > Olle > > > > -- > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: https://www.php.net/unsub.php > > > > I might be venting, but, I wish the operators RFC had passed... > I don't think I will re-propose it with the current set of voters tbh. The main people who contribute to the Zend folder (the core engine/compiler parts) were highly skeptical of it, with at least two telling me flat out that they would vote no even on a hypothetical perfect feature design. Very few contributors actually touch large parts of that area of the engine, so most voters tend to take the opinions of those 5-6 voters very seriously on such proposals. As I don't think it's possible for me to convince those 5-6 people, I don't think it would be a good idea to re-propose, because even if I did get a 2/3 vote on it, I feel like the people most responsible for helping me maintain the feature would not be very happy/willing to do so, and that would probably harm the PHP project in other ways. Jordan
Re: [PHP-DEV] [RFC] Path to Saner Increment/Decrement operators
On Tue, Jan 17, 2023 at 6:28 AM G. P. B. wrote: > Hello Internals, > > I would like to start the discussion on the Path to Saner > Increment/Decrement operators RFC: > https://wiki.php.net/rfc/saner-inc-dec-operators > > The goal of this RFC is to reduce language complexity by making $v++ behave > like $v += 1 and $v-- behave like $v -= 1; > > I am expecting the contentious part of the proposal to be the deprecation > of the PERL string increment feature to achieve the aforementioned goal. > However, I believe the benefits of aligning the behaviour of the > increment/decrement operators with addition/subtraction are larger than > keeping support for the PERL increment, which in its current state has > various shortcomings. > > Best regards, > > George P. Banyard > I don't see a section in the RFC about JIT or anything related to OpCache, but I know from experience with the Operator Overloads RFC that there are several architecture specific assembly optimizations for ++ and --. Have these been considered, and how will they be impacted? Jordan
Re: [PHP-DEV] [RFC] [Discussion] Readonly class amendments
On Sat, Nov 26, 2022 at 3:40 PM Deleu wrote: > > As I think more about this, there's nothing about the current RFC in this > code sample. What's breaking LSP here is the child class doing state > modification, not PHP. To further expand that rationale, PHP allows us to > create child classes. Whether that class will be LSP-safe or not is up to > us, not up to PHP. > > However, the point still stands. Allowing child classes to break readonly > will make it easier to build code that breaks LSP. The question then > becomes: why is this being proposed and is it worth it? > I cannot help but feel that the way `readonly` is being treated is going to end up one of those things that is regretted. "Readonly does not imply immutability". The fact that very nearly *every* single person who has not worked on the RFCs has at some point been confused by this however should be very telling. This comes from two *different* avenues that compound with each other to *both* make this design head-scratching to me. First, in virtually all other technical contexts where the term "readonly" is used, it means that the information/data cannot be altered. That is not the case with readonly. In PHP, in this implementation, it is not "readonly" in the sense that it is used everywhere else for computing, it is "assign once". Second, the English words "read only", particularly to native speakers, make this behavior very counterintuitive and confusing. I won't belabor that point further. What "read only" really is, is "constructor initialize only". It honestly has nothing to do with "read" as it's implemented. I guess I worry that this RFC makes `readonly` even more of a minefield for PHP developers, increasing the mental load of using it in code while *even further* watering down the benefits it may provide. It's already designed in a somewhat counterintuitive way that I feel will be almost completely replaced in actual code in the wild by "immutable" if PHP ever gets that. LSP doesn't exist because it is some objectively better way of programming according to universal laws of entropy or something. It is instead important because LSP helps programmers be able to predict the behavior of the program they are writing and reduces the short-term memory load involved in programming and architecture. Something that *technically* complies with LSP but makes the program harder to predict and increases the mental load of programming violates the *purpose* of LSP. We can argue about whether it is technically correct, but I feel like that somewhat misses the point: making the language more capable, more stable, and more predictable. In other words, I do not believe it is that important or care to argue about whether this RFC violates LSP. It violates the *purpose* of LSP, and that's a bigger problem to me personally. Jordan
Re: [PHP-DEV] RFC [Discussion]: Randomizer Additions
On Sat, Nov 5, 2022 at 9:00 AM Tim Düsterhus wrote: > > Likewise if you generate a random float between 0 and 1000 with this > method, some values will appear more often than others due to rounding > and the changing density of floats for each power of two. > > With the γ-section algorithm by Prof. Goualard all these issues are > eliminated and that's what is used for getFloat(). The getFloat() method > supports all 4 possible boundary combinations to ensure that users have > a safe solution for all possible use cases, so that they don't need to > build an unsafe solution in userland. > > This is a much more subtle problem than many people realize, and I'm sure there are people who will vote or use this feature that don't have a deep understanding of either the float/double type, or of the math behind this, so I'm going to re-explain this using some analogies and examples. **NOTE**: This is mainly for historical record if someone looks back on this internals thread, not in response to any individual in the thread. I'm trying to lay out in language that any passer-by could follow what the issue is and why it is important. Accordingly, I'll be referencing base-10 numbers instead of base-2 numbers through most of this for clarity, but the ideas behind it apply to the base-2 numbers that are actually used, just with different boundaries at powers of 2 instead of powers of 10. Suppose you have a number type that can store exactly 10 digits. Well over the interval [0, 1] you can represent any number between 0.000 000 000 and 1.000 000 000 without issue. In fact, since you can store exactly 10 digits, you can represent any number between 0.000 000 000 and 9.999 999 999. But what happens if you want the interval [0, 10]? Well, at 10 you can only represent the digits 10.000 000 00, since you have to use one of the digits that used to represent the decimal part to represent the whole part, because you have a fixed amount of digits you can use. In order to represent larger numbers, you lose the ability to represent certain numbers that you used to be able to represent. The "density" of numbers has gone down. So if you tell the program "I want a random number, with decimal places, between 0 and 1000", it runs into the following dilemma: between [0, 10), (this means the interval that includes 0 but does not include 10), you have 1 billion values between each whole number which could be chosen. However, for the numbers between [10, 100), you only have 100 million values between each whole number that could be chosen, because you lost a digit after the decimal point. This means that if you do a naive multiplication or selection of your number, the intervals between 0 to 10 are individually 10 times more likely to be chosen than any of the individual intervals between 10 to 100, because those intervals have 10 times as many values mapped to them. The result would actually be nearly equally likely to be in the range [0, 10) as it would [10, 100), (because there are nearly as many possible values between [0, 10) as there are between [10, 100)), even though mathematically the second range is nearly 10 times the size of the first range. Each possible representable value would be equally likely to be chosen, but because the *density* of values is different at different parts of the range, this actually skews the probability of a number landing within an arbitrary part of the range of outputs. This means that if your code does something like `if ($rand->getFloat(0, 1000) < 500)`, you're NOT actually going to get a 50% chance of `true` and a 50% chance of `false`. In fact, using the naive way of mapping floats that Tim mentioned (with base-10 math instead of base-2), you'd get `true` *over two thirds of the time*. Accounting for this is not very easy. What proportion of your total result set has an expanded representable value? In my example, that might be easy to calculate, but the actual math for a program like this is done in base-2, not base-10. To actually calculate this, you need all sorts of logs you need to take to figure out how many powers of 2 you're spanning, and how that affects the probability of different intervals. It is *extremely* easy to get this math wrong, even if you know what you're doing. As Tim said, virtually no implementations that exist *actually* do this correctly. Also consider that the requested range may not nicely straddle a power of 2. What if you want a float for the interval [5, 10]? Neither 5 nor 10 sit cleanly on a power of 2, so how does that affect your math? Like cryptography and security, this is an area where very specific and very confident expertise is necessary, and it is highly preferable to have everyone use a single vetted solution than roll their own. This makes it very poor as something to leave to userland, and makes it *highly* desirable to include it in core. It's very difficult to do, but there is also only one actually correct result, which makes it perfect for
Re: [PHP-DEV] [RFC][Discussion] Objects can be declared falsifiable
On Wed, Nov 2, 2022 at 1:12 AM Michał Marcin Brzuchalski < michal.brzuchal...@gmail.com> wrote: > Hi Josh, > > Have you tried not initializing invalid objects? This could help you. > Also that sounds more logical to me as I don't see any reasons to > initialize invalid objects if it's a matter of simple validation instead. > > P.S. I don't see it feasible to have objects that evaluate false in > logical expressions. > > Cheers, > Michał Marcin Brzuchalski > The one situation in which I can think of where an object might legitimately have a falsey bool casting is if it represents a single value (that may have multiple properties associated with it, like units of measurement), and `if ($obj)` is really asking something like `if ($obj->castSingleValuePropertyToBool())`. For most of *these* situations, either `if ($obj->isEqual(0))` is equivalent, or `if ($obj == 0)` is equivalent if operator overloading was accepted. Jordan
Re: [PHP-DEV] Request for Wiki karma
On Mon, Oct 31, 2022 at 10:43 AM Codito - Grzegorz Korba < grzegorz.ko...@codito.pl> wrote: > > I don't want to edit someone else's RFCs, but I saw there are several > pages related to the process itself, which I find not as helpful as they > should be I will work on the docs through the PRs, but wanted to make > some adjustments on the Wiki pages too, if you don't mind. > > I have some small RFC in mind too, but I'll send it separately > > Sorry for the duplicate, wrong click. > No worries! I just wanted to make sure there wasn't any confusion. :) I'm not actually the person that would give wiki karma. Jordan
Re: [PHP-DEV] Request for Wiki karma
On Mon, Oct 31, 2022 at 12:32 AM Codito - Grzegorz Korba < grzegorz.ko...@codito.pl> wrote: > Hi Internals! > > I would like to ask for Wiki karma (account: codito) in order to be able to > edit Wiki pages. I feel like I can help with providing helpful examples or > improve existing docs. In the future I'm most probably going to make RFCs > too. > > For those who don't know me, here's my blog post about PHP8.2 new features: > https://blog.codito.dev/2022/05/new-in-php-8.2/ > so you can see how I write. Some of you probably know me from Twitter: > https://twitter.com/_Codito_ > > Having those sources you can probably evaluate if you want my help :-) > > Have a nice day everyone, > Grzegorz Korba > Are you asking for wiki karma to work on the documentation? The documentation isn't part of the wiki, it has its own github repo. The wiki is mainly used for posting RFCs, but generally people with wiki karma don't change someone else's RFC with what they think might "improve" it. If you have an RFC you want to do, you can definitely get wiki karma. :) Just want to make sure we're helping you get the thing you're looking for. Jordan
Re: [PHP-DEV] RFC [Discussion]: Randomizer Additions
On Sat, Oct 29, 2022 at 6:02 PM Jordan LeDoux wrote: > > > On Sat, Oct 29, 2022 at 12:21 PM Jordan LeDoux > wrote: > >> >> >> >> Well... perhaps. But "get bytes from character list" would do exactly >> what it says it will do, even from UTF-8 strings. It will use any of the >> bytes from the character list, even if one character in the list may >> contribute multiple bytes to choose from. It is *not* contradictory, just >> potentially confusing about the result >> >> Jordan >> > > On second thought, isn't it possible to simply choose a random integer to > correspond with the char list position instead, sidestepping the UTF-8 > issue entirely? In which case, it might be more accurate to name it just > `getRandomCharFromList` > > Jordan > Nevermind, disregard. I just remembered (again) how strings are handled in PHP and why this wouldn't work. Jordan
Re: [PHP-DEV] RFC [Discussion]: Randomizer Additions
On Sat, Oct 29, 2022 at 12:21 PM Jordan LeDoux wrote: > > > > Well... perhaps. But "get bytes from character list" would do exactly what > it says it will do, even from UTF-8 strings. It will use any of the bytes > from the character list, even if one character in the list may contribute > multiple bytes to choose from. It is *not* contradictory, just potentially > confusing about the result > > Jordan > On second thought, isn't it possible to simply choose a random integer to correspond with the char list position instead, sidestepping the UTF-8 issue entirely? In which case, it might be more accurate to name it just `getRandomCharFromList` Jordan
Re: [PHP-DEV] RFC [Discussion]: Randomizer Additions
On Sat, Oct 29, 2022 at 6:10 AM Claude Pache wrote: > > > > Le 28 oct. 2022 à 23:43, Jordan LeDoux a > écrit : > > > > On Fri, Oct 28, 2022 at 12:30 PM Joshua Rüsweg via internals < > > internals@lists.php.net> wrote: > > > > Not to try and bikeshed further, but wouldn't `getBytesFromChars` or > > `getBytesFromCharList` be more clear while being nearly as accurate? > > > > Jordan > > > In the face of multibyte character sets such as UTF-8, I wouldn’t use > “char” to mean “byte” (even if, in practice, the most common use will be > strings of 1-byte chars). “Alphabet” or “string” might be ambiguous (is it > an alphabet of bytes or an alphabet of characters?), but at least they are > not contradictory. > > —Claude Well... perhaps. But "get bytes from character list" would do exactly what it says it will do, even from UTF-8 strings. It will use any of the bytes from the character list, even if one character in the list may contribute multiple bytes to choose from. It is *not* contradictory, just potentially confusing about the result Jordan
Re: [PHP-DEV] Re: RFC [Discussion]: Randomizer Additions
On Fri, Oct 28, 2022 at 12:23 PM Joshua Rüsweg via internals < internals@lists.php.net> wrote: > Hi > > > You can find the RFC at: > > > > https://wiki.php.net/rfc/randomizer_additions > > Tim Düsterhus and I have updated the RFC and have broadly adopted the > proposals. > > Firstly we have renamed the `getBytesFromAlphabet` to > `getBytesFromString` as Larry Garfield suggested. > > Secondly, we have extended the getFloat method with a parameter that > specifies which type of interval should be generated (Open, Closed, > Right Half-Open and Left Half-Open). > > Are you happy with the enum names? Have you any other suggestions? > > I had a discussion with Tim about this naming topic as well, and want to convey my suggestion along with the reasoning. I think the enum should be `Random\IntervalBoundary` with the enum cases: `IntervalBoundary::Open` `IntervalBoundary::Closed` `IntervalBoundary::OpenRight` or `IntervalBoundary::HalfOpenRight` `IntervalBoundary::OpenLeft` or `IntervalBoundary::HalfOpenLeft` First, I think the enum should be `IntervalBoundary` because an enum is used to explicitly represent a program state in a human readable format. Because of this, I think that the readability for enums should be the highest priority, even above brevity. Additionally, it should describe the thing that has the properties, in this case the interval itself. These interval settings are *not* a property of floats, it's just that interval boundary types don't usually matter outside of floats. The enum should be in the `Random\` namespace, because we are only guaranteeing that this is a complete list of interval boundary properties in the domain of random numbers. It should not be in the `Random\Randomizer` namespace, even though that's the only place it would be used, because these properties of an interval boundary would be shared by anything that has interval properties in the domain of random numbers. Enums don't describe a hierarchy, like interfaces do, so it doesn't make sense to me to do it the same way the engines are done, for example. I think `OpenRight` and `OpenLeft` are clear enough, since it clearly describes something that is only half open, but I wouldn't argue strongly against `HalfOpenRight` and `HalfOpenLeft` if someone else felt strongly about it. Anyway, that's my notes. :) Jordan
Re: [PHP-DEV] RFC [Discussion]: Randomizer Additions
On Fri, Oct 28, 2022 at 12:30 PM Joshua Rüsweg via internals < internals@lists.php.net> wrote: > Hello! > > [As Larry kindly pointed out to me, I only sent the email to Larry and > not to the mailing list.] > > > "Alphabet" here still, to me, implies a character set, not a byte > stream. Maybe getBytesFromString? getBytesFromList? getBytesFrom() > (because you're getting it "from" the string that's provided, so you don't > need another noun there.)? > > > > I'm not opposed to the functionality, but "alphabet" doesn't seem like > the right word for it. > > I'm not really happy with the name either and was hoping for some > suggestions. `getBytesFrom` sounds incomplete to me. `getBytesFromList` > sounds to me as if an array is being passed there and not a string. > `getBytesFromString` sounds good to me, though. Better than > `getBytesfromAlphabet`! > > Cheers > > Joshua Rüsweg > Not to try and bikeshed further, but wouldn't `getBytesFromChars` or `getBytesFromCharList` be more clear while being nearly as accurate? Jordan
Re: [PHP-DEV] Adding the OpenSSF Scorecards GitHub Action
On Thu, Oct 20, 2022 at 2:26 PM Pedro Nacht via internals < internals@lists.php.net> wrote: > I've made this suggestion as issue #9778 ( > https://github.com/php/php-src/issues/9778) and PR # 9789 ( > https://github.com/php/php-src/pull/9789), but have been invited by > @damianwadley to bring it to the mailing list. > > The Scorecards GitHub Action basically keeps an eye on a repo's security > posture and makes simple, objective suggestions for possible improvements. > > For PHP's current Scorecard results, see here: > https://api.securityscorecards.dev/projects/github.com/php/php-src. At the > moment it's a raw json dump, but it contains information on the results of > all the individual checks as well as comments on how to improve the scores. > When the Action is installed, this is cleanly added to the project's GitHub > Security Panel with step-by-step instructions. > What actionable benefit could this provide the project? Letting contributors know that some issues weren't responded to within 24 hours or something? I mean... none of us are paid to do that. Of course Google OSS projects have that kind of response, there's a trillion dollar company paying people to do that. But it's not like seeing a notification about something like that would provide php-src with actionable information. If we miss a metric that it's concerned about... who is responsible for doing something about it? Obviously the project is very active, and we have a lot of people who contribute, and we often do have quick responses between all the volunteers for things that need to be done quickly. But metrics and guarantees? If Christoph goes on vacation and Nikita is busy with work and Dmitry hasn't checked for notifications for a few days and everyone else thinks that one of them should weigh in first, then what would such a score actually tell us about the project? That we don't have employees responsible for those tasks? We already know that. What would forcing maintainers to go through a PR and review process for the types of changes that normally get pushed directly to master provide? A way for third parties to weigh in? Can't they already do that through the mailing list, issues, and PRs? If Google wants to help the PHP project, helping the project is probably better than supplying a tool that makes volunteers feel obligated in ways that employees do. Joe, Christoph, Dmitry, Nikita, Dan, etc all of these people with deep knowledge of the project and its history are critical to the project, but none of them are beholden to it. We were all sad to hear that Nikita's focus would shift with his new professional opportunities, but that doesn't mean he was wrong to take those opportunities or that he owed anything more than he was willing to give to the project. I just don't see what tangible benefit or actionable information something like this could provide. It's neat, and interesting, and maybe a bit of a novelty. But as part of an organizational workflow for the PHP project... why? Jordan
Re: [PHP-DEV] Should the engine be able to pass variables by reference of userland functions
On Wed, Oct 19, 2022 at 7:37 AM Kamil Tekiela wrote: > Hi, > > I am not sure if we should still support it. But I don't think it's > unthinkable to expect such feature from PHP. However, personally, I don't > find pass-by-ref that useful in general. The question is whether this > feature is used a lot in the wild. > > If we decide to drop support for this, it should probably go through a > deprecation phase. > > Regards, > Kamil > Pass by-ref is used a LOT in the wild, but I didn't interpret George's question as "should we remove pass by-ref from userland entirely". Surely the engine also supports pass by-ref somewhere in the VM as well as the place that was mentioned, it just does it in a different way? Jordan
Re: [PHP-DEV] RFC [Discussion]: Randomizer Additions
On Tue, Oct 18, 2022 at 10:22 AM Tim Düsterhus wrote: > > This cannot be reasonably done in userland, because you pay an increased > cost to turn the bytes into numbers and then to perform the necessary > bit fiddling to debias the numbers. > To add to this, I'm going to link to a userland implementation I wrote for my Fermat library. A couple of notes: 1. I am not at all claiming to be a subject matter expert, and this was my first pass at the feature, not a fully researched and optimized version. 2. The main issue at hand for me was that my 'numbers' could be arbitrary precision, which would require me to directly ask for bytes and then pull out numbers from them depending on the number of integer digits possible within the range. https://github.com/JordanRL/Fermat/blob/5d186eac99ceb98b089865099c2d7622428bfdaa/src/Samsara/Fermat/Provider/RandomProvider.php#L128 Now again, this was my first pass, but the way I tackled this was to get a string of bytes that fully contained the integer range. The issue of debiasing the numbers with that approach is *so* difficult, that I opted instead to simply recursively call the operation until a number within the desired range was generated. This avoids introducing bias, but is obviously less than optimal. Some kind of ability to directly provide a set of possible characters and generating from bytes directly would at least reduce the recursion space further in my case, though my particular algorithm still needs additional improvement obviously. Generating random numbers that have an arbitrary range is not easy, particularly if your range might exceed PHP_INT_MAX. *Any* utilities that core can provide to improve performance and reduce the number of places that bias might be introduced in such a situation would be much appreciated. Personally, I decided for my implementation that introducing bias was a greater concern than performance. Jordan
Re: [PHP-DEV] [VOTE] Improve unserialize() error handling
Sorry for double send Nicolas, I hit reply instead of reply-all on my first message. :) On Mon, Oct 17, 2022 at 1:57 AM Nicolas Grekas wrote: > > Yes, the specific error message should be part of the BC promise. This > allows building test suites that can assert the message in a stable way. > This is also why we don't change the output of var_dump/print_r/var_export: > they're written now, in the same of BC, for the best of stability. (I've > barely read any PHP code where exception's code is used in any useful BTW - > that can't be a solution.) > While I *definitely* sympathize with the "BC break" for tests, this doesn't actually break *code* unless you are switching behaviors in catch based on specific exception messages, which does not seem like a workflow that PHP needs to guarantee, as that is not the purpose of exception messages. Moreover, the actual messages change in php-src all the time in PR's, sometimes in PR's not even attached to RFCs. This has not, to my knowledge, ever been previously considered a BC promise, and it certainly hasn't ever been treated that way. If php-src took the position you are saying here, then any error message in PHP would need to remain constant until major versions, and we also probably could change between NOTICE, WARNING, or anything like that, as it would present similar issues. This would make it a BC break to provide deprecations ahead of the major versions, unless we did an *entire* version ahead, which I do not think is worth the benefit of providing that level of BC guarantee personally. As I said, I definitely sympathize with your tests example, because I have had libraries I work on with similar tests that break and/or are fragile due to the message changing. But the situations in which I was doing this in tests I realized were all because I was throwing the *same* exception for *different* problems and trying to ensure which path caused the throw within the test. In that case, I refactored the code to provide subclasses of that exception instead so they could be differentiated, which was the much more maintainable way to handle it. Basically, this change may break the Symfony tests here, and could definitely break other tests as well, but the tests it breaks are incorrect tests in my opinion, and don't actually guarantee the correctness that the green result implies. It is unlikely to break *code* (not tests) in ways that it wasn't already broken before. (Tim has explained this, RE: unserialization of various possible inputs). I still have yet to see an example (even a contrived one) in which this RFC would *introduce a failing path to code that wasn't there before* instead of *promote a hidden existing failing path into something that the developer can now respond to intelligently*. As far as I can tell from the examples provided so far, this RFC reduces the failing paths of 8.2 -> 8.3 code by promoting and exposing those paths to existing tests in a way that actually matches the documentation for unserialize. I might be still misunderstanding some nuance here. Jordan
Re: [PHP-DEV] Feature preview (formely was: experimental features)
On Tue, Oct 11, 2022 at 6:44 PM David Rodrigues wrote: > > Partially. As the usage definition has not yet been decided between > private(set) vs. private:set, so this feature is not ready for preview. > Unless the idea of allowing the two syntaxes to co-exist in this feature is > acceptable (which I personally think is a bad idea). > > If a "preview" doesn't allow us to make breaking changes, then what exactly is the point? I don't see any benefit at all to this without that. If the "preview" is *actually* just "put out an RFC in the next patch release as soon as it's merged to master", which is what it seems you're saying (as that seems like all that's left with all the things you said we can't do in a preview), then that seems dubious, prone to instability in the engine outside of the preview features, and a total breakage of the release cycle and RM process that is currently in place. Jordan
Re: [PHP-DEV] Experimental features
On Mon, Oct 10, 2022 at 5:05 PM David Gebler wrote: > On Tue, Oct 11, 2022 at 12:05 AM David Rodrigues > wrote: > > > The idea is that the experimental features are exclusively something that > > the PHP team has voted for (approved) and that will be part of the > language. > > > > So they're not experimental features, they're accepted RFCs, maybe with a > lower voting threshold. > > I don't really see what the confusion is about. It's for features that we have all agreed to include, but that the public API or behavior might change in minor versions while usage information, feedback, and so-on happens. The idea behind an experimental inclusion would be something like "the concept behind this feature we've agreed to include, unless something truly drastic comes up once it's out in the wild, but the syntax, parameters, and signatures might change while we look at usage and real-world code. It's like the opposite of a Deprecation notice in my mind... it's a flag on specific code that lets people know *ahead of time* that BC breaks in a minor version might be necessary for this feature for a little while. Jordan
Re: [PHP-DEV] Experimental features
On Thu, Oct 6, 2022 at 1:12 PM Rowan Tommins wrote: > On 06/10/2022 17:41, Alex Wells wrote: > > For example, Kotlin has recently introduced a new feature - unsigned > integer types. > > > I'm still struggling to understand what I, as a user, would do about this. > > If I start coding an application that relies on these new types, is > there a chance that they'll be removed completely, and I have to rewrite > it all? Is there a chance that every minor version I upgrade might > introduce subtle changes in the behaviour of my code? Or is there just a > chance that someone will decide the bikeshed's the wrong colour and I > have to regex replace all my "123u" to say "u123" instead? > > I would think all of the above, though I would expect given the nature of the RFC process that it would be exceedingly rare in PHP. It would be like a release preview only in a stable version. It does seem like it would have utility in PHP, since we could introduce a feature without worrying about BC breaks if it needs to be modified and adjusted. Jordan
Re: [PHP-DEV] Re: Issues with readonly classes
On Sun, Sep 25, 2022 at 10:57 AM Máté Kocsis wrote: > Hi, > > I agree with Tim, and I also think that both reverting and making any last > minute fundamental change is not a good idea, especially > because people don't have a clear agreement about how inheritance > should work. Readonly classes is an optional feature, so anyone > who wants proxies to work can simply not add the readonly flag to their > classes. Of course, it's a bit more tricky for library code, > but package authors should be aware of this gotcha. Having that said, I'll > try my best to fix the current shortcomings for PHP 7.3. > > Regards, > Máté > I tried hard to make it clear that I don't think this makes it "broken", it was just a deviation from my expectations and memory, both of which can obviously be flawed. I was mostly looking for some kind of information about what the reasoning was for this, given that I obviously (since I didn't remember it) missed that part of the discussion. The distinction between "readonly" and "immutable" is subtle, but fair. This distinction should probably be pointed out quite explicitly in the documentation though. If my default assumption (and Larry's) was that such a class would be immutable, it's fair to think that a non-trivial number of other programmers may make the same faulty assumption, and making this distinction obvious in the documentation would probably help. Jordan
Re: [PHP-DEV] Re: Issues with readonly classes
On Sun, Sep 11, 2022 at 8:22 AM Larry Garfield wrote: > > > Hm. I seem to recall during the discussion of readonly classes someone > saying that object properties of a readonly class had to also be readonly > classes, which would render the above code a compile error. However, I > just checked and that is not in the RFC. Was it removed? Am I imagining > things? Anyone else know what I'm talking about? :-) > > --Larry Garfield > > I remembered the same thing, and am similarly baffled. How did the RFC pass if you can do something as simple as `public readonly stdClass $var;`? I thought I followed the discussion on that RFC, but apparently I missed something. I would have expected an example like above to block acceptance of the RFC. To be clear though, I'm mostly confused about what the convincing argument about this was, or if it was something that everyone else viewed as an uncontroversial aspect? Jordan
Re: [PHP-DEV] Specify abstract parent methods for traits
On Sun, Sep 18, 2022 at 4:51 AM Mohammad Amin Chitgarha < machitgar...@gmail.com> wrote: > Hi. > > Currently, it's possible that, inside a trait's function, use the parent > method of a class using the trait. This way, not only it's implicitly > supposed the trait is used in a class having a parent, but also the parent > class has such a method. It doesn't seem to be a good practice, as stated > in the answers of this question ( > https://softwareengineering.stackexchange.com/questions/371067/should-a-trait-refer-to-parent-methods > ). > Also, it's almost impossible to override a parent method (using the same > signature) using a trait. This is useful if you have to inherit multiple > classes from a base class, but also override one (or more) of the base > methods with a common functionality provided by a trait. > There are some workarounds to these problems (specially talking about the > later one), but they have their own disadvantages: > Define a trait function with the same signature but a different name and > use it. The main disadvantage is that it's a different method, and is not > polymorphic. > Do (1), include the trait in the derived class(es), then override the > parent method in all derived classes and manually call the trait function. > Not perfect because you have to copy the same code for all derived classes. > > Stick with parent:: in the trait function. Implicit and not good (e.g. > static analyzers and IDEs cannot help). > > Change the parent class to use traits. This is not always possible, as it > might be someone else's code. > > Ignore this please: copy and paste the method all over the place. > > It's also not possible to use things like insteadof or as when including > the trait. > > Here, I want to propose the concept of explicitly declaring the parent > method. The way to achieve this is to use attributes for trait functions, > e.g. #[Override]. > It has the advantage of not requiring the redeclaration of the parent > method as abstract. However, it should be not allowed to use as clause when > including the trait function, as it's against the definition of overriding > a method (i.e. it must have the same name and visibility). > Another method is using a new parent specifier (i.e. abstract parent > public function …), and is more (?) consistent with the current behaviour. > However, it requires duplicating the parent method signature. > There could be methods using insteadof or as, but they has nothing to do > with the trait itself, and doesn't fix the problem of implicit declaration > of the parent method in the trait. > Thanks, > Mohammad Amin Chitgarha. > I can't quite understand what it is you want to accomplish. To make traits work better with parent classes of the classes they are used in? If so, my answer would be that traits aren't supposed to be used in that way in the first place, so any difficulty in doing so isn't a problem to be fixed. A trait should, in theory, (in my own opinion) be able to be used in any class, regardless of semantic correctness. That is, it should not produce compile time or run time errors related to class structure no matter what class it is used on. If a trait fails that test, it is a misuse of the feature in my opinion, and changes to traits that delay that error reporting are not beneficial in my opinion. This is just trying to use traits to make PHP multiple inheritance, but the PHP object model is fundamentally single inheritance. If you want to move PHP towards multiple inheritance, my preference would be to actually do *that* instead of making traits even more difficult and dangerous to use correctly. Jordan
Re: [PHP-DEV] make install overwriting php.ini
On Fri, Sep 16, 2022 at 6:27 PM Mark Tomlin wrote: > To the release managers of PHP, please make sure that you do not overwrite > the php.ini file. Making the php.ini.defaults file in the */usr/local/lib* > is fine, but overwriting it when running *make install* is going to break > some setups. This happened in both 8.2.0RC1 and now 8.2.0RC2. > > Please and thank you. > > -- > Thank you for your time, > Mark 'Dygear' Tomlin; > I thought the `php.ini.defaults` file was owned by the PHP build process, and the proper way to use it is to copy it before modifying? I'm fairly certain that's documented. This sounds like a "do it the wrong way at your own risk" type thing? Jordan
Re: [PHP-DEV] Error behaviour for max_input_vars
On Wed, Sep 14, 2022 at 12:33 PM Tim Düsterhus wrote: > Hi > > On 9/14/22 20:44, Jordan LeDoux wrote: > > Honestly, another question I'm thinking about at the moment is whether > it's > > possible to construct an attack against known script behavior if you also > > are able to determine the ini config at which partial form data would > make > > it to the script with the script thinking it has full form data. To be > > clear, I haven't been able to think of one, but I also recognize that I'm > > not nearly as clever at those sorts of things as some attackers are. > > Maybe I misunderstood what you are thinking about, but can't you just … > not send all the fields to achieve exactly the same results as an attacker? > > Best regards > Tim Düsterhus > Yes, probably. That's why I was saying, I know I'm not as clever with that space. I think those would be equivalent cases, but I'm not sure if there are any edgecases there either. Maybe that thought wasn't appropriate for the ML, since I'm not suggesting there is a problem, I'm mostly just wondering if someone with more expertise can confirm that it isn't an issue. Jordan
Re: [PHP-DEV] Error behaviour for max_input_vars
On Wed, Sep 14, 2022 at 11:38 AM Larry Garfield wrote: > > I think the key question here is if there is a reasonable action the > developer could take if an over-sized request came in. PHP itself can dump > that to the log, but is there anything reasonable beyond that the developer > could do, if they could detect it? > > And is anyone doing that now? > > --Larry Garfield > > Honestly, another question I'm thinking about at the moment is whether it's possible to construct an attack against known script behavior if you also are able to determine the ini config at which partial form data would make it to the script with the script thinking it has full form data. To be clear, I haven't been able to think of one, but I also recognize that I'm not nearly as clever at those sorts of things as some attackers are. I suppose that would depend on both the form and the script though. Jordan
Re: [PHP-DEV] Error behaviour for max_input_vars
On Tue, Sep 13, 2022 at 4:01 PM Derick Rethans wrote: > On 13 September 2022 19:36:15 BST, juan carlos morales < > dev.juan.mora...@gmail.com> wrote: > >El mar., 13 de septiembre de 2022 15:33, juan carlos morales < > >dev.juan.mora...@gmail.com> escribió: > > > >> > >> > >> El mar., 13 de septiembre de 2022 14:58, Mel Dafert > >> escribió: > >> > >>> > >>> In summary, I believe this can only be solved inside of PHP itself, by > >>> allowing to configure a way for `max_input_vars` to abort the request > >>> instead of truncating the input. > >>> The options I see feasible are: > >>> - A new ini setting `max_input_vars_abort` (default to 0), which, if > set > >>> to 1, will abort the request if there are more input variables than > >>> allowed. > >>> - A method to reliably detect whether the input vars were truncated > (eg. > >>> `function has_post_been_truncated(): bool`), so the application can > >>> decide whether to abort or not. > >>> - Deciding that `max_input_vars` is not relevant anymore and should be > >>> handled by the likes of Apache and NGINX, thus changing the default to > >>> `0` and removing the setting > >>> over a deprecation period. > >>> > >>> I am leaning towards the first option, but would be open to either > >>> outcome. > >>> > >> > >> > >> We should not delete the ini setting "max_input_vars"... Is a breaking > >> change very hard. > >> > >> I Am in favour of adding More flexibility about how to handle this > >> situation... And I also think that options 1 and 2 can coexist smoothly. > >> > >> I suggest you write and RFC for this and continue the discussion on this > >> e-mail list but with the RFC already created. > >> > > > > > >Check this out > > > >https://wiki.php.net/rfc/howto > > That's quite a condescending thing to say, considering that Mel has > already successfully passed an RFC ( > https://wiki.php.net/rfc/intldatetimepatterngenerator). > > cheers > Derick > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > > I didn't know that either! That also makes my comment about version inclusion a bit condescending. Sorry Mel! Jordan
Re: [PHP-DEV] Error behaviour for max_input_vars
On Tue, Sep 13, 2022 at 10:59 AM Mel Dafert wrote: > > (This happens in the legacy application I am working on, I do not > see it changing anytime soon.) > > All of these solutions would be available in some future version of PHP. While your situation highlights something that might be broadly applicable to PHP, you'd likely have to update the legacy application to take advantage of any solution that was eventually included so that it could run on the most recent version of PHP. Unless you're suggesting that this would also be backported? 7.4 falls out of all support in a few months. Just want to make sure you're aware of how the inclusion process would work for any solution to this issue. Jordan
Re: [PHP-DEV] xoshiro** edge case (all zeros)
On Thu, Aug 4, 2022 at 1:33 PM Hans Henrik Bergan wrote: > dangerous to be sure, but it's also a technically valid seed, > are you sure we should disallow a valid seed? > > How is it a valid seed if it creates invalid outputs?
Re: [PHP-DEV] RFC Idea - is_json - looking for feedback
On Sun, Jul 31, 2022 at 11:23 AM juan carlos morales < dev.juan.mora...@gmail.com> wrote: > - Benchmark including memory_get_peak_usage - > > # json_decode() > > Megas used before call: 79.23828125 > PEAK Megas used before call: 128.00390625 //< > Megas used after call: 3269.23828125 > PEAK Megas used after call: 3309.23828125 //< > Difference: 3190 > PEAK Difference: 3181.234375 //<- > Time: 12.109144926071 seconds > > # is_json() > > Megas used before call: 79.23828125 > PEAK Megas used before call: 128.00390625 //< > Megas used after call: 79.23828125 > PEAK Megas used after call: 128.00390625 //< > Difference: 0 > PEAK Difference: 0 //<- > Time: 5.4504480361938 seconds > This is actually suggesting a compelling case to me if this held up under close inspection of the code. You've certainly shown that it solves a problem that userspace is sort of half-solving, due to the limitations of the language around memory. > I want to clarify, as I previously mentioned, I did not develop any parser > at all, the parser already exists in PHP and is use by json_decode(), in > short words , what I propose is to create a new function, as an interface > to THE EXISTING PARSER, only, and only, to check if a string is a valid > json-string or not. > This is curious... the existing parser *should* need to allocate the memory. This makes me wonder if the above performance would hold up under scrutiny, *but* you have fully convinced me at the point (not that I have a vote) that it's worth the RFC to explore it. > Regarding publishing the a PR with my implementation, is out of context at > the moment, because we are discussing if a functionality like this should > be included or not, and nothing else. Also I am pretty sure that if this > gets a YES from the community (so far seems so), and I show my > implementation, someone will tell me that it could be done in a different > way , and is totally fine, is great actually. But now, at this moment, > everything is about the functionality. > Ah, okay. That I understand, even if I find it a tad frustrating. You want to understand if people are on-board with the merits of the idea without it being attached to your particular proof-of-concept code. If I'm reading the feedback correctly though, I think that any votes the RFC received would be heavily dependent on the eventual implementation and its performance though. So I think the RFC will be pretty closely tied to an implementation regardless of your efforts. Jordan
Re: [PHP-DEV] RFC Idea - is_json - looking for feedback
On Fri, Jul 29, 2022 at 7:27 AM juan carlos morales < dev.juan.mora...@gmail.com> wrote: > # Why this function ? > > At the moment the only way to determine if a JSON-string is valid we have > to execute the json_decode() function. > > The drawback about this, is that json_decode() generates an in memory an > object/array (depending on parameters) while parsing the string; this leads > to a memory usage that is not needed (because we use memory for creating > the object/array) and also can cause an error for reaching the memory-limit > of the php process. > > Sometimes we just need to know is the string is a valid json or not, and > nothing else. > You say that you have a first-pass at the implementation done. I'd be curious to see it. My initial thought was that in order to validate the string, you likely need to allocate extra memory as part of the validation that depends on the string size. You'd definitely save the overhead of a ZVAL, but for such an object that overhead is likely negligible. So I guess my question would be: in the actual implementation that lands, how much memory would this actually save compared to json_decode()? This seems like it would make the RFC tricky, as the purported benefit of the RFC depends very tightly on the implementation that lands. Jordan
Re: [PHP-DEV] [RFC] [VOTE] Constants in traits
On Tue, Jul 5, 2022 at 2:39 PM shinji igarashi wrote: > Hello internals, > > I've started the vote for the Constants in Traits RFC: > https://wiki.php.net/rfc/constants_in_traits > > The vote will end on 19. July 2022. > > Thanks! > > -- > Shinji Igarashi > > I don't have a vote, but I wanted to address this concern about the "usefulness" of traits, since the *voting* stage is rather the wrong place to bring up the idea that the existence of the feature itself is a negative. In my view, the "correct" way to use traits is for them to be entirely self-contained. That is, if you can put the trait in *any* class, and have that trait work as intended *even if* it makes no semantic sense to do so, then it's a good trait. This is currently somewhat difficult to do in certain situations. Some of the things the trait may need must live outside the trait, such as constants. This fact promotes further problematic usage of the feature. Requiring something like class constants to be external to the trait *forces* the kind of trait designs that they have complained about. Voting "no" because you want to see the feature removed instead is counter-productive to the process of improving the language itself if the RFC in question helps correct an oversight of the original feature design as stated by the original implementer of this feature and helps to promote more non-problematic usage of the feature. I don't know how else to view that position except for wanting to keep design flaws in a feature so that you have additional arguments in the future to remove it. Jordan
Re: [PHP-DEV] NULL Coercion Consistency
On Thu, May 26, 2022 at 5:21 AM Craig Francis wrote: > > It sounds like you got lucky - you have a function that has a problem with > NULL (but I assume it's fine with an empty string?), and during your > testing you happened to pass NULL to this function. As noted before, static > analysis is *considerably* better at these types of checks, because it's > able check if variables *can* contain NULL. They can also perform other > checks as well (important when your code seems to care about NULL vs an > empty string). > > Nearly *all* code has a problem with null. It very much feels like the original effort to deprecate null calls decided to resolve this by saying "let's have the language help developers improve their code so it doesn't have these problems in the first place", and this effort is trying to resolve this by saying "let's have the language support the buggy code in ways that makes it work". At my job, my task for the last three weeks has literally been upgrading our internal codebase for 8.1, and the biggest set of logs I'm dealing with is exactly what you're talking about here: null's passed to internal functions. Every single case I've looked at so far has been traced to code that was written incorrectly, where some code somewhere was not properly guarding its values, and error cases were slipping through. Jordan
Re: [PHP-DEV] The future of objects and operators
On Fri, May 13, 2022 at 7:05 AM Rowan Tommins wrote: > > I like Larry's "4 levels", but I've been thinking that there's some > existing functionality in PHP which takes a different direction: rather > than overloading *operators*, the language lets you overload *behaviour*. > We have magic methods like __get and __call, and interfaces like Iterator, > Countable, and ArrayAccess. Some hook into a particular function, or even > operator, but they're generally described in terms of what they do, not > what they look like, if you see what I mean. > > From that point of view, overloading comparison and equality *behaviour* > makes sense - it could affect not just the == and <=> operators, but things > like in_array() and sort(). I think this distinction is more pronounced in > PHP than some languages, because the standard library isn't "self-hosted": > a sort() call doesn't literally compile to a call to $a <=> $b > > I have been thinking about something similar, but not in the context of making operator overloads more like behavior overloads. Rather, I've been considering the idea that operator overloads are a *subset* of *engine overloads*. Ways that the developer can provide additional details to the engine about the behavior of their code that allows the engine to make more concrete assumptions about how it should be processed and interpreted. I started thinking about this mainly from the perspective of the syntax. I proposed the `operator +()` syntax in my overloads RFC, but my most compelling argument about the reason for it was sort of obscured because it was wrapped up in only overloads. To that end, I was considering more broadly what *all* magic methods are on objects: handlers. In fact, in the Zend engine that's how many of the same sorts of behaviors are described, as object handlers. Most of the standard library functions don't make calls for such handlers. For instance, sort() makes a call to zend_compare, and zend_compare ends up making a call to the compare handler on the relevant object. So I was at least considering the idea of a more broad replacement of the syntax for object behaviors, just not for an RFC related to overloads... such an RFC would have its own difficulties and controversy, and would almost certainly require a period of dual syntax support for old magic method syntax, making the arguments against very easy while the benefits would be more long term and less immediately apparent. > It's less obvious how that applies to mathematical operators - should > implementing "addition" allow an object to be used with array_sum() > perhaps? And what about deriving one operation from another, e.g. $foo*3 > running $foo+$foo+$foo, or $foo**3 running $foo*$foo*$foo? > > I don't really have a conclusion here, I just wanted to throw it out there > as a different mental model to consider. > > This would only be true for numerics, but not other kinds of math, such as matrices. Mathematical operators really are something that require direct calls and direct overloads if they are supported in any way, unless the language is willing to essentially never have things like complex numbers, matrices, etc. even in extensions. Still, it's an interesting thought and definitely the kind of high-level discussion I was looking for. Jordan