Provides the infrastructure to allow annotating the return types of functions, and does so for essentially every operation in the system (the only known exceptions being add, multiply, etc., on arbitrarily many arguments).
One main infrastructure enhancements are bounded template types, e.g. `T:number` being a template parameter where T can take on the type `number` or any subtype thereof.
A main internal enhancement is that base template types are no longer added to the typed universe; rather, there is a secondary, "meta" typed universe where they live. The primary point/purpose of this change is then the necessary search order for implementations can be much better modeled by typed-function's search order, using the `onMismatch` facility to redirect the search from fully instantiated implementations to the generic catchall implementations for each template (these catchalls live in the meta universe).
Numerous other small improvements and bugfixes were encountered along the way.
Co-authored-by: Glen Whitney <glen@studioinfinity.org>
Reviewed-on: #53
This means that the real and imaginary parts of a Complex must now be
the same type. This seems like a real benefit: a Complex with a number real
part and a bigint imaginary part does not seem sensible.
Note that this is now straining typed-function in (at least) the following
ways:
(1) In this change, it was necessary to remove the logic that the square root
of a negative number calls complex square root, which then calls back
to the number square root in its algorithm. (This was creating a circular
reference in the typed-function which the old implementation of Complex
was somehow sidestepping.)
(2) typed-function could not follow conversions that would be allowed by
uninstantiated templates (e.g. number => Complex<number> if the latter
template has not been instantiated) and so the facility for
instantiating a template was surfaced (and for example is called explicitly
in the demo loader `extendToComplex`. Similarly, this necessitated
making the unary signature of the `complex` conversion function explicit,
rather than just via implicit conversion to Complex.
(3) I find the order of implementations is mattering more in typed-function
definitions, implying that typed-function's sorting algorithm is having
trouble distinguishing alternatives.
But otherwise, the conversion went quite smoothly and I think is a good demo
of the power of this approach. And I expect that it will work even more
smoothly if some of the underlying facilities (subtypes, template types) are
integrated into typed-function.
Includes a full implementation of a type-homogeneous Tuple type, using the template types
feature, as a demonstration/check of its operation.
Co-authored-by: Glen Whitney <glen@studioinfinity.org>
Reviewed-on: #45
Also adds a `mean()` operation so there will be at least one operation
that takes only a rest parameter, to exercise the ban on splitting
such a parameter between the stored value and new arguments.
Adds various tests of chains.
Resolves#32.
Relational functions are added using templates, and existing generic functions are made more strict with them. Also a new built-in typeOf function is added, that automatically updates itself.
Resolves#34.
Co-authored-by: Glen Whitney <glen@studioinfinity.org>
Reviewed-on: #41
Merging of Pocomath modules is eased by allowing one PocomathInstance to
be merged into another. That allows types, for example, to be exported
as a PocomathInstance (so there is no need for a special identifier
convention for types; they can be directly added with an installType
method). Also, larger modules can just be exported as an instance, since
there is more flexibility and more checking in merging PocomathInstances
than raw modules.
This allows types to be collected; prior to this commit they
were conflicting from different modules.
Uses this fix to extend sqrt to bigint, with the convention
that it is undefined for non-perfect squares when 'predictable'
is false and is the "best" approximation to the square root when
'predictable' is true. Furthermore, for negative bigints, you might
get a Gaussian integer when predictable is false; or you will just get
your argument back when 'predictable' is true because what other
bigint could you give back for a negative bigint?
Also had to modify tests on the sign in sqrt(Complex) and add functions
'zero' and 'one' to get types to match, as expected in #27.
Adds numerous tests.
Resolves#26.
Resolves#27.
Allows dependencies to be economically expressed and used.
For example, see the new definition of subtract.
Credit for the basic idea goes to James Drew, see
https://stackoverflow.com/a/41525264Resolves#21.
Also starts each PocomathInstance with no types at all, and uses the new
situation to eliminate the need for a Complex "base case".
Resolves#14.
Resolves#13.
Co-authored-by: Glen Whitney <glen@studioinfinity.org>
Reviewed-on: #15
This PR also uses such self-reference to define negate and add
for Complex numbers in a way that is independent of component types.
Also adds a bigint type and verifies that pocomath will then handle
Gaussian integers "for free".
Ensures that if one function is invalidated, then any that depend on it will be.
Co-authored-by: Glen Whitney <glen@studioinfinity.org>
Reviewed-on: #4