Cleaning up Function Registry to Reducer interface

This commit is contained in:
Ozzie Gooen 2022-07-16 19:06:48 -07:00
parent d88fb95767
commit 5e8b46b7df
6 changed files with 18 additions and 48 deletions

View File

@ -50,8 +50,7 @@ module FooImplementation = {
let library = [fn]
}
let makeBindings = (previousBindings: Bindings.t): Bindings.t =>
previousBindings->FunctionRegistry_Core.Registry.makeModules(FooImplementation.library)
let makeBindings = FunctionRegistry_Core.Registry.makeBindings(_, FooImplementation.library)
let stdLibWithFoo = Bindings.emptyBindings->makeBindings

View File

@ -429,7 +429,7 @@ module NameSpace = {
module Registry = {
let toJson = (r: registry) => r->E.A2.fmap(Function.toJson)
let exportedSubset = (r: registry): registry => r |> E.A.filter(r => !r.requiresNamespace)
let _exportedSubset = (r: registry): registry => r |> E.A.filter(r => !r.requiresNamespace)
let definitionsWithFunctions = (r: registry) =>
r->E.A2.fmap(fn => fn.definitions->E.A2.fmap(def => (def, fn)))->E.A.concatMany
@ -439,7 +439,7 @@ module Registry = {
to the registry, then it's possible that there could be a match after the registry is
called. However, for now, we could just call the registry last.
*/
let matchAndRun = (
let _matchAndRun = (
~registry: registry,
~fnName: string,
~args: array<internalExpressionValue>,
@ -463,9 +463,15 @@ module Registry = {
}
}
let dispatch = (registry, (fnName, args): ReducerInterface_InternalExpressionValue.functionCall, env) => {
_matchAndRun(~registry=_exportedSubset(registry), ~fnName, ~args, ~env)->E.O2.fmap(
E.R2.errMap(_, s => Reducer_ErrorValue.RETodo(s)),
)
}
let allNamespaces = (t: registry) => t->E.A2.fmap(r => r.nameSpace)->E.A.uniq
let makeModules = (prevBindings: Reducer_Module.t, t: registry): Reducer_Module.t => {
let makeBindings = (prevBindings: Reducer_Module.t, t: registry): Reducer_Module.t => {
let nameSpaces = allNamespaces(t)
let nameSpaceBindings = nameSpaces->E.A2.fmap(nameSpace => {
let namespaceModule: NameSpace.t = {

View File

@ -7,3 +7,5 @@ let registry = Belt.Array.concatMany([
FR_Pointset.library,
FR_Scoring.library,
])
let dispatch = FunctionRegistry_Core.Registry.dispatch(registry)

View File

@ -1,31 +1,9 @@
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
type internalExpressionValue = InternalExpressionValue.t
// module Sample = {
// // In real life real libraries should be somewhere else
// /*
// For an example of mapping polymorphic custom functions. To be deleted after real integration
// */
// let customAdd = (a: float, b: float): float => {a +. b}
// }
/*
Map external calls of Reducer
*/
// I expect that it's important to build this first, so it doesn't get recalculated for each tryRegistry() call.
let registry = FunctionRegistry_Library.registry
let tryRegistry = ((fnName, args): InternalExpressionValue.functionCall, env) => {
FunctionRegistry_Core.Registry.matchAndRun(
~registry=FunctionRegistry_Core.Registry.exportedSubset(registry),
~fnName,
~args,
~env,
)->E.O2.fmap(E.R2.errMap(_, s => Reducer_ErrorValue.RETodo(s)))
}
let dispatch = (call: InternalExpressionValue.functionCall, environment, chain): result<
internalExpressionValue,
'e,
@ -35,22 +13,6 @@ let dispatch = (call: InternalExpressionValue.functionCall, environment, chain):
() => ReducerInterface_Date.dispatch(call, environment),
() => ReducerInterface_Duration.dispatch(call, environment),
() => ReducerInterface_Number.dispatch(call, environment),
() => tryRegistry(call, environment),
() => FunctionRegistry_Library.dispatch(call, environment),
])->E.O2.default(chain(call, environment))
}
/*
If your dispatch is too big you can divide it into smaller dispatches and pass the call so that it gets called finally.
The final chain(call) invokes the builtin default functions of the interpreter.
Via chain(call), all MathJs operators and functions are available for string, number , boolean, array and record
.e.g + - / * > >= < <= == /= not and or sin cos log ln concat, etc.
// See https://mathjs.org/docs/expressions/syntax.html
// See https://mathjs.org/docs/reference/functions.html
Remember from the users point of view, there are no different modules:
// "doSth( constructorType1 )"
// "doSth( constructorType2 )"
doSth gets dispatched to the correct module because of the type signature. You get function and operator abstraction for free. You don't need to combine different implementations into one type. That would be duplicating the repsonsibility of the dispatcher.
*/

View File

@ -1,6 +1,9 @@
module Module = Reducer_Module
let internalStdLib = Module.emptyModule->SquiggleLibrary_Math.makeBindings
let internalStdLib =
Module.emptyModule
->SquiggleLibrary_Math.makeBindings
->FunctionRegistry_Core.Registry.makeBindings(FunctionRegistry_Library.registry)
@genType
let externalStdLib = internalStdLib->Module.toTypeScriptBindings

View File

@ -21,6 +21,4 @@ let mathBindings: Bindings.t =
//TODO: This should be in a different place.
let makeBindings = (previousBindings: Bindings.t): Bindings.t =>
previousBindings
->Bindings.defineModule("Math", mathBindings)
->FunctionRegistry_Core.Registry.makeModules(FunctionRegistry_Library.registry)
previousBindings->Bindings.defineModule("Math", mathBindings)