feat: Add and illustrate multiple ways of specifying implementations #19
@ -16,6 +16,10 @@ Furthermore, note that 'Complex' is implemented in a way that doesn't care about
|
||||
|
||||
This core could be extended with many more operations, and more types could be defined, and additional sub-bundles like `number/all.mjs` or clever conditional loaders like `complex/extendToComplex.mjs` could be defined.
|
||||
|
||||
Also see the comments for the public member functions of
|
||||
`core/PocomathInstance.mjs` for further details on the structure and API of this
|
||||
scheme for organizing a CAS.
|
||||
|
||||
Hopefully this shows promise. It is an evolution of the concept first prototyped in [picomath](https://code.studioinfinity.org/glen/picomath). However, picomath depended on typed-function allowing mutable function entities, which turned out not to be performant. Pocomath, on the other hand, uses typed-function v3 as it stands, although it does suggest that it would be helpful to extend typed-function with subtypes, and it could even be reasonable to move the dependency tracking into typed-function itself (given that typed-function already supports self-dependencies, it would not be difficult to extend that to inter-dependencies between different typed-functions).
|
||||
|
||||
Note the conception of Pocomath includes allowing one implementation to depend just on a specific signature of another function, for efficiency's sake (if for example 'bar(Matrix)' knows it will only call 'foo(Matrix)', it avoids another type-dispatch). That capability did not actually come up in this toy example, so it remains unimplemented, but it should and could easily be added.
|
||||
|
@ -28,15 +28,16 @@ export default class PocomathInstance {
|
||||
* @param {Object<string, Object<Signature, [string[], function]>>} ops
|
||||
* The only parameter ops gives the semantics of the operations to install.
|
||||
* The keys are operation names. The value for a key is an object
|
||||
* mapping (typed-function) signature strings to pairs of dependency
|
||||
* lists and implementation functions.
|
||||
* mapping (typed-function) signature strings to specifications of
|
||||
* of dependency lists and implementation functions.
|
||||
*
|
||||
* A dependency list is a list of strings. Each string can either be the
|
||||
* name of a function that the corresponding implementation has to call,
|
||||
* or a specification of a particular signature of a function that it has
|
||||
* to call, in the form 'FN(SIGNATURE)'. Note the function name can be
|
||||
* the special value 'self' to indicate a recursive call to the given
|
||||
* operation (either with or without a particular signature.
|
||||
* to call, in the form 'FN(SIGNATURE)' [not implemented yet].
|
||||
* Note the function name can be the special value 'self' to indicate a
|
||||
* recursive call to the given operation (either with or without a
|
||||
* particular signature.
|
||||
*
|
||||
* There are two cases for the implementation function. If the dependency
|
||||
* list is empty, it should be a function taking the arguments specified
|
||||
@ -45,6 +46,30 @@ export default class PocomathInstance {
|
||||
* requested functions as values, to a function taking the arguments
|
||||
* specified by the signature and returning the value.
|
||||
*
|
||||
* There are various specifications currently allowed for the
|
||||
* dependency list and implementation function:
|
||||
*
|
||||
* 1) Just a function. Then the dependency list is assumed to be empty.
|
||||
*
|
||||
* 2) A pair (= Array with two entries) of a dependency list and the
|
||||
* implementation function.
|
||||
*
|
||||
* 3) An object whose property named 'does' gives the implementation
|
||||
* function and whose property named 'uses', if present, gives the
|
||||
* dependency list (which is assumed to be empty if the property is
|
||||
* not present).
|
||||
*
|
||||
* 4) A call to the 'use' function exported from the this module, with
|
||||
* first argument the dependencies and second argument the
|
||||
* implementation.
|
||||
*
|
||||
* For a visual comparison of the options, this proof-of-concept uses
|
||||
* option (1) when possible for the 'number' type, (3) for the 'Complex'
|
||||
* type, (4) for the 'bigint' type, and (2) under any other circumstances.
|
||||
* Likely a fleshed-out version of this scheme would settle on just one
|
||||
* or two of these options or variants thereof, rather than providing so
|
||||
* many different ones.
|
||||
*
|
||||
* Note that the "operation" named `Types` is special: it gives
|
||||
* types that must be installed in the instance. In this case, the keys
|
||||
* are type names, and the values are objects with a property 'test'
|
||||
|
Loading…
Reference in New Issue
Block a user