From 835ce6b81fb0081065caf47b43576fce4f972e0f Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Tue, 19 Jul 2022 08:42:08 -0700 Subject: [PATCH 01/23] Added reducer to Function Registry --- .../FunctionRegistry/FunctionRegistry_Core.res | 17 +++++++++++++---- .../FunctionRegistry/Library/FR_Dict.res | 12 ++++++------ .../FunctionRegistry/Library/FR_Dist.res | 10 ++++++---- .../rescript/FunctionRegistry/Library/FR_Fn.res | 2 +- .../FunctionRegistry/Library/FR_List.res | 10 +++++----- .../FunctionRegistry/Library/FR_Number.res | 6 +++--- .../FunctionRegistry/Library/FR_Pointset.res | 4 ++-- .../FunctionRegistry/Library/FR_Scoring.res | 6 +++--- .../ReducerInterface_ExternalLibrary.res | 12 +++++++----- 9 files changed, 46 insertions(+), 33 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index 25eb87b7..ea43561e 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -47,6 +47,7 @@ type fnDefinition = { array, array, GenericDist.env, + Reducer_Expression_T.reducerFn, ) => result, } @@ -342,10 +343,15 @@ module FnDefinition = { } } - let run = (t: t, args: array, env: GenericDist.env) => { + let run = ( + t: t, + args: array, + env: GenericDist.env, + reducer: Reducer_Expression_T.reducerFn, + ) => { let argValues = FRType.matchWithExpressionValueArray(t.inputs, args) switch argValues { - | Some(values) => t.run(args, values, env) + | Some(values) => t.run(args, values, env, reducer) | None => Error("Incorrect Types") } } @@ -452,6 +458,7 @@ module Registry = { ~fnName: string, ~args: array, ~env: GenericDist.env, + ~reducer: Reducer_Expression_T.reducerFn, ) => { let relevantFunctions = Js.Dict.get(registry.fnNameDict, fnName) |> E.O.default([]) let modified = {functions: relevantFunctions, fnNameDict: registry.fnNameDict} @@ -468,7 +475,8 @@ module Registry = { } switch Matcher.Registry.findMatches(modified, fnName, args) { - | Matcher.Match.FullMatch(match) => match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, env)) + | Matcher.Match.FullMatch(match) => + match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, env, reducer)) | SameNameDifferentArguments(m) => Some(Error(showNameMatchDefinitions(m))) | _ => None } @@ -478,8 +486,9 @@ module Registry = { registry, (fnName, args): ReducerInterface_InternalExpressionValue.functionCall, env, + reducer: Reducer_Expression_T.reducerFn, ) => { - _matchAndRun(~registry, ~fnName, ~args, ~env)->E.O2.fmap( + _matchAndRun(~registry, ~fnName, ~args, ~env, ~reducer)->E.O2.fmap( E.R2.errMap(_, s => Reducer_ErrorValue.RETodo(s)), ) } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res index 4a52f187..69ceb9c6 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res @@ -52,7 +52,7 @@ let library = [ FnDefinition.make( ~name="merge", ~inputs=[FRTypeDict(FRTypeAny), FRTypeDict(FRTypeAny)], - ~run=(inputs, _, _) => { + ~run=(inputs, _, _, _) => { switch inputs { | [IEvRecord(d1), IEvRecord(d2)] => Internals.merge(d1, d2)->Ok | _ => Error(impossibleError) @@ -74,7 +74,7 @@ let library = [ FnDefinition.make( ~name="mergeMany", ~inputs=[FRTypeArray(FRTypeDict(FRTypeAny))], - ~run=(_, inputs, _) => + ~run=(_, inputs, _, _) => inputs ->Prepare.ToTypedArray.dicts ->E.R2.fmap(E.Dict.concatMany) @@ -96,7 +96,7 @@ let library = [ FnDefinition.make( ~name="keys", ~inputs=[FRTypeDict(FRTypeAny)], - ~run=(inputs, _, _) => + ~run=(inputs, _, _, _) => switch inputs { | [IEvRecord(d1)] => Internals.keys(d1)->Ok | _ => Error(impossibleError) @@ -116,7 +116,7 @@ let library = [ FnDefinition.make( ~name="values", ~inputs=[FRTypeDict(FRTypeAny)], - ~run=(inputs, _, _) => + ~run=(inputs, _, _, _) => switch inputs { | [IEvRecord(d1)] => Internals.values(d1)->Ok | _ => Error(impossibleError) @@ -136,7 +136,7 @@ let library = [ FnDefinition.make( ~name="toList", ~inputs=[FRTypeDict(FRTypeAny)], - ~run=(inputs, _, _) => + ~run=(inputs, _, _, _) => switch inputs { | [IEvRecord(dict)] => dict->Internals.toList->Ok | _ => Error(impossibleError) @@ -156,7 +156,7 @@ let library = [ FnDefinition.make( ~name="fromList", ~inputs=[FRTypeArray(FRTypeArray(FRTypeAny))], - ~run=(inputs, _, _) => + ~run=(inputs, _, _, _) => switch inputs { | [IEvArray(items)] => Internals.fromList(items) | _ => Error(impossibleError) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dist.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dist.res index 424983d8..9e10577b 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dist.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dist.res @@ -21,7 +21,8 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeDistOrNumber, FRTypeDistOrNumber], - ~run=(_, inputs, env) => inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env), + ~run=(_, inputs, env, _) => + inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env), (), ) } @@ -30,7 +31,7 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeRecord([("p5", FRTypeDistOrNumber), ("p95", FRTypeDistOrNumber)])], - ~run=(_, inputs, env) => + ~run=(_, inputs, env, _) => inputs->Prepare.ToValueTuple.Record.twoDistOrNumber->process(~fn, ~env), (), ) @@ -40,7 +41,7 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeRecord([("mean", FRTypeDistOrNumber), ("stdev", FRTypeDistOrNumber)])], - ~run=(_, inputs, env) => + ~run=(_, inputs, env, _) => inputs->Prepare.ToValueTuple.Record.twoDistOrNumber->process(~fn, ~env), (), ) @@ -57,7 +58,8 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeDistOrNumber], - ~run=(_, inputs, env) => inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env), + ~run=(_, inputs, env, _) => + inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env), (), ) } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Fn.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Fn.res index 512d564a..ee2ef343 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Fn.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Fn.res @@ -51,7 +51,7 @@ let library = [ FnDefinition.make( ~name="declare", ~inputs=[Declaration.frType], - ~run=(_, inputs, _) => { + ~run=(_, inputs, _, _) => { inputs->getOrError(0)->E.R.bind(Declaration.fromExpressionValue) }, (), diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res index 25924232..a181fb33 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res @@ -37,7 +37,7 @@ let library = [ FnDefinition.make( ~name="make", ~inputs=[FRTypeNumber, FRTypeAny], - ~run=(inputs, _, _) => { + ~run=(inputs, _, _, _) => { switch inputs { | [IEvNumber(number), value] => Internals.makeFromNumber(number, value)->Ok | _ => Error(impossibleError) @@ -58,7 +58,7 @@ let library = [ FnDefinition.make( ~name="upTo", ~inputs=[FRTypeNumber, FRTypeNumber], - ~run=(_, inputs, _) => + ~run=(_, inputs, _, _) => inputs ->Prepare.ToValueTuple.twoNumbers ->E.R2.fmap(((low, high)) => Internals.upTo(low, high)), @@ -76,7 +76,7 @@ let library = [ FnDefinition.make( ~name="first", ~inputs=[FRTypeArray(FRTypeAny)], - ~run=(inputs, _, _) => + ~run=(inputs, _, _, _) => switch inputs { | [IEvArray(array)] => Internals.first(array) | _ => Error(impossibleError) @@ -95,7 +95,7 @@ let library = [ FnDefinition.make( ~name="last", ~inputs=[FRTypeArray(FRTypeAny)], - ~run=(inputs, _, _) => + ~run=(inputs, _, _, _) => switch inputs { | [IEvArray(array)] => Internals.last(array) | _ => Error(impossibleError) @@ -115,7 +115,7 @@ let library = [ FnDefinition.make( ~name="reverse", ~inputs=[FRTypeArray(FRTypeAny)], - ~run=(inputs, _, _) => + ~run=(inputs, _, _, _) => switch inputs { | [IEvArray(array)] => Internals.reverse(array)->Ok | _ => Error(impossibleError) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Number.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Number.res index c7027f06..472ae60b 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Number.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Number.res @@ -9,7 +9,7 @@ module NumberToNumber = { FnDefinition.make( ~name, ~inputs=[FRTypeNumber], - ~run=(_, inputs, _) => { + ~run=(_, inputs, _, _) => { inputs ->getOrError(0) ->E.R.bind(Prepare.oneNumber) @@ -25,7 +25,7 @@ module ArrayNumberDist = { FnDefinition.make( ~name, ~inputs=[FRTypeArray(FRTypeNumber)], - ~run=(_, inputs, _) => + ~run=(_, inputs, _, _) => Prepare.ToTypedArray.numbers(inputs) ->E.R.bind(r => E.A.length(r) === 0 ? Error("List is empty") : Ok(r)) ->E.R.bind(fn), @@ -36,7 +36,7 @@ module ArrayNumberDist = { FnDefinition.make( ~name, ~inputs=[FRTypeArray(FRTypeAny)], - ~run=(_, inputs, _) => + ~run=(_, inputs, _, _) => Prepare.ToTypedArray.numbers(inputs) ->E.R.bind(r => E.A.length(r) === 0 ? Error("List is empty") : Ok(r)) ->E.R.bind(fn), diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res index dc4daead..2c41a475 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res @@ -41,7 +41,7 @@ let library = [ FnDefinition.make( ~name="makeContinuous", ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], - ~run=(_, inputs, _) => inputsTodist(inputs, r => Continuous(Continuous.make(r))), + ~run=(_, inputs, _, _) => inputsTodist(inputs, r => Continuous(Continuous.make(r))), (), ), ], @@ -64,7 +64,7 @@ let library = [ FnDefinition.make( ~name="makeDiscrete", ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], - ~run=(_, inputs, _) => inputsTodist(inputs, r => Discrete(Discrete.make(r))), + ~run=(_, inputs, _, _) => inputsTodist(inputs, r => Discrete(Discrete.make(r))), (), ), ], diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Scoring.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Scoring.res index d8d5ddd0..972501e9 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Scoring.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Scoring.res @@ -30,7 +30,7 @@ let library = [ ("prior", FRTypeDist), ]), ], - ~run=(_, inputs, env) => { + ~run=(_, inputs, env, _) => { switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.threeArgs(inputs) { | Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueDist(d)), FRValueDist(prior)]) => runScoring(estimate, Score_Dist(d), Some(prior), env) @@ -49,7 +49,7 @@ let library = [ FnDefinition.make( ~name="logScore", ~inputs=[FRTypeRecord([("estimate", FRTypeDist), ("answer", FRTypeDistOrNumber)])], - ~run=(_, inputs, env) => { + ~run=(_, inputs, env, _) => { switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs(inputs) { | Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueDist(d))]) => runScoring(estimate, Score_Dist(d), None, env) @@ -74,7 +74,7 @@ let library = [ FnDefinition.make( ~name="klDivergence", ~inputs=[FRTypeDist, FRTypeDist], - ~run=(_, inputs, env) => { + ~run=(_, inputs, env, _) => { switch inputs { | [FRValueDist(estimate), FRValueDist(d)] => runScoring(estimate, Score_Dist(d), None, env) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res index d6a14dea..fc0a2821 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res @@ -4,16 +4,18 @@ type internalExpressionValue = InternalExpressionValue.t /* Map external calls of Reducer */ -let dispatch = (call: InternalExpressionValue.functionCall, environment, reducer, chain): result< - internalExpressionValue, - 'e, -> => { +let dispatch = ( + call: InternalExpressionValue.functionCall, + environment, + reducer: Reducer_Expression_T.reducerFn, + chain, +): result => { E.A.O.firstSomeFn([ () => ReducerInterface_GenericDistribution.dispatch(call, environment), () => ReducerInterface_Date.dispatch(call, environment), () => ReducerInterface_Duration.dispatch(call, environment), () => ReducerInterface_Number.dispatch(call, environment), - () => FunctionRegistry_Library.dispatch(call, environment), + () => FunctionRegistry_Library.dispatch(call, environment, reducer), ])->E.O2.default(chain(call, environment, reducer)) } From f8d6db61c530660e36a5a24b88ecb84cf756db47 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Tue, 19 Jul 2022 10:35:31 -0700 Subject: [PATCH 02/23] Moved list functions into FunctionRegistry --- .../Reducer/Reducer_mapReduce_test.res | 9 -- ...leLibrary_FunctionRegistryLibrary_test.res | 6 + .../FunctionRegistry/Library/FR_List.res | 145 +++++++++++++++++- .../Reducer_Dispatch_BuiltIn.res | 50 ------ .../squiggle-lang/src/rescript/Utility/E.res | 1 + 5 files changed, 148 insertions(+), 63 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res index f3df0962..f89173d5 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res @@ -1,15 +1,6 @@ open Jest open Reducer_TestHelpers -describe("map reduce", () => { - testEvalToBe("double(x)=2*x; arr=[1,2,3]; map(arr, double)", "Ok([2,4,6])") - testEvalToBe("myadd(acc,x)=acc+x; arr=[1,2,3]; reduce(arr, 0, myadd)", "Ok(6)") - testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; reduce(arr, 0, change)", "Ok(15)") - testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; reduceReverse(arr, 0, change)", "Ok(9)") - testEvalToBe("arr=[1,2,3]; reverse(arr)", "Ok([3,2,1])") - testEvalToBe("check(x)=(x==2);arr=[1,2,3]; filter(arr,check)", "Ok([2])") -}) - Skip.describe("map reduce (sam)", () => { testEvalToBe("addone(x)=x+1; map(2, addone)", "Error???") testEvalToBe("addone(x)=x+1; map(2, {x: addone})", "Error???") diff --git a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res index d4f52e5c..b7c7b8d0 100644 --- a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res +++ b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res @@ -16,6 +16,12 @@ describe("FunctionRegistry Library", () => { testEvalToBe("List.first([3,5,8])", "Ok(3)") testEvalToBe("List.last([3,5,8])", "Ok(8)") testEvalToBe("List.reverse([3,5,8])", "Ok([8,5,3])") + testEvalToBe("double(x)=2*x; arr=[1,2,3]; List.map(arr, double)", "Ok([2,4,6])") + testEvalToBe("myadd(acc,x)=acc+x; arr=[1,2,3]; List.reduce(arr, 0, myadd)", "Ok(6)") + testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; List.reduce(arr, 0, change)", "Ok(15)") + testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; List.reduceReverse(arr, 0, change)", "Ok(9)") + testEvalToBe("check(x)=(x==2);arr=[1,2,3]; List.filter(arr,check)", "Ok([2])") + testEvalToBe("arr=[1,2,3]; List.reverse(arr)", "Ok([3,2,1])") testEvalToBe("Dist.normal(5,2)", "Ok(Normal(5,2))") testEvalToBe("normal(5,2)", "Ok(Normal(5,2))") testEvalToBe("normal({mean:5,stdev:2})", "Ok(Normal(5,2))") diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res index a181fb33..ba9918da 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res @@ -23,13 +23,67 @@ module Internals = { let reverse = (array: array): internalExpressionValue => IEvArray( Belt.Array.reverse(array), ) + + let map = (array: array, environment, eLambdaValue, reducer): result< + ReducerInterface_InternalExpressionValue.t, + Reducer_ErrorValue.errorValue, + > => { + let rMappedList = array->E.A.reduceReverse(Ok(list{}), (rAcc, elem) => + rAcc->E.R.bind(_, acc => { + let rNewElem = Reducer_Expression_Lambda.doLambdaCall( + eLambdaValue, + list{elem}, + environment, + reducer, + ) + rNewElem->E.R2.fmap(newElem => list{newElem, ...acc}) + }) + ) + rMappedList->E.R2.fmap(mappedList => mappedList->Belt.List.toArray->Wrappers.evArray) + } + + let reduce = (aValueArray, initialValue, aLambdaValue, environment, reducer) => { + aValueArray->E.A.reduce(Ok(initialValue), (rAcc, elem) => + rAcc->E.R.bind(_, acc => + Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer) + ) + ) + } + + let reduceReverse = (aValueArray, initialValue, aLambdaValue, environment, reducer) => { + aValueArray->Belt.Array.reduceReverse(Ok(initialValue), (rAcc, elem) => + rAcc->Belt.Result.flatMap(acc => + Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer) + ) + ) + } + + let filter = (aValueArray, aLambdaValue, environment, reducer) => { + let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) => + rAcc->E.R.bind(_, acc => { + let rNewElem = Reducer_Expression_Lambda.doLambdaCall( + aLambdaValue, + list{elem}, + environment, + reducer, + ) + rNewElem->E.R2.fmap(newElem => + switch newElem { + | IEvBool(true) => list{elem, ...acc} + | _ => acc + } + ) + }) + ) + rMappedList->E.R2.fmap(mappedList => mappedList->Belt.List.toArray->Wrappers.evArray) + } } let library = [ Function.make( ~name="make", ~nameSpace, - ~requiresNamespace, + ~requiresNamespace=true, ~output=EvtArray, ~examples=[`List.make(2, "testValue")`], ~definitions=[ @@ -51,7 +105,7 @@ let library = [ Function.make( ~name="upTo", ~nameSpace, - ~requiresNamespace, + ~requiresNamespace=true, ~output=EvtArray, ~examples=[`List.upTo(1,4)`], ~definitions=[ @@ -70,7 +124,7 @@ let library = [ Function.make( ~name="first", ~nameSpace, - ~requiresNamespace, + ~requiresNamespace=true, ~examples=[`List.first([1,4,5])`], ~definitions=[ FnDefinition.make( @@ -89,7 +143,7 @@ let library = [ Function.make( ~name="last", ~nameSpace, - ~requiresNamespace, + ~requiresNamespace=true, ~examples=[`List.last([1,4,5])`], ~definitions=[ FnDefinition.make( @@ -125,4 +179,87 @@ let library = [ ], (), ), + Function.make( + ~name="map", + ~nameSpace, + ~output=EvtArray, + ~requiresNamespace=false, + ~examples=[`List.map([1,4,5], {|x| x+1})`], + ~definitions=[ + FnDefinition.make( + ~name="map", + ~inputs=[FRTypeArray(FRTypeAny), FRTypeLambda], + ~run=(inputs, _, env, reducer) => + switch inputs { + | [IEvArray(array), IEvLambda(lambda)] => + Internals.map(array, env, lambda, reducer)->E.R2.errMap(_ => "Error!") + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ), + Function.make( + ~name="reduce", + ~nameSpace, + ~requiresNamespace=false, + ~examples=[`List.reduce([1,4,5], 2, {|acc, el| acc+el})`], + ~definitions=[ + FnDefinition.make( + ~name="reduce", + ~inputs=[FRTypeArray(FRTypeAny), FRTypeAny, FRTypeLambda], + ~run=(inputs, _, env, reducer) => + switch inputs { + | [IEvArray(array), initialValue, IEvLambda(lambda)] => + Internals.reduce(array, initialValue, lambda, env, reducer)->E.R2.errMap(_ => "Error!") + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ), + Function.make( + ~name="reduceReverse", + ~nameSpace, + ~requiresNamespace=false, + ~examples=[`List.reduceReverse([1,4,5], 2, {|acc, el| acc-el})`], + ~definitions=[ + FnDefinition.make( + ~name="reduceReverse", + ~inputs=[FRTypeArray(FRTypeAny), FRTypeAny, FRTypeLambda], + ~run=(inputs, _, env, reducer) => + switch inputs { + | [IEvArray(array), initialValue, IEvLambda(lambda)] => + Internals.reduceReverse(array, initialValue, lambda, env, reducer)->E.R2.errMap(_ => + "Error!" + ) + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ), + Function.make( + ~name="filter", + ~nameSpace, + ~requiresNamespace=false, + ~examples=[`List.filter([1,4,5], {|x| x>3})`], + ~definitions=[ + FnDefinition.make( + ~name="filter", + ~inputs=[FRTypeArray(FRTypeAny), FRTypeLambda], + ~run=(inputs, _, env, reducer) => + switch inputs { + | [IEvArray(array), IEvLambda(lambda)] => + Internals.filter(array, lambda, env, reducer)->E.R2.errMap(_ => "Error!") + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ), ] diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 0cefe5ee..0f3e1e4b 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -95,31 +95,6 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce let doExportBindings = (bindings: nameSpace) => bindings->Bindings.toExpressionValue->Ok - let doKeepArray = (aValueArray, aLambdaValue) => { - let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) => - rAcc->Result.flatMap(acc => { - let rNewElem = Lambda.doLambdaCall(aLambdaValue, list{elem}, environment, reducer) - rNewElem->Result.map(newElem => - switch newElem { - | IEvBool(true) => list{elem, ...acc} - | _ => acc - } - ) - }) - ) - rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->IEvArray) - } - - let doMapArray = (aValueArray, aLambdaValue) => { - let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) => - rAcc->Result.flatMap(acc => { - let rNewElem = Lambda.doLambdaCall(aLambdaValue, list{elem}, environment, reducer) - rNewElem->Result.map(newElem => list{newElem, ...acc}) - }) - ) - rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->IEvArray) - } - module SampleMap = { type t = SampleSetDist.t let doLambdaCall = (aLambdaValue, list) => @@ -172,22 +147,6 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce } } - let doReduceArray = (aValueArray, initialValue, aLambdaValue) => { - aValueArray->Belt.Array.reduce(Ok(initialValue), (rAcc, elem) => - rAcc->Result.flatMap(acc => - Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer) - ) - ) - } - - let doReduceReverseArray = (aValueArray, initialValue, aLambdaValue) => { - aValueArray->Belt.Array.reduceReverse(Ok(initialValue), (rAcc, elem) => - rAcc->Result.flatMap(acc => - Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer) - ) - ) - } - switch call { | ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex) | ("$_atIndex_$", [IEvBindings(dict), IEvString(sIndex)]) => moduleAtIndex(dict, sIndex) @@ -226,10 +185,6 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce doAddString(aValueString, bValueString) | ("inspect", [value, IEvString(label)]) => inspectLabel(value, label) | ("inspect", [value]) => inspect(value) - | ("filter", [IEvArray(aValueArray), IEvLambda(aLambdaValue)]) => - doKeepArray(aValueArray, aLambdaValue) - | ("map", [IEvArray(aValueArray), IEvLambda(aLambdaValue)]) => - doMapArray(aValueArray, aLambdaValue) | ("mapSamples", [IEvDistribution(SampleSet(dist)), IEvLambda(aLambdaValue)]) => SampleMap.map1(dist, aLambdaValue) | ( @@ -253,11 +208,6 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce SampleMap.map3(dist1, dist2, dist3, aLambdaValue) | ("mapSamplesN", [IEvArray(aValueArray), IEvLambda(aLambdaValue)]) => SampleMap.mapN(aValueArray, aLambdaValue) - | ("reduce", [IEvArray(aValueArray), initialValue, IEvLambda(aLambdaValue)]) => - doReduceArray(aValueArray, initialValue, aLambdaValue) - | ("reduceReverse", [IEvArray(aValueArray), initialValue, IEvLambda(aLambdaValue)]) => - doReduceReverseArray(aValueArray, initialValue, aLambdaValue) - | ("reverse", [IEvArray(aValueArray)]) => aValueArray->Belt.Array.reverse->IEvArray->Ok | (_, [IEvBool(_)]) | (_, [IEvNumber(_)]) | (_, [IEvString(_)]) diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index a3af26e9..50a28382 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -546,6 +546,7 @@ module A = { let slice = Belt.Array.slice let init = Array.init let reduce = Belt.Array.reduce + let reduceReverse = Belt.Array.reduceReverse let reducei = Belt.Array.reduceWithIndex let some = Belt.Array.some let isEmpty = r => length(r) < 1 From 7316d27b54ff3152be0b3699a730625e57f12b43 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Tue, 19 Jul 2022 15:52:28 -0700 Subject: [PATCH 03/23] Added SampleSet fns to FunctionRegistry --- .../FunctionRegistry_Helpers.res | 2 + .../FunctionRegistry_Library.res | 1 + .../FunctionRegistry/Library/FR_List.res | 4 +- .../FunctionRegistry/Library/FR_Pointset.res | 29 +++ .../FunctionRegistry/Library/FR_Sampleset.res | 193 ++++++++++++++++++ .../Reducer_Dispatch_BuiltIn.res | 39 ---- 6 files changed, 227 insertions(+), 41 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index 115d5307..1c06d3c0 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -4,6 +4,8 @@ let impossibleError = "Wrong inputs / Logically impossible" module Wrappers = { let symbolic = r => DistributionTypes.Symbolic(r) + let pointSet = r => DistributionTypes.PointSet(r) + let sampleSet = r => DistributionTypes.SampleSet(r) let evDistribution = r => ReducerInterface_InternalExpressionValue.IEvDistribution(r) let evNumber = r => ReducerInterface_InternalExpressionValue.IEvNumber(r) let evArray = r => ReducerInterface_InternalExpressionValue.IEvArray(r) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index 9b0f6737..9236ab84 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -5,6 +5,7 @@ let fnList = Belt.Array.concatMany([ FR_List.library, FR_Number.library, FR_Pointset.library, + FR_Sampleset.library, FR_Scoring.library, ]) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res index ba9918da..762fe31b 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res @@ -67,12 +67,12 @@ module Internals = { environment, reducer, ) - rNewElem->E.R2.fmap(newElem => + rNewElem->E.R2.fmap(newElem => { switch newElem { | IEvBool(true) => list{elem, ...acc} | _ => acc } - ) + }) }) ) rMappedList->E.R2.fmap(mappedList => mappedList->Belt.List.toArray->Wrappers.evArray) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res index 2c41a475..b90bc96c 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res @@ -70,4 +70,33 @@ let library = [ ], (), ), + Function.make( + ~name="maked", + ~nameSpace, + ~requiresNamespace, + ~examples=[`Pointset.maked(normal(5,2))`], + ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~definitions=[ + FnDefinition.make( + ~name="maked", + ~inputs=[FRTypeDist], + ~run=(_, inputs, env, _) => + switch inputs { + | [FRValueDist(dist)] => + GenericDist.toPointSet( + dist, + ~xyPointLength=env.xyPointLength, + ~sampleCount=env.sampleCount, + (), + ) + ->E.R2.fmap(Wrappers.pointSet) + ->E.R2.fmap(Wrappers.evDistribution) + ->E.R2.errMap(_ => "") + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ), ] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res new file mode 100644 index 00000000..e92551da --- /dev/null +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res @@ -0,0 +1,193 @@ +open FunctionRegistry_Core +open FunctionRegistry_Helpers + +let nameSpace = "Sampleset" +let requiresNamespace = true + +module Internal = { + type t = SampleSetDist.t + let doLambdaCall = (aLambdaValue, list, environment, reducer) => + switch Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list, environment, reducer) { + | Ok(IEvNumber(f)) => Ok(f) + | _ => Error(Operation.SampleMapNeedsNtoNFunction) + } + + let toType = (r): result< + ReducerInterface_InternalExpressionValue.t, + Reducer_ErrorValue.errorValue, + > => + switch r { + | Ok(r) => Ok(Wrappers.evDistribution(SampleSet(r))) + | Error(r) => Error(REDistributionError(SampleSetError(r))) + } + + let map1 = (sampleSetDist: t, aLambdaValue, env, reducer) => { + let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, env, reducer) + SampleSetDist.samplesMap(~fn, sampleSetDist)->toType + } + + let map2 = (t1: t, t2: t, aLambdaValue, env, reducer) => { + let fn = (a, b) => doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b)}, env, reducer) + SampleSetDist.map2(~fn, ~t1, ~t2)->toType + } + + let map3 = (t1: t, t2: t, t3: t, aLambdaValue, env, reducer) => { + let fn = (a, b, c) => + doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b), IEvNumber(c)}, env, reducer) + SampleSetDist.map3(~fn, ~t1, ~t2, ~t3)->toType + } + + let parseSampleSetArray = (arr: array): option< + array, + > => { + let parseSampleSet = (value: internalExpressionValue): option => + switch value { + | IEvDistribution(SampleSet(dist)) => Some(dist) + | _ => None + } + E.A.O.openIfAllSome(E.A.fmap(parseSampleSet, arr)) + } + + let mapN = (aValueArray: array, aLambdaValue, env, reducer) => { + switch parseSampleSetArray(aValueArray) { + | Some(t1) => + let fn = a => + doLambdaCall( + aLambdaValue, + list{IEvArray(E.A.fmap(x => Wrappers.evNumber(x), a))}, + env, + reducer, + ) + SampleSetDist.mapN(~fn, ~t1)->toType + | None => Error(REFunctionNotFound("")) + } + } +} + +let library = [ + Function.make( + ~name="maker", + ~nameSpace, + ~requiresNamespace, + ~examples=[`Sampleset.maker(normal(5,2))`], + ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~definitions=[ + FnDefinition.make( + ~name="maker", + ~inputs=[FRTypeDist], + ~run=(_, inputs, env, _) => + switch inputs { + | [FRValueDist(dist)] => + GenericDist.toSampleSetDist(dist, env.sampleCount) + ->E.R2.fmap(Wrappers.sampleSet) + ->E.R2.fmap(Wrappers.evDistribution) + ->E.R2.errMap(_ => "") + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ), + Function.make( + ~name="map", + ~nameSpace, + ~requiresNamespace, + ~examples=[`Sampleset.map(Sampleset.maker(normal(5,2)), {|x| x + 1})`], + ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~definitions=[ + FnDefinition.make( + ~name="map", + ~inputs=[FRTypeDist, FRTypeLambda], + ~run=(inputs, _, env, reducer) => + switch inputs { + | [IEvDistribution(SampleSet(dist)), IEvLambda(lambda)] => + Internal.map1(dist, lambda, env, reducer)->E.R2.errMap(_ => "") + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ), + Function.make( + ~name="map2", + ~nameSpace, + ~requiresNamespace, + ~examples=[ + `Sampleset.map2(Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2)), {|x, y| x + y})`, + ], + ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~definitions=[ + FnDefinition.make( + ~name="map2", + ~inputs=[FRTypeDist, FRTypeDist, FRTypeLambda], + ~run=(inputs, _, env, reducer) => { + Js.log2("WHY DIDNT IT MATCH", inputs) + switch inputs { + | [ + IEvDistribution(SampleSet(dist1)), + IEvDistribution(SampleSet(dist2)), + IEvLambda(lambda), + ] => + Internal.map2(dist1, dist2, lambda, env, reducer)->E.R2.errMap(_ => "") + | _ => Error(impossibleError) + } + }, + (), + ), + ], + (), + ), + Function.make( + ~name="map3", + ~nameSpace, + ~requiresNamespace, + ~examples=[ + `Sampleset.map3(Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2)), {|x, y, z| max([x,y,z]))`, + ], + ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~definitions=[ + FnDefinition.make( + ~name="map3", + ~inputs=[FRTypeDist, FRTypeDist, FRTypeDist, FRTypeLambda], + ~run=(inputs, _, env, reducer) => + switch inputs { + | [ + IEvDistribution(SampleSet(dist1)), + IEvDistribution(SampleSet(dist2)), + IEvDistribution(SampleSet(dist3)), + IEvLambda(lambda), + ] => + Internal.map3(dist1, dist2, dist3, lambda, env, reducer)->E.R2.errMap(_ => "") + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ), + Function.make( + ~name="mapN", + ~nameSpace, + ~requiresNamespace, + ~examples=[ + `Sampleset.mapN([Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2))], {|x| max(x)`, + ], + ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~definitions=[ + FnDefinition.make( + ~name="mapN", + ~inputs=[FRTypeArray(FRTypeDist), FRTypeLambda], + ~run=(inputs, _, env, reducer) => + switch inputs { + | [IEvArray(dists), IEvLambda(lambda)] => + Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(_ => "") + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ), +] diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 0f3e1e4b..a2e66298 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -109,22 +109,6 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce | Error(r) => Error(REDistributionError(SampleSetError(r))) } - let map1 = (sampleSetDist: t, aLambdaValue) => { - let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)}) - toType(SampleSetDist.samplesMap(~fn, sampleSetDist)) - } - - let map2 = (t1: t, t2: t, aLambdaValue) => { - let fn = (a, b) => doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b)}) - SampleSetDist.map2(~fn, ~t1, ~t2)->toType - } - - let map3 = (t1: t, t2: t, t3: t, aLambdaValue) => { - let fn = (a, b, c) => - doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b), IEvNumber(c)}) - SampleSetDist.map3(~fn, ~t1, ~t2, ~t3)->toType - } - let parseSampleSetArray = (arr: array): option< array, > => { @@ -185,29 +169,6 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce doAddString(aValueString, bValueString) | ("inspect", [value, IEvString(label)]) => inspectLabel(value, label) | ("inspect", [value]) => inspect(value) - | ("mapSamples", [IEvDistribution(SampleSet(dist)), IEvLambda(aLambdaValue)]) => - SampleMap.map1(dist, aLambdaValue) - | ( - "mapSamples2", - [ - IEvDistribution(SampleSet(dist1)), - IEvDistribution(SampleSet(dist2)), - IEvLambda(aLambdaValue), - ], - ) => - SampleMap.map2(dist1, dist2, aLambdaValue) - | ( - "mapSamples3", - [ - IEvDistribution(SampleSet(dist1)), - IEvDistribution(SampleSet(dist2)), - IEvDistribution(SampleSet(dist3)), - IEvLambda(aLambdaValue), - ], - ) => - SampleMap.map3(dist1, dist2, dist3, aLambdaValue) - | ("mapSamplesN", [IEvArray(aValueArray), IEvLambda(aLambdaValue)]) => - SampleMap.mapN(aValueArray, aLambdaValue) | (_, [IEvBool(_)]) | (_, [IEvNumber(_)]) | (_, [IEvString(_)]) From 100ec2c1a8b3c023d4cdbc991d66fb3d41e20b26 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Tue, 19 Jul 2022 16:18:28 -0700 Subject: [PATCH 04/23] Adjusting documentation to reflect new functions --- .../FunctionRegistry/Library/FR_Sampleset.res | 2 +- packages/website/docs/Api/Date.md | 14 +++++----- packages/website/docs/Api/DistGeneric.mdx | 26 +----------------- packages/website/docs/Api/DistPointSet.md | 8 ------ packages/website/docs/Api/Function.md | 27 +++++++++++++++++++ packages/website/docs/Api/List.md | 6 +---- 6 files changed, 36 insertions(+), 47 deletions(-) create mode 100644 packages/website/docs/Api/Function.md diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res index e92551da..b5064352 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res @@ -172,7 +172,7 @@ let library = [ ~nameSpace, ~requiresNamespace, ~examples=[ - `Sampleset.mapN([Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2))], {|x| max(x)`, + `Sampleset.mapN([Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2))], {|x| max(x)})`, ], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ diff --git a/packages/website/docs/Api/Date.md b/packages/website/docs/Api/Date.md index 9f9b9f09..eef71ea0 100644 --- a/packages/website/docs/Api/Date.md +++ b/packages/website/docs/Api/Date.md @@ -5,16 +5,14 @@ title: Date Squiggle date types are a very simple implementation on [Javascript's Date type](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date). It's mainly here for early experimentation. There are more relevant functions for the [Duration](/docs/Api/Duration) type. -### makeFromYear - -(Now `makeDateFromYear`) +### fromYear ``` -Date.makeFromYear: (number) => date +Date.fromYear: (number) => date ``` ```js -makeFromYear(2022.32); +Date.fromYear(2022.32); ``` ### toString @@ -30,7 +28,7 @@ add: (date, duration) => date ``` ```js -makeFromYear(2022.32) + years(5); +Date.fromYear(2022.32) + years(5); ``` ### subtract @@ -41,6 +39,6 @@ subtract: (date, duration) => date ``` ```js -makeFromYear(2040) - makeFromYear(2020); // 20 years -makeFromYear(2040) - years(20); // 2020 +Date.fromYear(2040) - Date.fromYear(2020); // 20 years +Date.fromYear(2040) - years(20); // 2020 ``` diff --git a/packages/website/docs/Api/DistGeneric.mdx b/packages/website/docs/Api/DistGeneric.mdx index 42f464df..a96a6a1e 100644 --- a/packages/website/docs/Api/DistGeneric.mdx +++ b/packages/website/docs/Api/DistGeneric.mdx @@ -653,28 +653,4 @@ scaleLog: (distributionLike, number) => distribution ``` scaleLog10: (distributionLike, number) => distribution -``` - -## Special - -### Declaration (Continuous Functions) - -Adds metadata to a function of the input ranges. Works now for numeric and date inputs. This is useful when making formal predictions. It allows you to limit the domain that your prediction will be used and scored within. - -Declarations are currently experimental and will likely be removed or changed in the future. - -``` -declareFn: (dict<{fn: lambda, inputs: array>}>) => declaration -``` - -**Examples** - -```javascript -declareFn({ - fn: {|a,b| a }, - inputs: [ - {min: 0, max: 100}, - {min: 30, max: 50} - ] -}) -``` +``` \ No newline at end of file diff --git a/packages/website/docs/Api/DistPointSet.md b/packages/website/docs/Api/DistPointSet.md index b4c4ba81..f9117eb9 100644 --- a/packages/website/docs/Api/DistPointSet.md +++ b/packages/website/docs/Api/DistPointSet.md @@ -3,10 +3,6 @@ sidebar_position: 4 title: Point Set Distribution --- -:::danger -These functions aren't yet implemented with these specific names. This should be changed soon -::: - Point set distributions are one of the three distribution formats. They are stored as a list of x-y coordinates representing both discrete and continuous distributions. One complication is that it's possible to represent invalid probability distributions in the point set format. For example, you can represent shapes with negative values, or shapes that are not normalized. @@ -21,8 +17,6 @@ PointSet.make: (distribution) => pointSetDist ### makeContinuous -**TODO: Now called "toContinuousPointSet"** - Converts a set of x-y coordinates directly into a continuous distribution. ``` @@ -40,8 +34,6 @@ PointSet.makeContinuous([ ### makeDiscrete -**TODO: Now called "toDiscretePointSet"** - Converts a set of x-y coordinates directly into a discrete distribution. ``` diff --git a/packages/website/docs/Api/Function.md b/packages/website/docs/Api/Function.md new file mode 100644 index 00000000..b1c53ea3 --- /dev/null +++ b/packages/website/docs/Api/Function.md @@ -0,0 +1,27 @@ +--- +sidebar_position: 6 +title: Function +--- + +## declare (experimental) + +Adds metadata to a function of the input ranges. Works now for numeric and date inputs. This is useful when making formal predictions. It allows you to limit the domain that your prediction will be used and scored within. + +The one function that declarations currently have is that they impact plotting. If you ``declare`` a single-variable function within a specific range, this specific range will be plotted. + +Declarations are currently experimental and will likely be removed or changed in the future. + +``` +Function.declare: (dict<{fn: lambda, inputs: array>}>) => declaration +``` + +**Examples** + +```javascript +Function.declare({ + fn: {|a| a+10 }, + inputs: [ + {min: 30, max: 100} + ] +}) +``` \ No newline at end of file diff --git a/packages/website/docs/Api/List.md b/packages/website/docs/Api/List.md index 47d5f450..1a8ef7a8 100644 --- a/packages/website/docs/Api/List.md +++ b/packages/website/docs/Api/List.md @@ -11,8 +11,6 @@ myList = [3, normal(5, 2), "random"]; ### make -**Note: currently just called `makeList`, without the preix** - ``` List.make: (number, 'a) => list<'a> ``` @@ -37,9 +35,7 @@ toString: (list<'a>) => string length: (list<'a>) => number ``` -### up to - -**Note: currently just called `upTo`, without the preix** +### upTo ``` List.upTo: (low:number, high:number) => list From 35cd9f37d11166fecabfcd4b7200cab7444bf7c9 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Tue, 19 Jul 2022 20:52:08 -0700 Subject: [PATCH 05/23] Basic changes to API --- .../FunctionRegistry/Library/FR_Pointset.res | 8 +-- .../FunctionRegistry/Library/FR_Sampleset.res | 8 +-- packages/website/docs/Api/DistGeneric.mdx | 66 +++++-------------- packages/website/docs/Api/DistPointSet.md | 4 +- packages/website/docs/Api/DistSampleSet.md | 43 +++++++----- packages/website/docs/Api/Number.mdx | 12 ++++ 6 files changed, 65 insertions(+), 76 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res index b90bc96c..8634912f 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res @@ -71,14 +71,14 @@ let library = [ (), ), Function.make( - ~name="maked", + ~name="fromDist", ~nameSpace, - ~requiresNamespace, - ~examples=[`Pointset.maked(normal(5,2))`], + ~requiresNamespace=true, + ~examples=[`PointSet.fromDist(normal(5,2))`], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ FnDefinition.make( - ~name="maked", + ~name="fromDist", ~inputs=[FRTypeDist], ~run=(_, inputs, env, _) => switch inputs { diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res index b5064352..a19f740e 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res @@ -66,14 +66,14 @@ module Internal = { let library = [ Function.make( - ~name="maker", + ~name="fromDist", ~nameSpace, - ~requiresNamespace, - ~examples=[`Sampleset.maker(normal(5,2))`], + ~requiresNamespace=true, + ~examples=[`Sampleset.fromDist(normal(5,2))`], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ FnDefinition.make( - ~name="maker", + ~name="fromDist", ~inputs=[FRTypeDist], ~run=(_, inputs, env, _) => switch inputs { diff --git a/packages/website/docs/Api/DistGeneric.mdx b/packages/website/docs/Api/DistGeneric.mdx index a96a6a1e..e15f3477 100644 --- a/packages/website/docs/Api/DistGeneric.mdx +++ b/packages/website/docs/Api/DistGeneric.mdx @@ -364,6 +364,22 @@ klDivergence: (distribution, distribution) => number klDivergence(normal(5, 2), normal(5, 4)); // returns 0.57 ``` +### logScore + +A log loss score. Often that often acts as a [scoring rule](https://en.wikipedia.org/wiki/Scoring_rule). Useful when evaluating the accuracy of a forecast. + +Note that it is fairly slow. + +``` +logScore: ({estimate: distribution, ?prior: distribution, answer: distribution|number}) => number +``` + +**Examples** + +```javascript +Dist.logScore({estimate: normal(5, 2), answer: normal(4.5, 1.2), prior: normal(6,4)}); // returns -0.597.57 +``` + ## Display ### toString @@ -414,7 +430,7 @@ The only functions that do not return normalized distributions are the pointwise ### normalize -Normalize a distribution. This means scaling it appropriately so that it's cumulative sum is equal to 1. +Normalize a distribution. This means scaling it appropriately so that it's cumulative sum is equal to 1. This only impacts Pointset distributions, because those are the only ones that can be non-normlized. ``` normalize: (distribution) => distribution @@ -605,52 +621,4 @@ dotPow: (distributionLike, distributionLike) => distribution ``` dotExp: (distributionLike, distributionLike) => distribution -``` - -## Scale Arithmetic Operations - - -

- We're planning on removing scale operations in favor of more general - functions soon. -

-
- -Scale operations are similar to pointwise operations, but operate on a constant y-value instead of y-values coming from a distribution. You can think about this as scaling a distribution vertically by a constant. - -The following items would be equivalent. - -```js -scalePow(normal(5,2), 2) -mapY(normal(5,2), {|y| y ^ 2}) // Not yet available -``` - -### scaleMultiply - -``` -scaleMultiply: (distributionLike, number) => distribution -``` - -### scalePow - -``` -scalePow: (distributionLike, number) => distribution -``` - -### scaleExp - -``` -scaleExp: (distributionLike, number) => distribution -``` - -### scaleLog - -``` -scaleLog: (distributionLike, number) => distribution -``` - -### scaleLog10 - -``` -scaleLog10: (distributionLike, number) => distribution ``` \ No newline at end of file diff --git a/packages/website/docs/Api/DistPointSet.md b/packages/website/docs/Api/DistPointSet.md index f9117eb9..f3840055 100644 --- a/packages/website/docs/Api/DistPointSet.md +++ b/packages/website/docs/Api/DistPointSet.md @@ -7,12 +7,12 @@ Point set distributions are one of the three distribution formats. They are stor One complication is that it's possible to represent invalid probability distributions in the point set format. For example, you can represent shapes with negative values, or shapes that are not normalized. -### make +### fromDist Converts the distribution in question into a point set distribution. If the distribution is symbolic, then it does this by taking the quantiles. If the distribution is a sample set, then it uses a version of kernel density estimation to approximate the point set format. One complication of this latter process is that if there is a high proportion of overlapping samples (samples that are exactly the same as each other), it will convert these samples into discrete point masses. Eventually we'd like to add further methods to help adjust this process. ``` -PointSet.make: (distribution) => pointSetDist +PointSet.fromDist: (distribution) => pointSetDist ``` ### makeContinuous diff --git a/packages/website/docs/Api/DistSampleSet.md b/packages/website/docs/Api/DistSampleSet.md index 18005627..2796a778 100644 --- a/packages/website/docs/Api/DistSampleSet.md +++ b/packages/website/docs/Api/DistSampleSet.md @@ -13,36 +13,27 @@ Monte Carlo calculations typically result in sample set distributions. All regular distribution function work on sample set distributions. In addition, there are several functions that only work on sample set distributions. -### make - +### fromDist ``` -SampleSet.make: (distribution) => sampleSet -SampleSet.make: (list) => sampleSet -SampleSet.make: (() => number) => sampleSet // not yet implemented +Sampleset.fromDist: (list) => sampleSet ``` -### map - +### fromList ``` -SampleSet.map: (sampleSet, (number => number)) => sampleSet +Sampleset.fromList: (list) => sampleSet ``` -### map2 +### fromFn +(Not yet implemented) ``` -SampleSet.map2: (sampleSet, sampleSet, ((number, number) => number)) => sampleSet -``` - -### map3 - -``` -SampleSet.map3: (sampleSet, sampleSet, sampleSet, ((number, number, number) => number)) => sampleSet +Sampleset.fromFn: (() => number) => sampleSet ``` ### toList ``` -SampleSet.toList: (sampleSet) => list +Sampleset.toList: (sampleSet) => list ``` Gets the internal samples of a sampleSet distribution. This is separate from the sampleN() function, which would shuffle the samples. toList() maintains order and length. @@ -52,3 +43,21 @@ Gets the internal samples of a sampleSet distribution. This is separate from the ``` toList(toSampleSet(normal(5,2))) ``` + +### map + +``` +Sampleset.map: (sampleSet, (number => number)) => sampleSet +``` + +### map2 + +``` +Sampleset.map2: (sampleSet, sampleSet, ((number, number) => number)) => sampleSet +``` + +### map3 + +``` +Sampleset.map3: (sampleSet, sampleSet, sampleSet, ((number, number, number) => number)) => sampleSet +``` diff --git a/packages/website/docs/Api/Number.mdx b/packages/website/docs/Api/Number.mdx index dda79f64..e77432a0 100644 --- a/packages/website/docs/Api/Number.mdx +++ b/packages/website/docs/Api/Number.mdx @@ -55,6 +55,12 @@ min: (list) => number mean: (list) => number ``` +### geometric mean + +``` +geomean: (list) => number +``` + ### stdev ``` @@ -117,6 +123,12 @@ product: (list) => number cumprod: (list) => list ``` +### diff + +``` +diff: (list) => list +``` + ### subtract ``` From 90d3f89c0ac3ce061b340b5f9e685362924d2218 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Tue, 19 Jul 2022 21:32:11 -0700 Subject: [PATCH 06/23] Trying to fix things, but breaking a lot of tests. --- .../Reducer_Dispatch_BuiltIn_test.res | 2 +- .../ReducerInterface_Distribution_test.res | 6 --- .../FunctionRegistry/Library/FR_Sampleset.res | 54 ++++++++++++++++--- packages/website/docs/Api/DistPointSet.md | 2 - 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res index 65048ebb..a4cc15b3 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res @@ -18,7 +18,7 @@ describe("builtin", () => { testEval("2>1", "Ok(true)") testEval("concat('a','b')", "Ok('ab')") testEval( - "addOne(t)=t+1; toList(mapSamples(fromSamples([1,2,3,4,5,6]), addOne))", + "addOne(t)=t+1; toList(Sampleset.map(fromSamples([1,2,3,4,5,6]), addOne))", "Ok([2,3,4,5,6,7])", ) testEval( diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res index ecc07bfa..3083b71b 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res @@ -41,12 +41,6 @@ describe("eval on distribution functions", () => { describe("normalize", () => { testEval("normalize(normal(5,2))", "Ok(Normal(5,2))") }) - describe("toPointSet", () => { - testEval("toPointSet(normal(5,2))", "Ok(Point Set Distribution)") - }) - describe("toSampleSet", () => { - testEval("toSampleSet(normal(5,2), 100)", "Ok(Sample Set Distribution)") - }) describe("add", () => { testEval("add(normal(5,2), normal(10,2))", "Ok(Normal(15,2.8284271247461903))") testEval("add(normal(5,2), lognormal(10,2))", "Ok(Sample Set Distribution)") diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res index a19f740e..fd27c5f7 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res @@ -90,14 +90,57 @@ let library = [ (), ), Function.make( - ~name="map", + ~name="fromLlist", ~nameSpace, - ~requiresNamespace, - ~examples=[`Sampleset.map(Sampleset.maker(normal(5,2)), {|x| x + 1})`], + ~requiresNamespace=true, + ~examples=[`Sampleset.fromLlist([3,5,2,3,5,2,3,5,2,3,3,5,3,2,3,1,1,3])`], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ FnDefinition.make( - ~name="map", + ~name="fromLlist", + ~inputs=[FRTypeArray(FRTypeNumber)], + ~run=(_, inputs, _, _) => { + let sampleSet = + Prepare.ToTypedArray.numbers(inputs) |> E.R2.bind(r => + SampleSetDist.make(r)->E.R2.errMap(_ => "") + ) + sampleSet->E.R2.fmap(Wrappers.sampleSet)->E.R2.fmap(Wrappers.evDistribution) + }, + (), + ), + ], + (), + ), + Function.make( + ~name="toLlist", + ~nameSpace, + ~requiresNamespace=false, + ~examples=[`Sampleset.toLlist(Sampleset.maker(normal(5,2))`], + ~output=ReducerInterface_InternalExpressionValue.EvtArray, + ~definitions=[ + FnDefinition.make( + ~name="toLlist", + ~inputs=[FRTypeDist], + ~run=(inputs, _, _, _) => + switch inputs { + | [IEvDistribution(SampleSet(dist))] => + dist->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray->Ok + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ), + Function.make( + ~name="mapp", + ~nameSpace, + ~requiresNamespace, + ~examples=[`Sampleset.mapp(Sampleset.maker(normal(5,2)), {|x| x + 1})`], + ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~definitions=[ + FnDefinition.make( + ~name="mapp", ~inputs=[FRTypeDist, FRTypeLambda], ~run=(inputs, _, env, reducer) => switch inputs { @@ -123,7 +166,6 @@ let library = [ ~name="map2", ~inputs=[FRTypeDist, FRTypeDist, FRTypeLambda], ~run=(inputs, _, env, reducer) => { - Js.log2("WHY DIDNT IT MATCH", inputs) switch inputs { | [ IEvDistribution(SampleSet(dist1)), @@ -182,7 +224,7 @@ let library = [ ~run=(inputs, _, env, reducer) => switch inputs { | [IEvArray(dists), IEvLambda(lambda)] => - Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(_ => "") + Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(e => {Js.log2("HI", e); "AHHH doesn't work"}) | _ => Error(impossibleError) }, (), diff --git a/packages/website/docs/Api/DistPointSet.md b/packages/website/docs/Api/DistPointSet.md index f3840055..9c9c3d0d 100644 --- a/packages/website/docs/Api/DistPointSet.md +++ b/packages/website/docs/Api/DistPointSet.md @@ -34,8 +34,6 @@ PointSet.makeContinuous([ ### makeDiscrete -Converts a set of x-y coordinates directly into a discrete distribution. - ``` PointSet.makeDiscrete: (list<{x: number, y: number}>) => pointSetDist ``` From 9173b103f5b94867b0520fe339bde9f423ba7279 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Tue, 19 Jul 2022 23:06:10 -0700 Subject: [PATCH 07/23] Fixed major bug for module functions --- ...leLibrary_FunctionRegistryLibrary_test.res | 1 + packages/squiggle-lang/package.json | 1 + .../FunctionRegistry_Core.res | 103 ++++++++++++------ .../FunctionRegistry_Library.res | 2 +- .../FunctionRegistry/Library/FR_Dict.res | 5 +- .../FunctionRegistry/Library/FR_Pointset.res | 2 +- .../FunctionRegistry/Library/FR_Sampleset.res | 30 ++--- 7 files changed, 94 insertions(+), 50 deletions(-) diff --git a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res index b7c7b8d0..1dcf0471 100644 --- a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res +++ b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res @@ -59,6 +59,7 @@ describe("FunctionRegistry Library", () => { ) testEvalToBe("Dist.logScore({estimate: normal(5,2), answer: 4.5})", "Ok(1.6433360626394853)") testEvalToBe("Dist.klDivergence(normal(5,2), normal(5,1.5))", "Ok(0.06874342818671068)") + testEvalToBe("Sampleset.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)") }) describe("Fn auto-testing", () => { diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 75531a28..6adaa595 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -15,6 +15,7 @@ "start": "rescript build -w -with-deps", "clean": "rescript clean && rm -rf dist", "test:reducer": "jest __tests__/Reducer*/", + "test:current": "jest __tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.bs.js", "benchmark": "ts-node benchmark/conversion_tests.ts", "test": "jest", "test:ts": "jest __tests__/TS/", diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index ea43561e..f1dde98b 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -170,6 +170,7 @@ module FRType = { inputs: array, args: array, ): option> => { + // Js.log3("Matching", inputs, args) let isSameLength = E.A.length(inputs) == E.A.length(args) if !isSameLength { None @@ -240,53 +241,82 @@ module Matcher = { type definitionId = int type match = Match.t, definitionId> - let match = (f: function, fnName: string, args: array): match => { - let matchedDefinition = () => - E.A.getIndexBy(f.definitions, r => - MatchSimple.isFullMatch(FnDefinition.match(r, fnName, args)) - ) |> E.O.fmap(r => Match.FullMatch(r)) - let getMatchedNameOnlyDefinition = () => { - let nameMatchIndexes = - f.definitions - ->E.A2.fmapi((index, r) => - MatchSimple.isNameMatchOnly(FnDefinition.match(r, fnName, args)) ? Some(index) : None + let match = ( + f: function, + namespace: option, + fnName: string, + args: array, + ): match => { + switch namespace { + | Some(ns) if ns !== f.nameSpace => Match.DifferentName + | _ => { + let matchedDefinition = () => + E.A.getIndexBy(f.definitions, r => + MatchSimple.isFullMatch(FnDefinition.match(r, fnName, args)) + ) |> E.O.fmap(r => Match.FullMatch(r)) + let getMatchedNameOnlyDefinition = () => { + let nameMatchIndexes = + f.definitions + ->E.A2.fmapi((index, r) => + MatchSimple.isNameMatchOnly(FnDefinition.match(r, fnName, args)) + ? Some(index) + : None + ) + ->E.A.O.concatSomes + switch nameMatchIndexes { + | [] => None + | elements => Some(Match.SameNameDifferentArguments(elements)) + } + } + + E.A.O.firstSomeFnWithDefault( + [matchedDefinition, getMatchedNameOnlyDefinition], + Match.DifferentName, ) - ->E.A.O.concatSomes - switch nameMatchIndexes { - | [] => None - | elements => Some(Match.SameNameDifferentArguments(elements)) } } - - E.A.O.firstSomeFnWithDefault( - [matchedDefinition, getMatchedNameOnlyDefinition], - Match.DifferentName, - ) } } module RegistryMatch = { type match = { + namespace: option, fnName: string, inputIndex: int, } - let makeMatch = (fnName: string, inputIndex: int) => {fnName: fnName, inputIndex: inputIndex} + let makeMatch = (namespace: option, fnName: string, inputIndex: int) => { + namespace: namespace, + fnName: fnName, + inputIndex: inputIndex, + } } module Registry = { - let _findExactMatches = (r: registry, fnName: string, args: array) => { - let functionMatchPairs = r.functions->E.A2.fmap(l => (l, Function.match(l, fnName, args))) + let _findExactMatches = ( + r: registry, + namespace: option, + fnName: string, + args: array, + ) => { + let functionMatchPairs = + r.functions->E.A2.fmap(l => (l, Function.match(l, namespace, fnName, args))) let fullMatch = functionMatchPairs->E.A.getBy(((_, match)) => Match.isFullMatch(match)) fullMatch->E.O.bind(((fn, match)) => switch match { - | FullMatch(index) => Some(RegistryMatch.makeMatch(fn.name, index)) + | FullMatch(index) => Some(RegistryMatch.makeMatch(namespace, fn.name, index)) | _ => None } ) } - let _findNameMatches = (r: registry, fnName: string, args: array) => { - let functionMatchPairs = r.functions->E.A2.fmap(l => (l, Function.match(l, fnName, args))) + let _findNameMatches = ( + r: registry, + namespace: option, + fnName: string, + args: array, + ) => { + let functionMatchPairs = + r.functions->E.A2.fmap(l => (l, Function.match(l, namespace, fnName, args))) let getNameMatches = functionMatchPairs ->E.A2.fmap(((fn, match)) => Match.isNameMatchOnly(match) ? Some((fn, match)) : None) @@ -296,7 +326,7 @@ module Matcher = { ->E.A2.fmap(((fn, match)) => switch match { | SameNameDifferentArguments(indexes) => - indexes->E.A2.fmap(index => RegistryMatch.makeMatch(fn.name, index)) + indexes->E.A2.fmap(index => RegistryMatch.makeMatch(namespace, fn.name, index)) | _ => [] } ) @@ -307,22 +337,29 @@ module Matcher = { let findMatches = (r: registry, fnName: string, args: array) => { let fnNameInParts = Js.String.split(".", fnName) let fnToSearch = E.A.get(fnNameInParts, 1) |> E.O.default(fnNameInParts[0]) + let nameSpace = E.A.length(fnNameInParts) > 1 ? Some(fnNameInParts[0]) : None - switch _findExactMatches(r, fnToSearch, args) { + switch _findExactMatches(r, nameSpace, fnToSearch, args) { | Some(r) => Match.FullMatch(r) | None => - switch _findNameMatches(r, fnToSearch, args) { + switch _findNameMatches(r, nameSpace, fnToSearch, args) { | Some(r) => Match.SameNameDifferentArguments(r) | None => Match.DifferentName } } } - let matchToDef = (registry: registry, {fnName, inputIndex}: RegistryMatch.match): option< - fnDefinition, - > => + let matchToDef = ( + registry: registry, + {namespace, fnName, inputIndex}: RegistryMatch.match, + ): option => registry.functions - ->E.A.getBy(fn => fn.name === fnName) + ->E.A.getBy(fn => { + switch namespace { + | Some(ns) => ns === fn.nameSpace && fnName === fn.name + | _ => fnName === fn.name + } + }) ->E.O.bind(fn => E.A.get(fn.definitions, inputIndex)) } } @@ -474,6 +511,8 @@ module Registry = { `There are function matches for ${fnName}(), but with different arguments: ${defs}` } + let match = Matcher.Registry.findMatches(modified, fnName, args) + switch Matcher.Registry.findMatches(modified, fnName, args) { | Matcher.Match.FullMatch(match) => match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, env, reducer)) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index 9236ab84..a12c4a36 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -2,10 +2,10 @@ let fnList = Belt.Array.concatMany([ FR_Dict.library, FR_Dist.library, FR_Fn.library, + FR_Sampleset.library, FR_List.library, FR_Number.library, FR_Pointset.library, - FR_Sampleset.library, FR_Scoring.library, ]) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res index 69ceb9c6..10e84f92 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res @@ -156,11 +156,12 @@ let library = [ FnDefinition.make( ~name="fromList", ~inputs=[FRTypeArray(FRTypeArray(FRTypeAny))], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _, _) =>{ switch inputs { | [IEvArray(items)] => Internals.fromList(items) | _ => Error(impossibleError) - }, + } + }, (), ), ], diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res index 8634912f..1a4569f4 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res @@ -74,7 +74,7 @@ let library = [ ~name="fromDist", ~nameSpace, ~requiresNamespace=true, - ~examples=[`PointSet.fromDist(normal(5,2))`], + ~examples=[`Pointset.fromDist(normal(5,2))`], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ FnDefinition.make( diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res index fd27c5f7..85497f8d 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res @@ -90,19 +90,19 @@ let library = [ (), ), Function.make( - ~name="fromLlist", + ~name="fromList", ~nameSpace, ~requiresNamespace=true, - ~examples=[`Sampleset.fromLlist([3,5,2,3,5,2,3,5,2,3,3,5,3,2,3,1,1,3])`], + ~examples=[`Sampleset.fromList([3,5,2,3,5,2,3,5,2,3,3,5,3,2,3,1,1,3])`], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ FnDefinition.make( - ~name="fromLlist", + ~name="fromList", ~inputs=[FRTypeArray(FRTypeNumber)], ~run=(_, inputs, _, _) => { let sampleSet = Prepare.ToTypedArray.numbers(inputs) |> E.R2.bind(r => - SampleSetDist.make(r)->E.R2.errMap(_ => "") + SampleSetDist.make(r)->E.R2.errMap(_ => "AM I HERE? WHYERE AMI??") ) sampleSet->E.R2.fmap(Wrappers.sampleSet)->E.R2.fmap(Wrappers.evDistribution) }, @@ -112,14 +112,14 @@ let library = [ (), ), Function.make( - ~name="toLlist", + ~name="toList", ~nameSpace, ~requiresNamespace=false, - ~examples=[`Sampleset.toLlist(Sampleset.maker(normal(5,2))`], + ~examples=[`Sampleset.toList(Sampleset.fromDist(normal(5,2)))`], ~output=ReducerInterface_InternalExpressionValue.EvtArray, ~definitions=[ FnDefinition.make( - ~name="toLlist", + ~name="toList", ~inputs=[FRTypeDist], ~run=(inputs, _, _, _) => switch inputs { @@ -133,14 +133,14 @@ let library = [ (), ), Function.make( - ~name="mapp", + ~name="map", ~nameSpace, ~requiresNamespace, - ~examples=[`Sampleset.mapp(Sampleset.maker(normal(5,2)), {|x| x + 1})`], + ~examples=[`Sampleset.map(Sampleset.fromDist(normal(5,2)), {|x| x + 1})`], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ FnDefinition.make( - ~name="mapp", + ~name="map", ~inputs=[FRTypeDist, FRTypeLambda], ~run=(inputs, _, env, reducer) => switch inputs { @@ -158,7 +158,7 @@ let library = [ ~nameSpace, ~requiresNamespace, ~examples=[ - `Sampleset.map2(Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2)), {|x, y| x + y})`, + `Sampleset.map2(Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2)), {|x, y| x + y})`, ], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ @@ -186,7 +186,7 @@ let library = [ ~nameSpace, ~requiresNamespace, ~examples=[ - `Sampleset.map3(Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2)), {|x, y, z| max([x,y,z]))`, + `Sampleset.map3(Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2)), {|x, y, z| max([x,y,z])})`, ], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ @@ -214,7 +214,7 @@ let library = [ ~nameSpace, ~requiresNamespace, ~examples=[ - `Sampleset.mapN([Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2))], {|x| max(x)})`, + `Sampleset.mapN([Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2))], {|x| max(x)})`, ], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ @@ -224,7 +224,9 @@ let library = [ ~run=(inputs, _, env, reducer) => switch inputs { | [IEvArray(dists), IEvLambda(lambda)] => - Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(e => {Js.log2("HI", e); "AHHH doesn't work"}) + Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(e => { + "AHHH doesn't work" + }) | _ => Error(impossibleError) }, (), From 1c4557b638d3094db4946427f4e4c3b9a3daf303 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 19 Jul 2022 15:28:06 +0200 Subject: [PATCH 08/23] Introduce void type yarn all:rescript EvVoid parsing void void --- .../Reducer_Peggy_ToExpression_void_test.res | 20 ++++++++ packages/squiggle-lang/package.json | 1 + .../Reducer_Expression_ExpressionBuilder.res | 2 + .../Reducer_Peggy_GeneratedParser.peggy | 51 ++++++++++++------- .../Reducer_Peggy/Reducer_Peggy_Parse.res | 5 ++ .../Reducer_Peggy_ToExpression.res | 1 + .../rescript/Reducer/Reducer_Peggy/helpers.ts | 4 ++ ...ducerInterface_ExternalExpressionValue.res | 2 + ...ducerInterface_InternalExpressionValue.res | 8 +++ 9 files changed, 75 insertions(+), 19 deletions(-) create mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_void_test.res diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_void_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_void_test.res new file mode 100644 index 00000000..a106a188 --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_void_test.res @@ -0,0 +1,20 @@ +open Jest +open Reducer_Peggy_TestHelpers + +describe("Peggy void", () => { + //literal + testToExpression("()", "{()}", ~v="()", ()) + testToExpression( + "fn()=1", + "{(:$_let_$ :fn (:$$_lambda_$$ [_] {1}))}", + ~v="@{fn: lambda(_=>internal code)}", + (), + ) + testToExpression("fn()=1; fn()", "{(:$_let_$ :fn (:$$_lambda_$$ [_] {1})); (:fn ())}", ~v="1", ()) + testToExpression( + "fn(a)=(); call fn(1)", + "{(:$_let_$ :fn (:$$_lambda_$$ [a] {()})); (:$_let_$ :_ {(:fn 1)})}", + ~v="@{_: (),fn: lambda(a=>internal code)}", + (), + ) +}) diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 75531a28..1c4ba3ac 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -31,6 +31,7 @@ "format:prettier": "prettier --write .", "format": "yarn format:rescript && yarn format:prettier", "prepack": "yarn build && yarn test && yarn bundle", + "all:rescript": "yarn build:rescript && yarn test:rescript && yarn format:rescript", "all": "yarn build && yarn bundle && yarn test" }, "keywords": [ diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res index 14ffe685..9cc25725 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res @@ -82,3 +82,5 @@ let eIdentifier = (name: string): expression => let eTypeIdentifier = (name: string): expression => name->BInternalExpressionValue.IEvTypeIdentifier->BExpressionT.EValue + +let eVoid: expression = BInternalExpressionValue.IEvVoid->BExpressionT.EValue diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy index f4acd4a3..befda109 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy @@ -5,13 +5,12 @@ }} start - // = _nl start:typeExpression _nl finalComment? {return start} = _nl start:outerBlock _nl finalComment? {return start} zeroOMoreArgumentsBlockOrExpression = innerBlockOrExpression / lambda outerBlock - = statements:array_statements finalExpression: (statementSeparator @expression)? + = statements:array_statements finalExpression: (statementSeparator @expression)? { if (finalExpression != null) { statements.push(finalExpression) } return h.nodeBlock(statements) } / finalExpression: expression @@ -24,25 +23,31 @@ innerBlockOrExpression quotedInnerBlock = '{' _nl statements:array_statements finalExpression: (statementSeparator @expression) _nl '}' - { statements.push(finalExpression) - return h.nodeBlock(statements) } + { statements.push(finalExpression) + return h.nodeBlock(statements) } / '{' _nl finalExpression: expression _nl '}' - { return h.nodeBlock([finalExpression]) } + { return h.nodeBlock([finalExpression]) } array_statements = head:statement tail:(statementSeparator @array_statements ) { return [head, ...tail] } / head:statement - { return [head] } + { return [head] } statement = letStatement / defunStatement / typeStatement + / voidStatement + +voidStatement + = "call" _nl value:zeroOMoreArgumentsBlockOrExpression + { var variable = h.nodeIdentifier("_", location()); + return h.nodeLetStatement(variable, value); } letStatement = variable:identifier _ assignmentOp _nl value:zeroOMoreArgumentsBlockOrExpression - { return h.nodeLetStatement(variable, value) } + { return h.nodeLetStatement(variable, value) } defunStatement = variable:identifier '(' _nl args:array_parameters _nl ')' _ assignmentOp _nl body:innerBlockOrExpression @@ -53,13 +58,15 @@ defunStatement array_parameters = head:dollarIdentifier tail:(_ ',' _nl @dollarIdentifier)* - { return [head, ...tail]; } + { return [head, ...tail]; } + / "" + { return [h.nodeIdentifier("_", location())]; } expression = ifthenelse / ternary / logicalAdditive ifthenelse = 'if' __nl condition:logicalAdditive - __nl 'then' __nl trueExpression:innerBlockOrExpression + __nl 'then' __nl trueExpression:innerBlockOrExpression __nl 'else' __nl falseExpression:(ifthenelse/innerBlockOrExpression) { return h.nodeTernary(condition, trueExpression, falseExpression) } @@ -88,8 +95,8 @@ equality = left:relational _ operator:equalityOp _nl right:relational { return h.makeFunctionCall(h.toFunction[operator], [left, right])} / relational - - equalityOp "operator" = '=='/'!=' + + equalityOp "operator" = '=='/'!=' relational = left:additive _ operator:relationalOp _nl right:additive @@ -172,19 +179,25 @@ collectionElement array_functionArguments = head:expression tail:(_ ',' _nl @expression)* { return [head, ...tail]; } + / "" + {return [h.nodeVoid()];} atom = '(' _nl expression:expression _nl ')' {return expression} / basicValue basicValue = valueConstructor / basicLiteral - + basicLiteral = string / number / boolean / dollarIdentifierWithModule / dollarIdentifier + / voidLiteral + +voidLiteral 'void' + = "()" {return h.nodeVoid();} dollarIdentifierWithModule 'identifier' = head:$moduleIdentifier @@ -195,7 +208,7 @@ dollarIdentifierWithModule 'identifier' modifiers.unshift(head) modifiers.push(final) let modifiedIdentifier = modifiers.join('.') - return h.nodeIdentifier(modifiedIdentifier) + return h.nodeIdentifier(modifiedIdentifier, location()) } identifier 'identifier' @@ -232,8 +245,8 @@ float 'float' = $(((d+ "\." d*) / ("\." d+)) floatExponent? / d+ floatExponent) { return h.nodeFloat(parseFloat(text()))} - floatExponent = [e]i '-'? d+ - d = [0-9] + floatExponent = [e]i '-'? d+ + d = [0-9] boolean 'boolean' = ('true'/'false') @@ -247,10 +260,10 @@ valueConstructor lambda = '{' _nl '|' _nl args:array_parameters _nl '|' _nl statements:array_statements finalExpression: (statementSeparator @expression) _nl '}' - { statements.push(finalExpression) - return h.nodeLambda(args, h.nodeBlock(statements)) } + { statements.push(finalExpression) + return h.nodeLambda(args, h.nodeBlock(statements)) } / '{' _nl '|' _nl args:array_parameters _nl '|' _nl finalExpression: expression _nl '}' - { return h.nodeLambda(args, h.nodeBlock([finalExpression])) } + { return h.nodeLambda(args, h.nodeBlock([finalExpression])) } arrayConstructor 'array' = '[' _nl ']' @@ -289,7 +302,7 @@ __nl 'whitespace or newline' = (whiteSpaceCharactersOrComment / commentOrNewLine )+ statementSeparator 'statement separator' - = _ (';'/ commentOrNewLine)+ _nl + = _ (';'/ commentOrNewLine)+ _nl commentOrNewLine = finalComment? newLine diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_Parse.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_Parse.res index a38c66e9..193cb893 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_Parse.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_Parse.res @@ -34,6 +34,7 @@ type nodeModuleIdentifier = {...node, "value": string} type nodeString = {...node, "value": string} type nodeTernary = {...node, "condition": node, "trueExpression": node, "falseExpression": node} type nodeTypeIdentifier = {...node, "value": string} +type nodeVoid = node type peggyNode = | PgNodeBlock(nodeBlock) @@ -50,6 +51,7 @@ type peggyNode = | PgNodeString(nodeString) | PgNodeTernary(nodeTernary) | PgNodeTypeIdentifier(nodeTypeIdentifier) + | PgNodeVoid(nodeVoid) external castNodeBlock: node => nodeBlock = "%identity" external castNodeBoolean: node => nodeBoolean = "%identity" @@ -65,6 +67,7 @@ external castNodeModuleIdentifier: node => nodeModuleIdentifier = "%identity" external castNodeString: node => nodeString = "%identity" external castNodeTernary: node => nodeTernary = "%identity" external castNodeTypeIdentifier: node => nodeTypeIdentifier = "%identity" +external castNodeVoid: node => nodeVoid = "%identity" exception UnsupportedPeggyNodeType(string) // This should never happen; programming error let castNodeType = (node: node) => @@ -83,6 +86,7 @@ let castNodeType = (node: node) => | "String" => node->castNodeString->PgNodeString | "Ternary" => node->castNodeTernary->PgNodeTernary | "TypeIdentifier" => node->castNodeTypeIdentifier->PgNodeTypeIdentifier + | "Void" => node->castNodeVoid->PgNodeVoid | _ => raise(UnsupportedPeggyNodeType(node["type"])) } @@ -116,6 +120,7 @@ let rec pgToString = (peggyNode: peggyNode): string => { " " ++ toString(node["falseExpression"]) ++ ")" | PgNodeTypeIdentifier(node) => `#${node["value"]}` + | PgNodeVoid(_node) => "()" } } and toString = (node: node): string => node->castNodeType->pgToString diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression.res index 6e04a55d..73247a8e 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression.res @@ -48,5 +48,6 @@ let rec fromNode = (node: Parse.node): expression => { ) | PgNodeTypeIdentifier(nodeTypeIdentifier) => ExpressionBuilder.eTypeIdentifier(nodeTypeIdentifier["value"]) + | PgNodeVoid(_) => ExpressionBuilder.eVoid } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts index 57b85f9e..94975233 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts @@ -213,3 +213,7 @@ export function nodeTernary( export function nodeTypeIdentifier(typeValue: string) { return { type: "TypeIdentifier", value: typeValue }; } + +export function nodeVoid() { + return { type: "Void" }; +} diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res index b21ba3c6..a4d6e713 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res @@ -25,6 +25,7 @@ type rec externalExpressionValue = | EvTypeIdentifier(string) | EvModule(record) | EvType(record) + | EvVoid and record = Js.Dict.t and externalBindings = record and lambdaValue = { @@ -63,6 +64,7 @@ let rec toString = aValue => | EvTimeDuration(t) => DateTime.Duration.toString(t) | EvType(t) => `type${t->toStringRecord}` | EvTypeIdentifier(id) => `#${id}` + | EvVoid => `()` } and toStringRecord = aRecord => { let pairs = diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index 4523b02a..39019fba 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -23,6 +23,7 @@ type rec t = | IEvTimeDuration(float) | IEvType(map) | IEvTypeIdentifier(string) + | IEvVoid and map = Belt.Map.String.t and nameSpace = NameSpace(Belt.Map.String.t) and lambdaValue = { @@ -60,6 +61,7 @@ let rec toString = aValue => | IEvType(aMap) => aMap->toStringMap | IEvTimeDuration(t) => DateTime.Duration.toString(t) | IEvTypeIdentifier(id) => `#${id}` + | IEvVoid => `()` } and toStringMap = aMap => { let pairs = @@ -92,6 +94,7 @@ let toStringWithType = aValue => | IEvTimeDuration(_) => `Date::${toString(aValue)}` | IEvType(_) => `Type::${toString(aValue)}` | IEvTypeIdentifier(_) => `TypeIdentifier::${toString(aValue)}` + | IEvVoid => `Void` } let argsToString = (args: array): string => { @@ -135,6 +138,7 @@ type internalExpressionValueType = | EvtTimeDuration | EvtType | EvtTypeIdentifier + | EvtVoid type functionCallSignature = CallSignature(string, array) type functionDefinitionSignature = @@ -158,6 +162,7 @@ let valueToValueType = value => | IEvTimeDuration(_) => EvtTimeDuration | IEvType(_) => EvtType | IEvTypeIdentifier(_) => EvtTypeIdentifier + | IEvVoid => EvtVoid } let functionCallToCallSignature = (functionCall: functionCall): functionCallSignature => { @@ -183,6 +188,7 @@ let valueTypeToString = (valueType: internalExpressionValueType): string => | EvtTimeDuration => `Duration` | EvtType => `Type` | EvtTypeIdentifier => `TypeIdentifier` + | EvtVoid => `Void` } let functionCallSignatureToString = (functionCallSignature: functionCallSignature): string => { @@ -212,6 +218,7 @@ let rec toExternal = (iev: t): ExternalExpressionValue.t => { | IEvType(v) => v->mapToExternal->EvType | IEvTypeIdentifier(v) => EvTypeIdentifier(v) | IEvBindings(v) => v->nameSpaceToTypeScriptBindings->EvModule + | IEvVoid => EvVoid } } and mapToExternal = v => @@ -251,6 +258,7 @@ let rec toInternal = (ev: ExternalExpressionValue.t): t => { | EvTimeDuration(v) => IEvTimeDuration(v) | EvType(v) => v->recordToInternal->IEvType | EvTypeIdentifier(v) => IEvTypeIdentifier(v) + | EvVoid => IEvVoid } } and recordToInternal = v => From 078534f7c849b6bbf002a41b1648c1b2b6429cf1 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Wed, 20 Jul 2022 08:27:57 -0700 Subject: [PATCH 09/23] Fixed typescript build --- packages/squiggle-lang/src/js/index.ts | 151 ++++++++++-------- .../squiggle-lang/src/js/rescript_interop.ts | 3 +- 2 files changed, 82 insertions(+), 72 deletions(-) diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 5e4cf2c1..acee005c 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -120,77 +120,86 @@ function createTsExport( x: expressionValue, environment: environment ): squiggleExpression { - switch (x.tag) { - case "EvArray": - // genType doesn't convert anything more than 2 layers down into {tag: x, value: x} - // format, leaving it as the raw values. This converts the raw values - // directly into typescript values. - // - // The casting here is because genType is about the types of the returned - // values, claiming they are fully recursive when that's not actually the - // case - return tag( - "array", - x.value.map( - (arrayItem): squiggleExpression => - convertRawToTypescript( - arrayItem as unknown as rescriptExport, - environment + switch (x) { + case "EvVoid": + return tag("void", ""); + default: { + switch (x.tag) { + case "EvArray": + // genType doesn't convert anything more than 2 layers down into {tag: x, value: x} + // format, leaving it as the raw values. This converts the raw values + // directly into typescript values. + // + // The casting here is because genType is about the types of the returned + // values, claiming they are fully recursive when that's not actually the + // case + return tag( + "array", + x.value.map( + (arrayItem): squiggleExpression => + convertRawToTypescript( + arrayItem as unknown as rescriptExport, + environment + ) ) - ) - ); - case "EvArrayString": - return tag("arraystring", x.value); - case "EvBool": - return tag("boolean", x.value); - case "EvCall": - return tag("call", x.value); - case "EvLambda": - return tag("lambda", x.value); - case "EvDistribution": - return tag("distribution", new Distribution(x.value, environment)); - case "EvNumber": - return tag("number", x.value); - case "EvRecord": - // genType doesn't support records, so we have to do the raw conversion ourself - let result: tagged<"record", { [key: string]: squiggleExpression }> = tag( - "record", - _.mapValues(x.value, (x: unknown) => - convertRawToTypescript(x as rescriptExport, environment) - ) - ); - return result; - case "EvString": - return tag("string", x.value); - case "EvSymbol": - return tag("symbol", x.value); - case "EvDate": - return tag("date", x.value); - case "EvTimeDuration": - return tag("timeDuration", x.value); - case "EvDeclaration": - return tag("lambdaDeclaration", x.value); - case "EvTypeIdentifier": - return tag("typeIdentifier", x.value); - case "EvType": - let typeResult: tagged<"type", { [key: string]: squiggleExpression }> = - tag( - "type", - _.mapValues(x.value, (x: unknown) => - convertRawToTypescript(x as rescriptExport, environment) - ) - ); - return typeResult; - case "EvModule": - let moduleResult: tagged< - "module", - { [key: string]: squiggleExpression } - > = tag( - "module", - _.mapValues(x.value, (x: unknown) => - convertRawToTypescript(x as rescriptExport, environment) - ) - ); - return moduleResult; + ); + case "EvArrayString": + return tag("arraystring", x.value); + case "EvBool": + return tag("boolean", x.value); + case "EvCall": + return tag("call", x.value); + case "EvLambda": + return tag("lambda", x.value); + case "EvDistribution": + return tag("distribution", new Distribution(x.value, environment)); + case "EvNumber": + return tag("number", x.value); + case "EvRecord": + // genType doesn't support records, so we have to do the raw conversion ourself + let result: tagged<"record", { [key: string]: squiggleExpression }> = + tag( + "record", + _.mapValues(x.value, (x: unknown) => + convertRawToTypescript(x as rescriptExport, environment) + ) + ); + return result; + case "EvString": + return tag("string", x.value); + case "EvSymbol": + return tag("symbol", x.value); + case "EvDate": + return tag("date", x.value); + case "EvTimeDuration": + return tag("timeDuration", x.value); + case "EvDeclaration": + return tag("lambdaDeclaration", x.value); + case "EvTypeIdentifier": + return tag("typeIdentifier", x.value); + case "EvType": + let typeResult: tagged< + "type", + { [key: string]: squiggleExpression } + > = tag( + "type", + _.mapValues(x.value, (x: unknown) => + convertRawToTypescript(x as rescriptExport, environment) + ) + ); + return typeResult; + case "EvModule": + let moduleResult: tagged< + "module", + { [key: string]: squiggleExpression } + > = tag( + "module", + _.mapValues(x.value, (x: unknown) => + convertRawToTypescript(x as rescriptExport, environment) + ) + ); + return moduleResult; + } + } } } diff --git a/packages/squiggle-lang/src/js/rescript_interop.ts b/packages/squiggle-lang/src/js/rescript_interop.ts index dcba24e6..80548a7f 100644 --- a/packages/squiggle-lang/src/js/rescript_interop.ts +++ b/packages/squiggle-lang/src/js/rescript_interop.ts @@ -131,7 +131,8 @@ export type squiggleExpression = | tagged<"record", { [key: string]: squiggleExpression }> | tagged<"type", { [key: string]: squiggleExpression }> | tagged<"typeIdentifier", string> - | tagged<"module", { [key: string]: squiggleExpression }>; + | tagged<"module", { [key: string]: squiggleExpression }> + | tagged<"void", string>; export { lambdaValue }; From 590ffac5528ae00dba2dc6592350f9459a4bb72f Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Wed, 20 Jul 2022 09:28:32 -0700 Subject: [PATCH 10/23] Minor component fix to show Void statements --- packages/components/src/components/SquiggleItem.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/components/src/components/SquiggleItem.tsx b/packages/components/src/components/SquiggleItem.tsx index 48a8a0fb..52330e8b 100644 --- a/packages/components/src/components/SquiggleItem.tsx +++ b/packages/components/src/components/SquiggleItem.tsx @@ -200,6 +200,12 @@ export const SquiggleItem: React.FC = ({ {expression.value.toDateString()} ); + case "void": + return ( + + {"Void"} + + ); case "timeDuration": { return ( From fe552eb6efc524afaad88fdbf350f9d816ce0d24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Jul 2022 23:47:59 +0000 Subject: [PATCH 11/23] :arrow_up: Bump terser from 4.8.0 to 4.8.1 Bumps [terser](https://github.com/terser/terser) from 4.8.0 to 4.8.1. - [Release notes](https://github.com/terser/terser/releases) - [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md) - [Commits](https://github.com/terser/terser/commits) --- updated-dependencies: - dependency-name: terser dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index fd243efb..a61e16f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17115,9 +17115,9 @@ terser-webpack-plugin@^5.0.3, terser-webpack-plugin@^5.1.3, terser-webpack-plugi terser "^5.7.2" terser@^4.1.2, terser@^4.6.3: - version "4.8.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" - integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== + version "4.8.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.1.tgz#a00e5634562de2239fd404c649051bf6fc21144f" + integrity sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw== dependencies: commander "^2.20.0" source-map "~0.6.1" From d3a12eb4e996f745f42fe6efe948bc6b9fddaafc Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 21 Jul 2022 08:31:46 -0700 Subject: [PATCH 12/23] Fixed bug with namespaces --- .../Reducer_Dispatch_BuiltIn_test.res | 8 -------- ...uiggleLibrary_FunctionRegistryLibrary_test.res | 10 ++++++++++ packages/squiggle-lang/package.json | 2 +- .../FunctionRegistry/FunctionRegistry_Core.res | 15 ++++++--------- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res index a4cc15b3..f3c92f78 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res @@ -17,14 +17,6 @@ describe("builtin", () => { testEval("1-1", "Ok(0)") testEval("2>1", "Ok(true)") testEval("concat('a','b')", "Ok('ab')") - testEval( - "addOne(t)=t+1; toList(Sampleset.map(fromSamples([1,2,3,4,5,6]), addOne))", - "Ok([2,3,4,5,6,7])", - ) - testEval( - "toList(mapSamplesN([fromSamples([1,2,3,4,5,6]), fromSamples([6, 5, 4, 3, 2, 1])], {|x| x[0] > x[1] ? x[0] : x[1]}))", - "Ok([6,5,4,4,5,6])", - ) }) describe("builtin exception", () => { diff --git a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res index 1dcf0471..7a1564f7 100644 --- a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res +++ b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res @@ -17,6 +17,7 @@ describe("FunctionRegistry Library", () => { testEvalToBe("List.last([3,5,8])", "Ok(8)") testEvalToBe("List.reverse([3,5,8])", "Ok([8,5,3])") testEvalToBe("double(x)=2*x; arr=[1,2,3]; List.map(arr, double)", "Ok([2,4,6])") + testEvalToBe("double(x)=2*x; arr=[1,2,3]; map(arr, double)", "Ok([2,4,6])") testEvalToBe("myadd(acc,x)=acc+x; arr=[1,2,3]; List.reduce(arr, 0, myadd)", "Ok(6)") testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; List.reduce(arr, 0, change)", "Ok(15)") testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; List.reduceReverse(arr, 0, change)", "Ok(9)") @@ -60,6 +61,15 @@ describe("FunctionRegistry Library", () => { testEvalToBe("Dist.logScore({estimate: normal(5,2), answer: 4.5})", "Ok(1.6433360626394853)") testEvalToBe("Dist.klDivergence(normal(5,2), normal(5,1.5))", "Ok(0.06874342818671068)") testEvalToBe("Sampleset.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)") + testEvalToBe("Sampleset.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)") + testEvalToBe( + "addOne(t)=t+1; Sampleset.toList(Sampleset.map(Sampleset.fromList([1,2,3,4,5,6]), addOne))", + "Ok([2,3,4,5,6,7])", + ) + testEvalToBe( + "toList(Sampleset.mapN([Sampleset.fromList([1,2,3,4,5,6]), Sampleset.fromList([6, 5, 4, 3, 2, 1])], {|x| x[0] > x[1] ? x[0] : x[1]}))", + "Ok([6,5,4,4,5,6])", + ) }) describe("Fn auto-testing", () => { diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 3dd90839..52c9f07c 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -15,9 +15,9 @@ "start": "rescript build -w -with-deps", "clean": "rescript clean && rm -rf dist", "test:reducer": "jest __tests__/Reducer*/", - "test:current": "jest __tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.bs.js", "benchmark": "ts-node benchmark/conversion_tests.ts", "test": "jest", + "test:lib": "jest __tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.bs.js", "test:ts": "jest __tests__/TS/", "test:rescript": "jest --modulePathIgnorePatterns=__tests__/TS/*", "test:watch": "jest --watchAll", diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index f1dde98b..f4864531 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -280,11 +280,11 @@ module Matcher = { module RegistryMatch = { type match = { - namespace: option, + namespace: string, fnName: string, inputIndex: int, } - let makeMatch = (namespace: option, fnName: string, inputIndex: int) => { + let makeMatch = (namespace: string, fnName: string, inputIndex: int) => { namespace: namespace, fnName: fnName, inputIndex: inputIndex, @@ -303,7 +303,7 @@ module Matcher = { let fullMatch = functionMatchPairs->E.A.getBy(((_, match)) => Match.isFullMatch(match)) fullMatch->E.O.bind(((fn, match)) => switch match { - | FullMatch(index) => Some(RegistryMatch.makeMatch(namespace, fn.name, index)) + | FullMatch(index) => Some(RegistryMatch.makeMatch(fn.nameSpace, fn.name, index)) | _ => None } ) @@ -326,7 +326,7 @@ module Matcher = { ->E.A2.fmap(((fn, match)) => switch match { | SameNameDifferentArguments(indexes) => - indexes->E.A2.fmap(index => RegistryMatch.makeMatch(namespace, fn.name, index)) + indexes->E.A2.fmap(index => RegistryMatch.makeMatch(fn.nameSpace, fn.name, index)) | _ => [] } ) @@ -355,10 +355,7 @@ module Matcher = { ): option => registry.functions ->E.A.getBy(fn => { - switch namespace { - | Some(ns) => ns === fn.nameSpace && fnName === fn.name - | _ => fnName === fn.name - } + namespace === fn.nameSpace && fnName === fn.name }) ->E.O.bind(fn => E.A.get(fn.definitions, inputIndex)) } @@ -511,7 +508,7 @@ module Registry = { `There are function matches for ${fnName}(), but with different arguments: ${defs}` } - let match = Matcher.Registry.findMatches(modified, fnName, args) + // let match = Matcher.Registry.findMatches(modified, fnName, args); Js.log2("Match", match) switch Matcher.Registry.findMatches(modified, fnName, args) { | Matcher.Match.FullMatch(match) => From 223ddf6a3e7f9518a9b9102ef7808eb6823507f8 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 21 Jul 2022 08:54:41 -0700 Subject: [PATCH 13/23] Fixed bug with namespaces --- ...leLibrary_FunctionRegistryLibrary_test.res | 8 +- .../FunctionRegistry/Library/FR_Pointset.res | 96 +++++++++---------- .../FunctionRegistry/Library/FR_Sampleset.res | 16 ++-- 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res index 7a1564f7..da357653 100644 --- a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res +++ b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res @@ -60,14 +60,14 @@ describe("FunctionRegistry Library", () => { ) testEvalToBe("Dist.logScore({estimate: normal(5,2), answer: 4.5})", "Ok(1.6433360626394853)") testEvalToBe("Dist.klDivergence(normal(5,2), normal(5,1.5))", "Ok(0.06874342818671068)") - testEvalToBe("Sampleset.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)") - testEvalToBe("Sampleset.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)") + testEvalToBe("SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)") + testEvalToBe("SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)") testEvalToBe( - "addOne(t)=t+1; Sampleset.toList(Sampleset.map(Sampleset.fromList([1,2,3,4,5,6]), addOne))", + "addOne(t)=t+1; SampleSet.toList(SampleSet.map(SampleSet.fromList([1,2,3,4,5,6]), addOne))", "Ok([2,3,4,5,6,7])", ) testEvalToBe( - "toList(Sampleset.mapN([Sampleset.fromList([1,2,3,4,5,6]), Sampleset.fromList([6, 5, 4, 3, 2, 1])], {|x| x[0] > x[1] ? x[0] : x[1]}))", + "toList(SampleSet.mapN([SampleSet.fromList([1,2,3,4,5,6]), SampleSet.fromList([6, 5, 4, 3, 2, 1])], {|x| x[0] > x[1] ? x[0] : x[1]}))", "Ok([6,5,4,4,5,6])", ) }) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res index 1a4569f4..4f4e1731 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res @@ -1,7 +1,7 @@ open FunctionRegistry_Core open FunctionRegistry_Helpers -let nameSpace = "Pointset" +let nameSpace = "PointSet" let requiresNamespace = true let inputsTodist = (inputs: array, makeDist) => { @@ -24,57 +24,11 @@ let inputsTodist = (inputs: array, makeDist) => { } let library = [ - Function.make( - ~name="makeContinuous", - ~nameSpace, - ~requiresNamespace, - ~examples=[ - `Pointset.makeContinuous([ - {x: 0, y: 0.2}, - {x: 1, y: 0.7}, - {x: 2, y: 0.8}, - {x: 3, y: 0.2} - ])`, - ], - ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, - ~definitions=[ - FnDefinition.make( - ~name="makeContinuous", - ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], - ~run=(_, inputs, _, _) => inputsTodist(inputs, r => Continuous(Continuous.make(r))), - (), - ), - ], - (), - ), - Function.make( - ~name="makeDiscrete", - ~nameSpace, - ~requiresNamespace, - ~examples=[ - `Pointset.makeDiscrete([ - {x: 0, y: 0.2}, - {x: 1, y: 0.7}, - {x: 2, y: 0.8}, - {x: 3, y: 0.2} - ])`, - ], - ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, - ~definitions=[ - FnDefinition.make( - ~name="makeDiscrete", - ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], - ~run=(_, inputs, _, _) => inputsTodist(inputs, r => Discrete(Discrete.make(r))), - (), - ), - ], - (), - ), Function.make( ~name="fromDist", ~nameSpace, ~requiresNamespace=true, - ~examples=[`Pointset.fromDist(normal(5,2))`], + ~examples=[`PointSet.fromDist(normal(5,2))`], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ FnDefinition.make( @@ -99,4 +53,50 @@ let library = [ ], (), ), + Function.make( + ~name="makeContinuous", + ~nameSpace, + ~requiresNamespace, + ~examples=[ + `PointSet.makeContinuous([ + {x: 0, y: 0.2}, + {x: 1, y: 0.7}, + {x: 2, y: 0.8}, + {x: 3, y: 0.2} + ])`, + ], + ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~definitions=[ + FnDefinition.make( + ~name="makeContinuous", + ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], + ~run=(_, inputs, _, _) => inputsTodist(inputs, r => Continuous(Continuous.make(r))), + (), + ), + ], + (), + ), + Function.make( + ~name="makeDiscrete", + ~nameSpace, + ~requiresNamespace, + ~examples=[ + `PointSet.makeDiscrete([ + {x: 0, y: 0.2}, + {x: 1, y: 0.7}, + {x: 2, y: 0.8}, + {x: 3, y: 0.2} + ])`, + ], + ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~definitions=[ + FnDefinition.make( + ~name="makeDiscrete", + ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], + ~run=(_, inputs, _, _) => inputsTodist(inputs, r => Discrete(Discrete.make(r))), + (), + ), + ], + (), + ), ] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res index 85497f8d..a13ff46c 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res @@ -1,7 +1,7 @@ open FunctionRegistry_Core open FunctionRegistry_Helpers -let nameSpace = "Sampleset" +let nameSpace = "SampleSet" let requiresNamespace = true module Internal = { @@ -69,7 +69,7 @@ let library = [ ~name="fromDist", ~nameSpace, ~requiresNamespace=true, - ~examples=[`Sampleset.fromDist(normal(5,2))`], + ~examples=[`SampleSet.fromDist(normal(5,2))`], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ FnDefinition.make( @@ -93,7 +93,7 @@ let library = [ ~name="fromList", ~nameSpace, ~requiresNamespace=true, - ~examples=[`Sampleset.fromList([3,5,2,3,5,2,3,5,2,3,3,5,3,2,3,1,1,3])`], + ~examples=[`SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5,3,2,3,1,1,3])`], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ FnDefinition.make( @@ -115,7 +115,7 @@ let library = [ ~name="toList", ~nameSpace, ~requiresNamespace=false, - ~examples=[`Sampleset.toList(Sampleset.fromDist(normal(5,2)))`], + ~examples=[`SampleSet.toList(SampleSet.fromDist(normal(5,2)))`], ~output=ReducerInterface_InternalExpressionValue.EvtArray, ~definitions=[ FnDefinition.make( @@ -136,7 +136,7 @@ let library = [ ~name="map", ~nameSpace, ~requiresNamespace, - ~examples=[`Sampleset.map(Sampleset.fromDist(normal(5,2)), {|x| x + 1})`], + ~examples=[`SampleSet.map(SampleSet.fromDist(normal(5,2)), {|x| x + 1})`], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ FnDefinition.make( @@ -158,7 +158,7 @@ let library = [ ~nameSpace, ~requiresNamespace, ~examples=[ - `Sampleset.map2(Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2)), {|x, y| x + y})`, + `SampleSet.map2(SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), {|x, y| x + y})`, ], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ @@ -186,7 +186,7 @@ let library = [ ~nameSpace, ~requiresNamespace, ~examples=[ - `Sampleset.map3(Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2)), {|x, y, z| max([x,y,z])})`, + `SampleSet.map3(SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), {|x, y, z| max([x,y,z])})`, ], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ @@ -214,7 +214,7 @@ let library = [ ~nameSpace, ~requiresNamespace, ~examples=[ - `Sampleset.mapN([Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2))], {|x| max(x)})`, + `SampleSet.mapN([SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2))], {|x| max(x)})`, ], ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ From acebaa517b5aed232040b092ef37708b3563199d Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 21 Jul 2022 10:31:53 -0700 Subject: [PATCH 14/23] Simple SampleSet.fromDist function --- ...leLibrary_FunctionRegistryLibrary_test.res | 1 + .../FunctionRegistry/Library/FR_Sampleset.res | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res index da357653..a7e98163 100644 --- a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res +++ b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res @@ -62,6 +62,7 @@ describe("FunctionRegistry Library", () => { testEvalToBe("Dist.klDivergence(normal(5,2), normal(5,1.5))", "Ok(0.06874342818671068)") testEvalToBe("SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)") testEvalToBe("SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)") + testEvalToBe("SampleSet.fromFn({|| sample(normal(5,2))})", "Ok(Sample Set Distribution)") testEvalToBe( "addOne(t)=t+1; SampleSet.toList(SampleSet.map(SampleSet.fromList([1,2,3,4,5,6]), addOne))", "Ok([2,3,4,5,6,7])", diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res index a13ff46c..b2927b82 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res @@ -21,6 +21,17 @@ module Internal = { | Error(r) => Error(REDistributionError(SampleSetError(r))) } + //TODO: I don't know why this seems to need at least one input + let fromFn = ( + aLambdaValue, + env: ReducerInterface_InternalExpressionValue.environment, + reducer, + ) => { + let sampleCount = env.sampleCount + let fn = (r) => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, env, reducer) + Belt_Array.makeBy(sampleCount, (r) => fn(r->Js.Int.toFloat))->E.A.R.firstErrorOrOpen + } + let map1 = (sampleSetDist: t, aLambdaValue, env, reducer) => { let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, env, reducer) SampleSetDist.samplesMap(~fn, sampleSetDist)->toType @@ -132,6 +143,30 @@ let library = [ ], (), ), + Function.make( + ~name="fromFn", + ~nameSpace, + ~requiresNamespace=false, + ~examples=[`SampleSet.fromFn(sample(normal(5,2)))`], + ~output=ReducerInterface_InternalExpressionValue.EvtArray, + ~definitions=[ + FnDefinition.make( + ~name="fromFn", + ~inputs=[FRTypeLambda], + ~run=(inputs, _, env, reducer) => + switch inputs { + | [IEvLambda(lambda)] => + switch Internal.fromFn(lambda, env, reducer) { + | Ok(r) => Ok(r->Wrappers.sampleSet->Wrappers.evDistribution) + | Error(_) => Error("issue") + } + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ), Function.make( ~name="map", ~nameSpace, From 47f1be07020312b6e0db28e002feec7e31df38b9 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 21 Jul 2022 11:29:59 -0700 Subject: [PATCH 15/23] Story cleanup --- ...leLibrary_FunctionRegistryLibrary_test.res | 2 +- packages/squiggle-lang/package.json | 2 +- .../FunctionRegistry_Core.res | 28 +++++++++---------- .../FunctionRegistry/Library/FR_Dict.res | 2 +- .../FunctionRegistry/Library/FR_Sampleset.res | 12 ++++---- .../Reducer_Dispatch_BuiltIn.res | 1 - .../ReducerInterface_GenericDistribution.res | 13 --------- packages/website/docs/Api/DistSampleSet.md | 13 +++++---- 8 files changed, 30 insertions(+), 43 deletions(-) diff --git a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res index a7e98163..2418b4d8 100644 --- a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res +++ b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res @@ -68,7 +68,7 @@ describe("FunctionRegistry Library", () => { "Ok([2,3,4,5,6,7])", ) testEvalToBe( - "toList(SampleSet.mapN([SampleSet.fromList([1,2,3,4,5,6]), SampleSet.fromList([6, 5, 4, 3, 2, 1])], {|x| x[0] > x[1] ? x[0] : x[1]}))", + "SampleSet.toList(SampleSet.mapN([SampleSet.fromList([1,2,3,4,5,6]), SampleSet.fromList([6, 5, 4, 3, 2, 1])], {|x| x[0] > x[1] ? x[0] : x[1]}))", "Ok([6,5,4,4,5,6])", ) }) diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 52c9f07c..e12b363c 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -17,10 +17,10 @@ "test:reducer": "jest __tests__/Reducer*/", "benchmark": "ts-node benchmark/conversion_tests.ts", "test": "jest", - "test:lib": "jest __tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.bs.js", "test:ts": "jest __tests__/TS/", "test:rescript": "jest --modulePathIgnorePatterns=__tests__/TS/*", "test:watch": "jest --watchAll", + "test:fnRegistry": "jest __tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.bs.js", "coverage:rescript": "rm -f *.coverage && yarn clean && BISECT_ENABLE=yes yarn build && yarn test:rescript && bisect-ppx-report html", "coverage:ts": "yarn clean && yarn build && nyc --reporter=lcov yarn test:ts", "coverage:rescript:ci": "yarn clean && BISECT_ENABLE=yes yarn build:rescript && yarn test:rescript && bisect-ppx-report send-to Codecov", diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index f4864531..4b27c221 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -170,7 +170,6 @@ module FRType = { inputs: array, args: array, ): option> => { - // Js.log3("Matching", inputs, args) let isSameLength = E.A.length(inputs) == E.A.length(args) if !isSameLength { None @@ -186,6 +185,9 @@ module FRType = { This module, Matcher, is fairly lengthy. However, only two functions from it are meant to be used outside of it. These are findMatches and matchToDef in Matches.Registry. The rest of it is just called from those two functions. + + Update: This really should be completely re-done sometime, and tested. It works, but it's pretty messy. I'm sure + there are internal bugs, but the end functionality works, so I'm not too worried. */ module Matcher = { module MatchSimple = { @@ -243,11 +245,11 @@ module Matcher = { let match = ( f: function, - namespace: option, + nameSpace: option, fnName: string, args: array, ): match => { - switch namespace { + switch nameSpace { | Some(ns) if ns !== f.nameSpace => Match.DifferentName | _ => { let matchedDefinition = () => @@ -280,12 +282,12 @@ module Matcher = { module RegistryMatch = { type match = { - namespace: string, + nameSpace: string, fnName: string, inputIndex: int, } - let makeMatch = (namespace: string, fnName: string, inputIndex: int) => { - namespace: namespace, + let makeMatch = (nameSpace: string, fnName: string, inputIndex: int) => { + nameSpace: nameSpace, fnName: fnName, inputIndex: inputIndex, } @@ -294,12 +296,12 @@ module Matcher = { module Registry = { let _findExactMatches = ( r: registry, - namespace: option, + nameSpace: option, fnName: string, args: array, ) => { let functionMatchPairs = - r.functions->E.A2.fmap(l => (l, Function.match(l, namespace, fnName, args))) + r.functions->E.A2.fmap(l => (l, Function.match(l, nameSpace, fnName, args))) let fullMatch = functionMatchPairs->E.A.getBy(((_, match)) => Match.isFullMatch(match)) fullMatch->E.O.bind(((fn, match)) => switch match { @@ -311,12 +313,12 @@ module Matcher = { let _findNameMatches = ( r: registry, - namespace: option, + nameSpace: option, fnName: string, args: array, ) => { let functionMatchPairs = - r.functions->E.A2.fmap(l => (l, Function.match(l, namespace, fnName, args))) + r.functions->E.A2.fmap(l => (l, Function.match(l, nameSpace, fnName, args))) let getNameMatches = functionMatchPairs ->E.A2.fmap(((fn, match)) => Match.isNameMatchOnly(match) ? Some((fn, match)) : None) @@ -351,11 +353,11 @@ module Matcher = { let matchToDef = ( registry: registry, - {namespace, fnName, inputIndex}: RegistryMatch.match, + {nameSpace, fnName, inputIndex}: RegistryMatch.match, ): option => registry.functions ->E.A.getBy(fn => { - namespace === fn.nameSpace && fnName === fn.name + nameSpace === fn.nameSpace && fnName === fn.name }) ->E.O.bind(fn => E.A.get(fn.definitions, inputIndex)) } @@ -508,8 +510,6 @@ module Registry = { `There are function matches for ${fnName}(), but with different arguments: ${defs}` } - // let match = Matcher.Registry.findMatches(modified, fnName, args); Js.log2("Match", match) - switch Matcher.Registry.findMatches(modified, fnName, args) { | Matcher.Match.FullMatch(match) => match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, env, reducer)) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res index 10e84f92..0c85bbe1 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res @@ -156,7 +156,7 @@ let library = [ FnDefinition.make( ~name="fromList", ~inputs=[FRTypeArray(FRTypeArray(FRTypeAny))], - ~run=(inputs, _, _, _) =>{ + ~run=(inputs, _, _, _) => { switch inputs { | [IEvArray(items)] => Internals.fromList(items) | _ => Error(impossibleError) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res index b2927b82..9995c3ef 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res @@ -28,8 +28,8 @@ module Internal = { reducer, ) => { let sampleCount = env.sampleCount - let fn = (r) => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, env, reducer) - Belt_Array.makeBy(sampleCount, (r) => fn(r->Js.Int.toFloat))->E.A.R.firstErrorOrOpen + let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, env, reducer) + Belt_Array.makeBy(sampleCount, r => fn(r->Js.Int.toFloat))->E.A.R.firstErrorOrOpen } let map1 = (sampleSetDist: t, aLambdaValue, env, reducer) => { @@ -125,7 +125,7 @@ let library = [ Function.make( ~name="toList", ~nameSpace, - ~requiresNamespace=false, + ~requiresNamespace=true, ~examples=[`SampleSet.toList(SampleSet.fromDist(normal(5,2)))`], ~output=ReducerInterface_InternalExpressionValue.EvtArray, ~definitions=[ @@ -146,9 +146,9 @@ let library = [ Function.make( ~name="fromFn", ~nameSpace, - ~requiresNamespace=false, - ~examples=[`SampleSet.fromFn(sample(normal(5,2)))`], - ~output=ReducerInterface_InternalExpressionValue.EvtArray, + ~requiresNamespace=true, + ~examples=[`SampleSet.fromFn({|| sample(normal(5,2))})`], + ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, ~definitions=[ FnDefinition.make( ~name="fromFn", diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index a2e66298..dbec93c1 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -96,7 +96,6 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce let doExportBindings = (bindings: nameSpace) => bindings->Bindings.toExpressionValue->Ok module SampleMap = { - type t = SampleSetDist.t let doLambdaCall = (aLambdaValue, list) => switch Lambda.doLambdaCall(aLambdaValue, list, environment, reducer) { | Ok(IEvNumber(f)) => Ok(f) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index a65edf2f..addd4388 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -233,19 +233,6 @@ let dispatchToGenericOutput = (call: IEV.functionCall, env: GenericDist.env): op | ("inv", [IEvDistribution(dist), IEvNumber(float)]) => Helpers.toFloatFn(#Inv(float), dist, ~env) | ("quantile", [IEvDistribution(dist), IEvNumber(float)]) => Helpers.toFloatFn(#Inv(float), dist, ~env) - | ("toSampleSet", [IEvDistribution(dist), IEvNumber(float)]) => - Helpers.toDistFn(ToSampleSet(Belt.Int.fromFloat(float)), dist, ~env) - | ("toSampleSet", [IEvDistribution(dist)]) => - Helpers.toDistFn(ToSampleSet(env.sampleCount), dist, ~env) - | ("toList", [IEvDistribution(SampleSet(dist))]) => Some(FloatArray(SampleSetDist.T.get(dist))) - | ("fromSamples", [IEvArray(inputArray)]) => { - let _wrapInputErrors = x => SampleSetDist.NonNumericInput(x) - let parsedArray = Helpers.parseNumberArray(inputArray)->E.R2.errMap(_wrapInputErrors) - switch parsedArray { - | Ok(array) => DistributionOperation.run(FromSamples(array), ~env) - | Error(e) => GenDistError(SampleSetError(e)) - }->Some - } | ("inspect", [IEvDistribution(dist)]) => Helpers.toDistFn(Inspect, dist, ~env) | ("truncateLeft", [IEvDistribution(dist), IEvNumber(float)]) => Helpers.toDistFn(Truncate(Some(float), None), dist, ~env) diff --git a/packages/website/docs/Api/DistSampleSet.md b/packages/website/docs/Api/DistSampleSet.md index 2796a778..68e2e7a8 100644 --- a/packages/website/docs/Api/DistSampleSet.md +++ b/packages/website/docs/Api/DistSampleSet.md @@ -3,10 +3,6 @@ sidebar_position: 5 title: Sample Set Distribution --- -:::danger -These functions aren't yet implemented with these specific names. This should be added soon. -::: - Sample set distributions are one of the three distribution formats. Internally, they are stored as a list of numbers. It's useful to distinguish point set distributions from arbitrary lists of numbers to make it clear which functions are applicable. Monte Carlo calculations typically result in sample set distributions. @@ -25,9 +21,8 @@ Sampleset.fromList: (list) => sampleSet ### fromFn -(Not yet implemented) ``` -Sampleset.fromFn: (() => number) => sampleSet +Sampleset.fromFn: ((float) => number) => sampleSet ``` ### toList @@ -61,3 +56,9 @@ Sampleset.map2: (sampleSet, sampleSet, ((number, number) => number)) => sampleSe ``` Sampleset.map3: (sampleSet, sampleSet, sampleSet, ((number, number, number) => number)) => sampleSet ``` + +### mapN + +``` +Sampleset.mapN: (list, (list => number)) => sampleSet +``` \ No newline at end of file From 0a806b4fe216ee1caff413397c9f395a1a6a2cef Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 21 Jul 2022 11:41:32 -0700 Subject: [PATCH 16/23] Website lint --- packages/website/docs/Api/DistGeneric.mdx | 8 ++++++-- packages/website/docs/Api/DistSampleSet.md | 6 ++++-- packages/website/docs/Api/Function.md | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/website/docs/Api/DistGeneric.mdx b/packages/website/docs/Api/DistGeneric.mdx index e15f3477..247bb4b8 100644 --- a/packages/website/docs/Api/DistGeneric.mdx +++ b/packages/website/docs/Api/DistGeneric.mdx @@ -377,7 +377,11 @@ logScore: ({estimate: distribution, ?prior: distribution, answer: distribution|n **Examples** ```javascript -Dist.logScore({estimate: normal(5, 2), answer: normal(4.5, 1.2), prior: normal(6,4)}); // returns -0.597.57 +Dist.logScore({ + estimate: normal(5, 2), + answer: normal(4.5, 1.2), + prior: normal(6, 4), +}); // returns -0.597.57 ``` ## Display @@ -621,4 +625,4 @@ dotPow: (distributionLike, distributionLike) => distribution ``` dotExp: (distributionLike, distributionLike) => distribution -``` \ No newline at end of file +``` diff --git a/packages/website/docs/Api/DistSampleSet.md b/packages/website/docs/Api/DistSampleSet.md index 68e2e7a8..4da7fee5 100644 --- a/packages/website/docs/Api/DistSampleSet.md +++ b/packages/website/docs/Api/DistSampleSet.md @@ -10,16 +10,18 @@ Monte Carlo calculations typically result in sample set distributions. All regular distribution function work on sample set distributions. In addition, there are several functions that only work on sample set distributions. ### fromDist + ``` Sampleset.fromDist: (list) => sampleSet ``` ### fromList + ``` Sampleset.fromList: (list) => sampleSet ``` -### fromFn +### fromFn ``` Sampleset.fromFn: ((float) => number) => sampleSet @@ -61,4 +63,4 @@ Sampleset.map3: (sampleSet, sampleSet, sampleSet, ((number, number, number) => n ``` Sampleset.mapN: (list, (list => number)) => sampleSet -``` \ No newline at end of file +``` diff --git a/packages/website/docs/Api/Function.md b/packages/website/docs/Api/Function.md index b1c53ea3..1c08bb8f 100644 --- a/packages/website/docs/Api/Function.md +++ b/packages/website/docs/Api/Function.md @@ -7,7 +7,7 @@ title: Function Adds metadata to a function of the input ranges. Works now for numeric and date inputs. This is useful when making formal predictions. It allows you to limit the domain that your prediction will be used and scored within. -The one function that declarations currently have is that they impact plotting. If you ``declare`` a single-variable function within a specific range, this specific range will be plotted. +The one function that declarations currently have is that they impact plotting. If you `declare` a single-variable function within a specific range, this specific range will be plotted. Declarations are currently experimental and will likely be removed or changed in the future. @@ -24,4 +24,4 @@ Function.declare({ {min: 30, max: 100} ] }) -``` \ No newline at end of file +``` From 8dd7aff77fc8405fb1cda511115c18206a48daf7 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 21 Jul 2022 13:48:51 -0700 Subject: [PATCH 17/23] Simple version number --- .../src/rescript/SquiggleLibrary/Versions.res | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 packages/squiggle-lang/src/rescript/SquiggleLibrary/Versions.res diff --git a/packages/squiggle-lang/src/rescript/SquiggleLibrary/Versions.res b/packages/squiggle-lang/src/rescript/SquiggleLibrary/Versions.res new file mode 100644 index 00000000..6554ca4d --- /dev/null +++ b/packages/squiggle-lang/src/rescript/SquiggleLibrary/Versions.res @@ -0,0 +1,9 @@ +module Bindings = Reducer_Bindings + +let bindings: Bindings.t = + [ + ("System.version", ReducerInterface_InternalExpressionValue.IEvString("0.2.11")), + ]->Bindings.fromArray + +let makeBindings = (previousBindings: Bindings.t): Bindings.t => + previousBindings->Bindings.merge(bindings) From 0d4141a899fd4ba87435d53f80acf85089316917 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 21 Jul 2022 13:51:14 -0700 Subject: [PATCH 18/23] Simple refactors to versioning --- .../src/rescript/ReducerInterface/ReducerInterface_StdLib.res | 2 +- .../{Versions.res => SquiggleLibrary_Versions.res} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/squiggle-lang/src/rescript/SquiggleLibrary/{Versions.res => SquiggleLibrary_Versions.res} (100%) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res index 5c1a9c30..6c133332 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -1,6 +1,6 @@ module Bindings = Reducer_Bindings -let internalStdLib = Bindings.emptyBindings->SquiggleLibrary_Math.makeBindings +let internalStdLib = Bindings.emptyBindings->SquiggleLibrary_Math.makeBindings->SquiggleLibrary_Versions.makeBindings @genType let externalStdLib = internalStdLib->Bindings.toTypeScriptBindings diff --git a/packages/squiggle-lang/src/rescript/SquiggleLibrary/Versions.res b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res similarity index 100% rename from packages/squiggle-lang/src/rescript/SquiggleLibrary/Versions.res rename to packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res From 3165e1e499bfbcfbd59d1bcfc12a5e75f69c90cd Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 21 Jul 2022 13:57:11 -0700 Subject: [PATCH 19/23] Updated version --- .../src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res index 6554ca4d..55d1e5b7 100644 --- a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res +++ b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res @@ -2,7 +2,7 @@ module Bindings = Reducer_Bindings let bindings: Bindings.t = [ - ("System.version", ReducerInterface_InternalExpressionValue.IEvString("0.2.11")), + ("System.version", ReducerInterface_InternalExpressionValue.IEvString("0.2.12")), ]->Bindings.fromArray let makeBindings = (previousBindings: Bindings.t): Bindings.t => From 57782aa2a623412e450dfd1596221be13ffb19e2 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 21 Jul 2022 14:59:36 -0700 Subject: [PATCH 20/23] Update DistSampleSet.md --- packages/website/docs/Api/DistSampleSet.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/website/docs/Api/DistSampleSet.md b/packages/website/docs/Api/DistSampleSet.md index 4da7fee5..cfde2be9 100644 --- a/packages/website/docs/Api/DistSampleSet.md +++ b/packages/website/docs/Api/DistSampleSet.md @@ -12,25 +12,25 @@ All regular distribution function work on sample set distributions. In addition, ### fromDist ``` -Sampleset.fromDist: (list) => sampleSet +SampleSet.fromDist: (list) => sampleSet ``` ### fromList ``` -Sampleset.fromList: (list) => sampleSet +SampleSet.fromList: (list) => sampleSet ``` ### fromFn ``` -Sampleset.fromFn: ((float) => number) => sampleSet +SampleSet.fromFn: ((float) => number) => sampleSet ``` ### toList ``` -Sampleset.toList: (sampleSet) => list +SampleSet.toList: (sampleSet) => list ``` Gets the internal samples of a sampleSet distribution. This is separate from the sampleN() function, which would shuffle the samples. toList() maintains order and length. @@ -44,19 +44,19 @@ toList(toSampleSet(normal(5,2))) ### map ``` -Sampleset.map: (sampleSet, (number => number)) => sampleSet +SampleSet.map: (sampleSet, (number => number)) => sampleSet ``` ### map2 ``` -Sampleset.map2: (sampleSet, sampleSet, ((number, number) => number)) => sampleSet +SampleSet.map2: (sampleSet, sampleSet, ((number, number) => number)) => sampleSet ``` ### map3 ``` -Sampleset.map3: (sampleSet, sampleSet, sampleSet, ((number, number, number) => number)) => sampleSet +SampleSet.map3: (sampleSet, sampleSet, sampleSet, ((number, number, number) => number)) => sampleSet ``` ### mapN From 5c78ad1fc4af1d5740032082b5fd4b23ee009561 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 21 Jul 2022 15:36:56 -0700 Subject: [PATCH 21/23] Update DistSampleSet.md --- packages/website/docs/Api/DistSampleSet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/website/docs/Api/DistSampleSet.md b/packages/website/docs/Api/DistSampleSet.md index cfde2be9..cadc1496 100644 --- a/packages/website/docs/Api/DistSampleSet.md +++ b/packages/website/docs/Api/DistSampleSet.md @@ -62,5 +62,5 @@ SampleSet.map3: (sampleSet, sampleSet, sampleSet, ((number, number, number) => n ### mapN ``` -Sampleset.mapN: (list, (list => number)) => sampleSet +SampleSet.mapN: (list, (list => number)) => sampleSet ``` From 0ef01da963ecf11c0138085ceac05ef1eea9e5cb Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 21 Jul 2022 15:44:46 -0700 Subject: [PATCH 22/23] Update DistGeneric.mdx --- packages/website/docs/Api/DistGeneric.mdx | 46 ----------------------- 1 file changed, 46 deletions(-) diff --git a/packages/website/docs/Api/DistGeneric.mdx b/packages/website/docs/Api/DistGeneric.mdx index 247bb4b8..982af57c 100644 --- a/packages/website/docs/Api/DistGeneric.mdx +++ b/packages/website/docs/Api/DistGeneric.mdx @@ -290,38 +290,6 @@ quantile: (distribution, number) => number quantile(normal(5, 2), 0.5); ``` -### toPointSet - -**TODO: Will soon be called "PointSet.make"** - -Converts a distribution to the pointSet format. - -``` -toPointSet: (distribution) => pointSetDistribution -``` - -**Examples** - -```javascript -toPointSet(normal(5, 2)); -``` - -### toSampleSet - -**TODO: Will soon be called "SampleSet.make"** - -Converts a distribution to the sampleSet format, with n samples. - -``` -toSampleSet: (distribution, number) => sampleSetDistribution -``` - -**Examples** - -```javascript -toSampleSet(normal(5, 2), 1000); -``` - ### truncateLeft Truncates the left side of a distribution. Returns either a pointSet distribution or a symbolic distribution. @@ -412,20 +380,6 @@ sparkline: (distribution, n = 20) => string toSparkline(truncateLeft(normal(5, 2), 3), 20); // produces ▁▇█████▇▅▄▃▂▂▁▁▁▁▁▁▁ ``` -### inspect - -Prints the value of the distribution to the Javascript console, then returns the distribution. Useful for debugging. - -``` -inspect: (distribution) => distribution -``` - -**Examples** - -```javascript -inspect(normal(5, 2)); // logs "normal(5, 2)" to the javascript console and returns the distribution. -``` - ## Normalization There are some situations where computation will return unnormalized distributions. This means that their cumulative sums are not equal to 1.0. Unnormalized distributions are not valid for many relevant functions; for example, klDivergence and scoring. From 4a98cc210aef75bbc684f431cd065044bc7a09d0 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 22 Jul 2022 17:49:53 +0200 Subject: [PATCH 23/23] fix compiler warnings --- .../src/rescript/FunctionRegistry/Library/FR_Sampleset.res | 2 +- .../Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res | 2 +- .../ReducerInterface_InternalExpressionValue.res | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res index 9995c3ef..27b870ee 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res @@ -259,7 +259,7 @@ let library = [ ~run=(inputs, _, env, reducer) => switch inputs { | [IEvArray(dists), IEvLambda(lambda)] => - Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(e => { + Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(_e => { "AHHH doesn't work" }) | _ => Error(impossibleError) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index dbec93c1..a2ca204a 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -119,7 +119,7 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce E.A.O.openIfAllSome(E.A.fmap(parseSampleSet, arr)) } - let mapN = (aValueArray: array, aLambdaValue) => { + let _mapN = (aValueArray: array, aLambdaValue) => { switch parseSampleSetArray(aValueArray) { | Some(t1) => let fn = a => doLambdaCall(aLambdaValue, list{IEvArray(E.A.fmap(x => IEvNumber(x), a))}) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index af951d83..3805d790 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -183,6 +183,7 @@ let externalValueToValueType = (value: ExternalExpressionValue.t) => | EvTimeDuration(_) => EvtTimeDuration | EvType(_) => EvtType | EvTypeIdentifier(_) => EvtTypeIdentifier + | EvVoid => EvtVoid } let functionCallToCallSignature = (functionCall: functionCall): functionCallSignature => {