mathjs
mathjs copied to clipboard
[BREAKING] chore: adopt proposed new config option organization
This PR:
- deprecates most existing config options, allowing for a translation table into the newly-supported options
- reorganizes almost all options into one of three groups:
parse,compute, orcompatibility, to indicate what aspect of the system it controls. The only exception is thenumberoption giving the global default number type, as it affects both parsing (math.evaluate('2 + 2')) and computation (math.sum([])), per the proposal in issue 3420. So that option is not deprecated and remains at the top level. - adds the
compute.numberApproximateoption to control the type of output when theconfig.numberoption is not suitable. Currently this is only used for physical constants (since there is no input on which to base their type, and there is no guarantee thatconfig.numberwill support their values), but it is planned for use with square roots of bigints, for example. - validates all config options and adds warning for unrecognized options
- updates all documentation and tests and typescript typing
- conforms the behavior of statistics functions
min,max,sum, andprodwith all other mathjs functions at the moment so that strings are interpreted by way of typed-function's conversion rules, rather that mathjs' parsing rules. (There is a proposal to switch to the latter across the board; but in the meantime, mathjs functions should be consistent with each other.) - adds the
zero()function (to streamline the update ofisPositiveandisNegative; it was pending on another PR anyway) - implements unaryMinus correctly on boolean, to match the implementation of unaryPlus
- Prevents
simplifyConstantfrom changing intentional Fraction constants back into the default number type, potentially introducing roundoff errors. For this sake, it internally "advises" some of the Fraction methods so it can track whether a given Fraction in the result came from Fractions that were autogenerated from numbers (and so should be converted back to the default number type) or were in the original expression as Fraction constants. All this advice is removed before simplifyConstant returns. If the reviewer is uncomfortable with this approach, there are alternatives that do not touch the Fraction prototype even temporarily. For example, we could create an explicit datatype used for the folded constants that externally, rather than internally (by a property on the Fraction object) tracks whether they came from non-Fraction number constants. It would just be significantly more new code in simplifyConstant.js. You might reasonably ask how this change became entangled with this particular PR -- it's because the number-type config parameters have changed, and the old ones were used in selecting how to turn a Fraction into other types at the end of simplification, and in trying to update that code, I discovered the bug that actual Fractions in the original expression could be transformed into (say) JavaScript number in the result. It seemed like an opportune time to fix the bug. - adjusts the docgenerator so that the list of config options, which is already long and will be getting longer, only has to be documented in one place (the docs/core/configuration.md list is copied into the reference/function/config.md page). This will ease adding new options and prevent the inevitable drift of differences (that was already underway) between the two locations.
- Adjusts the
create()function so that it initially creates with the default config and then loads the supplied config, so that the supplied config can undergo the same option translation and validation processes as happens with explicit calls to theconfig()function. - discontinues the previously-deprecated
epsilonoption; note the option is still noticed and throws a discontinuation error if someone tries to set it. - deprecates the
config.compatibility.subsetoption so that in 2+ future major versions it can be discontinued. - eliminates the config.MATRIX_OPTIONS and config.NUMBER_OPTIONS properties in favor of a comprehensive config.ALLOWED_CONFIG property that shows all allowed options and the validity condition on each one.
- removes the config dependency from several functions that were not actually using it
- Downgrades to Complex number precision on out-of-real-range trigonometric functions on BigNumber arguments, rather than just returning BigNumber(NaN), to conform with all other functions (e.g. log).
As reminders, the rationales for this option reorganization are:
- To pave the way for a host of parsing configuration options to move off of the
parse()function and into theconfig.parseoption group, so that they will be more clearly documented and exposed to the library users, and cannot be changed on the library static instance (cf. #3420) - To make room for per-type tolerance parameters with systematic notation in the
config.compute.TYPENAMEgroups, including for the built-innumbertype, without clashing with the top-levelnumberoption (cf. #3556) - To provide for a minimal collection of type-choosing parameters that cover known use cases:
config.numberat the top level affecting both parsing and computation,config.parse.numberFallbackfor interpreting decimal literals when theconfig.numbertype does not support them, andconfig.compute.numberApproximatefor the return types of functions when the input does not necessarily determine the type and the result may not be representable asconfig.number(e.g.,math.evaluate(sqrt(5))whenconfig.number()isbigint).
When this is reviewed, adjusted as necessary, and merged into v16, work can resume on (a replacement for) #3423, which will (for example) systematize the tokenization of operators like ?. that end in a dot, as well as allow new token types (such as #HHHHHH for color constants) on the part of library users.