diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res index f43944d4..c386d343 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res @@ -31,9 +31,7 @@ describe("Bindings", () => { describe("extend", () => { let value2 = Reducer_T.IEvNumber(5.) - let extendedBindings = bindings - ->Bindings.extend - ->Bindings.set("value", value2) + let extendedBindings = bindings->Bindings.extend->Bindings.set("value", value2) test("get on extended", () => { expect(extendedBindings->Bindings.get("value")) == Some(value2) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res index 7e667acd..71b9c86d 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res @@ -144,3 +144,4 @@ // let callLambdaExpression = eList(list{lambdaExpression, eNumber(1.)}) // testMacroEval([("y", IEvNumber(666.))], callLambdaExpression, "Ok(667)") // }) + diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Namespace_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Namespace_test.res index 64401e32..e745dc64 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Namespace_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Namespace_test.res @@ -35,13 +35,9 @@ describe("Namespace", () => { let x2 = makeValue(20.) let x3 = makeValue(30.) let x4 = makeValue(40.) - let ns1 = Namespace.make() - ->Namespace.set("x1", x1) - ->Namespace.set("x2", x2) - let ns2 = Namespace.make() - ->Namespace.set("x3", x3) - ->Namespace.set("x4", x4) - + let ns1 = Namespace.make()->Namespace.set("x1", x1)->Namespace.set("x2", x2) + let ns2 = Namespace.make()->Namespace.set("x3", x3)->Namespace.set("x4", x4) + let nsMerged = Namespace.mergeMany([ns, ns1, ns2]) test("merge many 1", () => { diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_test.res index 416e0178..6c60c187 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_test.res @@ -38,58 +38,22 @@ describe("Peggy parse", () => { testParse("1 * 2 / 3", "{(:divide (:multiply 1 2) 3)}") testParse("1 / 2 * 3", "{(:multiply (:divide 1 2) 3)}") testParse("1 / 2 / 3", "{(:divide (:divide 1 2) 3)}") - testParse( - "1 * 2 + 3 * 4", - "{(:add (:multiply 1 2) (:multiply 3 4))}", - ) - testParse( - "1 * 2 - 3 * 4", - "{(:subtract (:multiply 1 2) (:multiply 3 4))}", - ) - testParse( - "1 * 2 .+ 3 * 4", - "{(:dotAdd (:multiply 1 2) (:multiply 3 4))}", - ) - testParse( - "1 * 2 .- 3 * 4", - "{(:dotSubtract (:multiply 1 2) (:multiply 3 4))}", - ) - testParse( - "1 * 2 + 3 .* 4", - "{(:add (:multiply 1 2) (:dotMultiply 3 4))}", - ) - testParse( - "1 * 2 + 3 / 4", - "{(:add (:multiply 1 2) (:divide 3 4))}", - ) - testParse( - "1 * 2 + 3 ./ 4", - "{(:add (:multiply 1 2) (:dotDivide 3 4))}", - ) - testParse( - "1 * 2 - 3 .* 4", - "{(:subtract (:multiply 1 2) (:dotMultiply 3 4))}", - ) - testParse( - "1 * 2 - 3 / 4", - "{(:subtract (:multiply 1 2) (:divide 3 4))}", - ) - testParse( - "1 * 2 - 3 ./ 4", - "{(:subtract (:multiply 1 2) (:dotDivide 3 4))}", - ) - testParse( - "1 * 2 - 3 * 4^5", - "{(:subtract (:multiply 1 2) (:multiply 3 (:pow 4 5)))}", - ) + testParse("1 * 2 + 3 * 4", "{(:add (:multiply 1 2) (:multiply 3 4))}") + testParse("1 * 2 - 3 * 4", "{(:subtract (:multiply 1 2) (:multiply 3 4))}") + testParse("1 * 2 .+ 3 * 4", "{(:dotAdd (:multiply 1 2) (:multiply 3 4))}") + testParse("1 * 2 .- 3 * 4", "{(:dotSubtract (:multiply 1 2) (:multiply 3 4))}") + testParse("1 * 2 + 3 .* 4", "{(:add (:multiply 1 2) (:dotMultiply 3 4))}") + testParse("1 * 2 + 3 / 4", "{(:add (:multiply 1 2) (:divide 3 4))}") + testParse("1 * 2 + 3 ./ 4", "{(:add (:multiply 1 2) (:dotDivide 3 4))}") + testParse("1 * 2 - 3 .* 4", "{(:subtract (:multiply 1 2) (:dotMultiply 3 4))}") + testParse("1 * 2 - 3 / 4", "{(:subtract (:multiply 1 2) (:divide 3 4))}") + testParse("1 * 2 - 3 ./ 4", "{(:subtract (:multiply 1 2) (:dotDivide 3 4))}") + testParse("1 * 2 - 3 * 4^5", "{(:subtract (:multiply 1 2) (:multiply 3 (:pow 4 5)))}") testParse( "1 * 2 - 3 * 4^5^6", "{(:subtract (:multiply 1 2) (:multiply 3 (:pow (:pow 4 5) 6)))}", ) - testParse( - "1 * -a[-2]", - "{(:multiply 1 (:unaryMinus (:$_atIndex_$ :a (:unaryMinus 2))))}", - ) + testParse("1 * -a[-2]", "{(:multiply 1 (:unaryMinus (:$_atIndex_$ :a (:unaryMinus 2))))}") }) describe("multi-line", () => { @@ -111,25 +75,13 @@ describe("Peggy parse", () => { describe("arrays", () => { testParse("[]", "{[]}") testParse("[0, 1, 2]", "{[0; 1; 2]}") - testParse( - "['hello', 'world']", - "{['hello'; 'world']}", - ) - testParse( - "([0,1,2])[1]", - "{(:$_atIndex_$ [0; 1; 2] 1)}", - ) + testParse("['hello', 'world']", "{['hello'; 'world']}") + testParse("([0,1,2])[1]", "{(:$_atIndex_$ [0; 1; 2] 1)}") }) describe("records", () => { - testParse( - "{a: 1, b: 2}", - "{{'a': 1, 'b': 2}}", - ) - testParse( - "{1+0: 1, 2+0: 2}", - "{{(:add 1 0): 1, (:add 2 0): 2}}", - ) // key can be any expression + testParse("{a: 1, b: 2}", "{{'a': 1, 'b': 2}}") + testParse("{1+0: 1, 2+0: 2}", "{{(:add 1 0): 1, (:add 2 0): 2}}") // key can be any expression testParse("record.property", "{(:$_atIndex_$ :record 'property')}") }) @@ -137,10 +89,7 @@ describe("Peggy parse", () => { //function call, array and record access are post operators with higher priority than unary operators testParse("a==!b(1)", "{(:equal :a (:not (:b 1)))}") testParse("a==!b[1]", "{(:equal :a (:not (:$_atIndex_$ :b 1)))}") - testParse( - "a==!b.one", - "{(:equal :a (:not (:$_atIndex_$ :b 'one')))}", - ) + testParse("a==!b.one", "{(:equal :a (:not (:$_atIndex_$ :b 'one')))}") }) describe("comments", () => { @@ -167,14 +116,8 @@ describe("Peggy parse", () => { }) describe("if then else", () => { - testParse( - "if true then 2 else 3", - "{(::$$_ternary_$$ true {2} {3})}", - ) - testParse( - "if false then {2} else {3}", - "{(::$$_ternary_$$ false {2} {3})}", - ) + testParse("if true then 2 else 3", "{(::$$_ternary_$$ true {2} {3})}") + testParse("if false then {2} else {3}", "{(::$$_ternary_$$ false {2} {3})}") testParse( "if false then {2} else if false then {4} else {5}", "{(::$$_ternary_$$ false {2} (::$$_ternary_$$ false {4} {5}))}", @@ -189,51 +132,18 @@ describe("Peggy parse", () => { testParse("a && b || c && d", "{(:or (:and :a :b) (:and :c :d))}") testParse("a && !b || c", "{(:or (:and :a (:not :b)) :c)}") testParse("a && b==c || d", "{(:or (:and :a (:equal :b :c)) :d)}") - testParse( - "a && b!=c || d", - "{(:or (:and :a (:unequal :b :c)) :d)}", - ) - testParse( - "a && !(b==c) || d", - "{(:or (:and :a (:not (:equal :b :c))) :d)}", - ) - testParse( - "a && b>=c || d", - "{(:or (:and :a (:largerEq :b :c)) :d)}", - ) - testParse( - "a && !(b>=c) || d", - "{(:or (:and :a (:not (:largerEq :b :c))) :d)}", - ) - testParse( - "a && b<=c || d", - "{(:or (:and :a (:smallerEq :b :c)) :d)}", - ) + testParse("a && b!=c || d", "{(:or (:and :a (:unequal :b :c)) :d)}") + testParse("a && !(b==c) || d", "{(:or (:and :a (:not (:equal :b :c))) :d)}") + testParse("a && b>=c || d", "{(:or (:and :a (:largerEq :b :c)) :d)}") + testParse("a && !(b>=c) || d", "{(:or (:and :a (:not (:largerEq :b :c))) :d)}") + testParse("a && b<=c || d", "{(:or (:and :a (:smallerEq :b :c)) :d)}") testParse("a && b>c || d", "{(:or (:and :a (:larger :b :c)) :d)}") - testParse( - "a && b { describe("pipe", () => { testParse("1 -> add(2)", "{(:add 1 2)}") testParse("-1 -> add(2)", "{(:add (:unaryMinus 1) 2)}") - testParse( - "-a[1] -> add(2)", - "{(:add (:unaryMinus (:$_atIndex_$ :a 1)) 2)}", - ) + testParse("-a[1] -> add(2)", "{(:add (:unaryMinus (:$_atIndex_$ :a 1)) 2)}") testParse("-f(1) -> add(2)", "{(:add (:unaryMinus (:f 1)) 2)}") testParse("1 + 2 -> add(3)", "{(:add 1 (:add 2 3))}") testParse("1 -> add(2) * 3", "{(:multiply (:add 1 2) 3)}") testParse("1 -> subtract(2)", "{(:subtract 1 2)}") testParse("-1 -> subtract(2)", "{(:subtract (:unaryMinus 1) 2)}") - testParse( - "1 -> subtract(2) * 3", - "{(:multiply (:subtract 1 2) 3)}", - ) + testParse("1 -> subtract(2) * 3", "{(:multiply (:subtract 1 2) 3)}") }) describe("elixir pipe", () => { @@ -269,10 +173,7 @@ describe("Peggy parse", () => { describe("to", () => { testParse("1 to 2", "{(:credibleIntervalToDistribution 1 2)}") - testParse( - "-1 to -2", - "{(:credibleIntervalToDistribution (:unaryMinus 1) (:unaryMinus 2))}", - ) // lower than unary + testParse("-1 to -2", "{(:credibleIntervalToDistribution (:unaryMinus 1) (:unaryMinus 2))}") // lower than unary testParse( "a[1] to a[2]", "{(:credibleIntervalToDistribution (:$_atIndex_$ :a 1) (:$_atIndex_$ :a 2))}", @@ -281,10 +182,7 @@ describe("Peggy parse", () => { "a.p1 to a.p2", "{(:credibleIntervalToDistribution (:$_atIndex_$ :a 'p1') (:$_atIndex_$ :a 'p2'))}", ) // lower than post - testParse( - "1 to 2 + 3", - "{(:add (:credibleIntervalToDistribution 1 2) 3)}", - ) // higher than binary operators + testParse("1 to 2 + 3", "{(:add (:credibleIntervalToDistribution 1 2) 3)}") // higher than binary operators testParse( "1->add(2) to 3->add(4) -> add(4)", "{(:credibleIntervalToDistribution (:add 1 2) (:add (:add 3 4) 4))}", @@ -301,10 +199,7 @@ describe("Peggy parse", () => { testParse("{|x| x}", "{{|:x| :x}}") testParse("f={|x| x}", "{:f = {{|:x| :x}}}") testParse("f(x)=x", "{:f = {|:x| {:x}}}") // Function definitions are lambda assignments - testParse( - "f(x)=x ? 1 : 0", - "{:f = {|:x| {(::$$_ternary_$$ :x 1 0)}}}", - ) // Function definitions are lambda assignments + testParse("f(x)=x ? 1 : 0", "{:f = {|:x| {(::$$_ternary_$$ :x 1 0)}}}") // Function definitions are lambda assignments }) describe("Using lambda as value", () => { @@ -321,18 +216,9 @@ describe("Peggy parse", () => { "{:myaddd = {|:x,:y| {(:add :x :y)}}; :z = {{'x': :myaddd}}; :z}", ) testParse("f({|x| x+1})", "{(:f {|:x| (:add :x 1)})}") - testParse( - "map(arr, {|x| x+1})", - "{(:map :arr {|:x| (:add :x 1)})}", - ) - testParse( - "map([1,2,3], {|x| x+1})", - "{(:map [1; 2; 3] {|:x| (:add :x 1)})}", - ) - testParse( - "[1,2,3]->map({|x| x+1})", - "{(:map [1; 2; 3] {|:x| (:add :x 1)})}", - ) + testParse("map(arr, {|x| x+1})", "{(:map :arr {|:x| (:add :x 1)})}") + testParse("map([1,2,3], {|x| x+1})", "{(:map [1; 2; 3] {|:x| (:add :x 1)})}") + testParse("[1,2,3]->map({|x| x+1})", "{(:map [1; 2; 3] {|:x| (:add :x 1)})}") }) describe("unit", () => { testParse("1m", "{(:fromUnit_m 1)}") @@ -419,7 +305,7 @@ describe("parsing new line", () => { g=f+4 g `, - "{:f = {:x = {1}; :y = {2}; :z = {3}; (:add (:add :x :y) :z)}; :g = {(:add :f 4)}; :g}" + "{:f = {:x = {1}; :y = {2}; :z = {3}; (:add (:add :x :y) :z)}; :g = {(:add :f 4)}; :g}", ) testParse( ` @@ -441,7 +327,7 @@ describe("parsing new line", () => { p -> q `, - "{:f = {:x = {1}; :y = {2}; :z = {3}; (:add (:add :x :y) :z)}; :g = {(:add :f 4)}; (:q (:p (:h :g)))}" + "{:f = {:x = {1}; :y = {2}; :z = {3}; (:add (:add :x :y) :z)}; :g = {(:add :f 4)}; (:q (:p (:h :g)))}", ) testParse( ` @@ -460,6 +346,6 @@ describe("parsing new line", () => { d + e `, - "{(:add (:d (:c (:b :a))) :e)}" + "{(:add (:d (:c (:b :a))) :e)}", ) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res index bcc99bfb..03ef24c8 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res @@ -4,20 +4,12 @@ module InternalExpressionValue = ReducerInterface_InternalExpressionValue open Jest open Reducer_Peggy_TestHelpers +// Note: these tests aren't useful anymore since outer block macro got deleted. +// Probably can be removed or folded into other Peggy tests. describe("Peggy Outer Block", () => { testToExpression("1", "1", ~v="1", ()) testToExpression("x=1", "x = {1}", ~v="()", ()) - testToExpression( - "x=1; y=2", - "x = {1}; y = {2}", - ~v="()", - (), - ) + testToExpression("x=1; y=2", "x = {1}; y = {2}", ~v="()", ()) testToExpression("x=1; 2", "x = {1}; 2", ~v="2", ()) - testToExpression( - "x={a=1; a}; x", - "x = {a = {1}; a}; x", - ~v="1", - (), - ) + testToExpression("x={a=1; a}; x", "x = {a = {1}; a}; x", ~v="1", ()) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res index d2e64393..3016e3c2 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res @@ -25,11 +25,7 @@ describe("Peggy to Expression", () => { describe("multi-line", () => { testToExpression("x=1; 2", "x = {1}; 2", ~v="2", ()) - testToExpression( - "x=1; y=2", - "x = {1}; y = {2}", - (), - ) + testToExpression("x=1; y=2", "x = {1}; y = {2}", ()) }) describe("variables", () => { @@ -39,11 +35,7 @@ describe("Peggy to Expression", () => { }) describe("functions", () => { - testToExpression( - "identity(x) = x", - "identity = {|x| {x}}", - (), - ) // Function definitions become lambda assignments + testToExpression("identity(x) = x", "identity = {|x| {x}}", ()) // Function definitions become lambda assignments testToExpression("identity(x)", "(identity)(x)", ()) // Note value returns error properly testToExpression( "f(x) = x> 2 ? 0 : 1; f(3)", @@ -55,43 +47,15 @@ describe("Peggy to Expression", () => { describe("arrays", () => { testToExpression("[]", "[]", ~v="[]", ()) - testToExpression( - "[0, 1, 2]", - "[0, 1, 2]", - ~v="[0,1,2]", - (), - ) - testToExpression( - "['hello', 'world']", - "['hello', 'world']", - ~v="['hello','world']", - (), - ) - testToExpression( - "([0,1,2])[1]", - "($_atIndex_$)([0, 1, 2], 1)", - ~v="1", - (), - ) + testToExpression("[0, 1, 2]", "[0, 1, 2]", ~v="[0,1,2]", ()) + testToExpression("['hello', 'world']", "['hello', 'world']", ~v="['hello','world']", ()) + testToExpression("([0,1,2])[1]", "($_atIndex_$)([0, 1, 2], 1)", ~v="1", ()) }) describe("records", () => { - testToExpression( - "{a: 1, b: 2}", - "{'a': 1, 'b': 2}", - ~v="{a: 1,b: 2}", - (), - ) - testToExpression( - "{1+0: 1, 2+0: 2}", - "{(add)(1, 0): 1, (add)(2, 0): 2}", - (), - ) // key can be any expression - testToExpression( - "record.property", - "($_atIndex_$)(record, 'property')", - (), - ) + testToExpression("{a: 1, b: 2}", "{'a': 1, 'b': 2}", ~v="{a: 1,b: 2}", ()) + testToExpression("{1+0: 1, 2+0: 2}", "{(add)(1, 0): 1, (add)(2, 0): 2}", ()) // key can be any expression + testToExpression("record.property", "($_atIndex_$)(record, 'property')", ()) testToExpression( "record={property: 1}; record.property", "record = {{'property': 1}}; ($_atIndex_$)(record, 'property')", @@ -103,45 +67,15 @@ describe("Peggy to Expression", () => { describe("comments", () => { testToExpression("1 # This is a line comment", "1", ~v="1", ()) testToExpression("1 // This is a line comment", "1", ~v="1", ()) - testToExpression( - "1 /* This is a multi line comment */", - "1", - ~v="1", - (), - ) - testToExpression( - "/* This is a multi line comment */ 1", - "1", - ~v="1", - (), - ) + testToExpression("1 /* This is a multi line comment */", "1", ~v="1", ()) + testToExpression("/* This is a multi line comment */ 1", "1", ~v="1", ()) }) describe("ternary operator", () => { - testToExpression( - "true ? 1 : 0", - "true ? (1) : (0)", - ~v="1", - (), - ) - testToExpression( - "false ? 1 : 0", - "false ? (1) : (0)", - ~v="0", - (), - ) - testToExpression( - "true ? 1 : false ? 2 : 0", - "true ? (1) : (false ? (2) : (0))", - ~v="1", - (), - ) // nested ternary - testToExpression( - "false ? 1 : false ? 2 : 0", - "false ? (1) : (false ? (2) : (0))", - ~v="0", - (), - ) // nested ternary + testToExpression("true ? 1 : 0", "true ? (1) : (0)", ~v="1", ()) + testToExpression("false ? 1 : 0", "false ? (1) : (0)", ~v="0", ()) + testToExpression("true ? 1 : false ? 2 : 0", "true ? (1) : (false ? (2) : (0))", ~v="1", ()) // nested ternary + testToExpression("false ? 1 : false ? 2 : 0", "false ? (1) : (false ? (2) : (0))", ~v="0", ()) // nested ternary describe("ternary bindings", () => { testToExpression( // expression binding @@ -168,16 +102,8 @@ describe("Peggy to Expression", () => { }) describe("if then else", () => { - testToExpression( - "if true then 2 else 3", - "true ? ({2}) : ({3})", - (), - ) - testToExpression( - "if true then {2} else {3}", - "true ? ({2}) : ({3})", - (), - ) + testToExpression("if true then 2 else 3", "true ? ({2}) : ({3})", ()) + testToExpression("if true then {2} else {3}", "true ? ({2}) : ({3})", ()) testToExpression( "if false then {2} else if false then {4} else {5}", "false ? ({2}) : (false ? ({4}) : ({5}))", @@ -187,18 +113,8 @@ describe("Peggy to Expression", () => { describe("pipe", () => { testToExpression("1 -> add(2)", "(add)(1, 2)", ~v="3", ()) - testToExpression( - "-1 -> add(2)", - "(add)((unaryMinus)(1), 2)", - ~v="1", - (), - ) // note that unary has higher priority naturally - testToExpression( - "1 -> add(2) * 3", - "(multiply)((add)(1, 2), 3)", - ~v="9", - (), - ) + testToExpression("-1 -> add(2)", "(add)((unaryMinus)(1), 2)", ~v="1", ()) // note that unary has higher priority naturally + testToExpression("1 -> add(2) * 3", "(multiply)((add)(1, 2), 3)", ~v="9", ()) }) describe("elixir pipe", () => { @@ -219,27 +135,10 @@ describe("Peggy to Expression", () => { }) describe("lambda", () => { - testToExpression( - "{|x| x}", - "{|x| x}", - ~v="lambda(x=>internal code)", - (), - ) - testToExpression( - "f={|x| x}", - "f = {{|x| x}}", - (), - ) - testToExpression( - "f(x)=x", - "f = {|x| {x}}", - (), - ) // Function definitions are lambda assignments - testToExpression( - "f(x)=x ? 1 : 0", - "f = {|x| {x ? (1) : (0)}}", - (), - ) + testToExpression("{|x| x}", "{|x| x}", ~v="lambda(x=>internal code)", ()) + testToExpression("f={|x| x}", "f = {{|x| x}}", ()) + testToExpression("f(x)=x", "f = {|x| {x}}", ()) // Function definitions are lambda assignments + testToExpression("f(x)=x ? 1 : 0", "f = {|x| {x ? (1) : (0)}}", ()) }) describe("module", () => { diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res index a8c9717e..c69d060c 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res @@ -86,3 +86,4 @@ // expectedValue: string, // ) => testMacroEval_(Only.test, bindArray, expr, expectedValue) // } + diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res index 7d3ab86b..8abf5f7a 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res @@ -50,3 +50,4 @@ // "Ok({properties: {age: #number,name: #string},typeTag: 'typeRecord'})", // ) // myTypeTest(test, "{age: number, name: string}", "{age: number, name: string}") + diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res index be20c5fd..64f2554a 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res @@ -40,3 +40,4 @@ // test(aTypeSourceCode, () => myCheckArgumentsExpectEqual(aTypeSourceCode, sourceCode, answer)) // myCheckArgumentsTest(test, "number=>number=>number", "[1,2]", "Ok") + diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res index f935c7b0..c4272880 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res @@ -71,3 +71,4 @@ // myTypeCheckTest(test, "number<-min(10)", "0", "Expected type: number<-min(10) but got: 0") // myTypeCheckTest(test, "any", "0", "Ok") // myTypeCheckTest(test, "any", "'a'", "Ok") + diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res index 27fe6fce..88f3d9a6 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res @@ -124,3 +124,4 @@ // expect(result)->toEqual(Some(Ok(IEvString("helloworld")))) // }) // }) + diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res index 52f8329b..e48d1223 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res @@ -2,14 +2,8 @@ open Jest open Reducer_TestHelpers describe("Parse function assignment", () => { - testParseToBe( - "f(x)=x", - "Ok(f = {|x| {x}})" - ) - testParseToBe( - "f(x)=2*x", - "Ok(f = {|x| {(multiply)(2, x)}})" - ) + testParseToBe("f(x)=x", "Ok(f = {|x| {x}})") + testParseToBe("f(x)=2*x", "Ok(f = {|x| {(multiply)(2, x)}})") //MathJs does not allow blocks in function definitions }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index 8045d0d2..14f7f380 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -46,10 +46,7 @@ describe("call and bindings", () => { testEvalToBe("f(x)=x+1; y=f(1); f(1)", "Ok(2)") testEvalToBe("f(x)=x+1; y=f(1); z=f(1); z", "Ok(2)") testEvalToBe("f(x)=x+1; g(x)=f(x)+1; g(0)", "Ok(2)") - testParseToBe( - "f=99; g(x)=f; g(2)", - "Ok(f = {99}; g = {|x| {f}}; (g)(2))", - ) + testParseToBe("f=99; g(x)=f; g(2)", "Ok(f = {99}; g = {|x| {f}}; (g)(2))") testEvalToBe("f=99; g(x)=f; g(2)", "Ok(99)") testEvalToBe("f(x)=x; g(x)=f(x); g(2)", "Ok(2)") testEvalToBe("f(x)=x+1; g(x)=f(x)+1; y=g(2); y", "Ok(4)") diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res index 3f66649b..e157ccbf 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res @@ -2,10 +2,7 @@ open Jest open Reducer_TestHelpers describe("Parse ternary operator", () => { - testParseToBe( - "true ? 'YES' : 'NO'", - "Ok(true ? ('YES') : ('NO'))", - ) + testParseToBe("true ? 'YES' : 'NO'", "Ok(true ? ('YES') : ('NO'))") }) describe("Evaluate ternary operator", () => { diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res index 21a0e9c3..78d3f900 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res @@ -119,10 +119,7 @@ describe("eval on distribution functions", () => { describe("parse on distribution functions", () => { describe("power", () => { - testParse( - "normal(5,2) ^ normal(5,1)", - "Ok((pow)((normal)(5, 2), (normal)(5, 1)))", - ) + testParse("normal(5,2) ^ normal(5,1)", "Ok((pow)((normal)(5, 2), (normal)(5, 1)))") testParse("3 ^ normal(5,1)", "Ok((pow)(3, (normal)(5, 1)))") testParse("normal(5,2) ^ 3", "Ok((pow)((normal)(5, 2), 3))") }) @@ -138,18 +135,9 @@ describe("parse on distribution functions", () => { "Ok((:$$_block_$$ (:dotSubtract (:normal 5 2) (:normal 5 1))))", // TODO: !!! returns "Ok({(:dotPow (:normal 5 2) (:normal 5 1))})" ) - testParse( - "normal(5,2) .* normal(5,1)", - "Ok((dotMultiply)((normal)(5, 2), (normal)(5, 1)))", - ) - testParse( - "normal(5,2) ./ normal(5,1)", - "Ok((dotDivide)((normal)(5, 2), (normal)(5, 1)))", - ) - testParse( - "normal(5,2) .^ normal(5,1)", - "Ok((dotPow)((normal)(5, 2), (normal)(5, 1)))", - ) + testParse("normal(5,2) .* normal(5,1)", "Ok((dotMultiply)((normal)(5, 2), (normal)(5, 1)))") + testParse("normal(5,2) ./ normal(5,1)", "Ok((dotDivide)((normal)(5, 2), (normal)(5, 1)))") + testParse("normal(5,2) .^ normal(5,1)", "Ok((dotPow)((normal)(5, 2), (normal)(5, 1)))") }) describe("equality", () => { testParse("5 == normal(5,2)", "Ok((equal)(5, (normal)(5, 2)))") diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res index 3097d74a..3d1fcddc 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res @@ -75,9 +75,7 @@ x=1`, }) test("include as variables", () => { - expect(project->Project.Private.getIncludesAsVariables("main")) == [ - ("myVariable", "myModule"), - ] + expect(project->Project.Private.getIncludesAsVariables("main")) == [("myVariable", "myModule")] }) }) @@ -110,8 +108,6 @@ x=1`, expect(Project.getPastChain(project, "main")) == ["common", "common2"] }) test("include as variables", () => { - expect(project->Project.Private.getIncludesAsVariables("main")) == [ - ("myVariable", "myModule"), - ] + expect(project->Project.Private.getIncludesAsVariables("main")) == [("myVariable", "myModule")] }) }) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res index ccda4b4f..d85d636c 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res @@ -14,8 +14,7 @@ let runFetchResult = (project, sourceId) => { let runFetchFlatBindings = (project, sourceId) => { Project.run(project, sourceId) - Project.getBindings(project, sourceId) - ->InternalExpressionValue.toStringRecord + Project.getBindings(project, sourceId)->InternalExpressionValue.toStringRecord } test("test result true", () => { diff --git a/packages/squiggle-lang/benchmark/Benchmark_Array.res b/packages/squiggle-lang/benchmark/Benchmark_Array.res index 61562732..268fea01 100644 --- a/packages/squiggle-lang/benchmark/Benchmark_Array.res +++ b/packages/squiggle-lang/benchmark/Benchmark_Array.res @@ -24,7 +24,9 @@ module Map: Benchmark_Helpers.BenchmarkTopic = { } let runAll = () => { - Js.log(`Mapping identity function over arrays of size ${arraySize->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`) + Js.log( + `Mapping identity function over arrays of size ${arraySize->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`, + ) Benchmark_Helpers.measure("Belt.Array.map", beltArray) Benchmark_Helpers.measure("Js.Array2.map", jsArray2) Benchmark_Helpers.measure("Array.map", ocamlArray) @@ -65,7 +67,9 @@ module Sort: Benchmark_Helpers.BenchmarkTopic = { } let runAll = () => { - Js.log(`Sorting arrays of size ${arraySize->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`) + Js.log( + `Sorting arrays of size ${arraySize->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`, + ) Benchmark_Helpers.measure("Js.Array2.sort", jsArray2) Benchmark_Helpers.measure("Js.Array2.sort with Ocaml compare", jsArray2withOcamlCompare) Benchmark_Helpers.measure("Array.fast_sort", ocamlArray) diff --git a/packages/squiggle-lang/benchmark/Benchmark_Helpers.res b/packages/squiggle-lang/benchmark/Benchmark_Helpers.res index 0e889d15..e6365bea 100644 --- a/packages/squiggle-lang/benchmark/Benchmark_Helpers.res +++ b/packages/squiggle-lang/benchmark/Benchmark_Helpers.res @@ -1,11 +1,11 @@ module type BenchmarkTopic = { - let runAll: () => unit + let runAll: unit => unit } -let measure = (name: string, f: () => unit) => { - let start = Js.Date.make()->Js.Date.valueOf - f() - let end = Js.Date.make()->Js.Date.valueOf - let duration = (end -. start) /. 1000. - Js.log2(duration, name) +let measure = (name: string, f: unit => unit) => { + let start = Js.Date.make()->Js.Date.valueOf + f() + let end = Js.Date.make()->Js.Date.valueOf + let duration = (end -. start) /. 1000. + Js.log2(duration, name) } diff --git a/packages/squiggle-lang/benchmark/Benchmark_Map.res b/packages/squiggle-lang/benchmark/Benchmark_Map.res index d04d501d..ee9ae51b 100644 --- a/packages/squiggle-lang/benchmark/Benchmark_Map.res +++ b/packages/squiggle-lang/benchmark/Benchmark_Map.res @@ -2,63 +2,61 @@ module StringMap: Benchmark_Helpers.BenchmarkTopic = { let size = 1000 let iterations = 10_000 - let kv = Belt.Array.range(1, size)->Belt.Array.map( - v => ("key" ++ v->Belt.Int.toString, v) - ) + let kv = Belt.Array.range(1, size)->Belt.Array.map(v => ("key" ++ v->Belt.Int.toString, v)) let beltMap = () => { Belt.Range.forEach(1, iterations, _ => { - let m = Belt.Map.String.empty - let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => acc->Belt.Map.String.set(k, v)) + let m = Belt.Map.String.empty + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => acc->Belt.Map.String.set(k, v)) }) } let beltMutableMap = () => { Belt.Range.forEach(1, iterations, _ => { - let m = Belt.MutableMap.String.make() - let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { - acc->Belt.MutableMap.String.set(k, v) - acc - }) + let m = Belt.MutableMap.String.make() + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { + acc->Belt.MutableMap.String.set(k, v) + acc + }) }) } let beltHashMap = () => { Belt.Range.forEach(1, iterations, _ => { - let m = Belt.HashMap.String.make(~hintSize=100) - let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { - acc->Belt.HashMap.String.set(k, v) - acc - }) + let m = Belt.HashMap.String.make(~hintSize=100) + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { + acc->Belt.HashMap.String.set(k, v) + acc + }) }) } let jsDict = () => { Belt.Range.forEach(1, iterations, _ => { - let m = Js.Dict.empty() - let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { - acc->Js.Dict.set(k, v) - acc - }) + let m = Js.Dict.empty() + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { + acc->Js.Dict.set(k, v) + acc + }) }) } let jsMap = () => { Belt.Range.forEach(1, iterations, _ => { - let m = Js_map.make() - let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => - acc->Js_map.set(k, v) - ) + let m = Js_map.make() + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => acc->Js_map.set(k, v)) }) } let runAll = () => { - Js.log(`Filling a map with ("key{i}" => "i") key-value pairs, size ${size->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`) - Benchmark_Helpers.measure("Belt.Map.String", beltMap) - Benchmark_Helpers.measure("Belt.MutableMap.String", beltMutableMap) - Benchmark_Helpers.measure("Belt.HashMap.String", beltHashMap) - Benchmark_Helpers.measure("Js.Dict", jsDict) - Benchmark_Helpers.measure("Js.Map", jsMap) + Js.log( + `Filling a map with ("key{i}" => "i") key-value pairs, size ${size->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`, + ) + Benchmark_Helpers.measure("Belt.Map.String", beltMap) + Benchmark_Helpers.measure("Belt.MutableMap.String", beltMutableMap) + Benchmark_Helpers.measure("Belt.HashMap.String", beltHashMap) + Benchmark_Helpers.measure("Js.Dict", jsDict) + Benchmark_Helpers.measure("Js.Map", jsMap) } } diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res b/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res new file mode 100644 index 00000000..7ab3b1a9 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res @@ -0,0 +1,123 @@ +open FunctionRegistry_Core +open FunctionRegistry_Helpers + +let nameSpace = "" // no namespaced versions + +type simpleDefinition = { + inputs: array, + fn: array => result, +} + +let makeFnMany = (name: string, definitions: array) => + Function.make( + ~name, + ~nameSpace, + ~requiresNamespace=false, + ~definitions=definitions->Js.Array2.map(({inputs, fn}) => + FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ()) + ), + (), + ) + +let makeFn = ( + name: string, + inputs: array, + fn: array => result, +) => makeFnMany(name, [{inputs: inputs, fn: fn}]) + +let makeFF2F = (name: string, fn: (float, float) => float) => { + makeFn(name, [FRTypeNumber, FRTypeNumber], inputs => { + switch inputs { + | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvNumber->Ok + | _ => Error(impossibleError) + } + }) +} + +let makeFF2B = (name: string, fn: (float, float) => bool) => { + makeFn(name, [FRTypeNumber, FRTypeNumber], inputs => { + switch inputs { + | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvBool->Ok + | _ => Error(impossibleError) + } + }) +} + +let makeBB2B = (name: string, fn: (bool, bool) => bool) => { + makeFn(name, [FRTypeBool, FRTypeBool], inputs => { + switch inputs { + | [IEvBool(x), IEvBool(y)] => fn(x, y)->IEvBool->Ok + | _ => Error(impossibleError) + } + }) +} + +let library = [ + makeFF2F("add", (x, y) => x +. y), // infix + (see Reducer/Reducer_Peggy/helpers.ts) + makeFF2F("subtract", (x, y) => x -. y), // infix - + makeFF2F("multiply", (x, y) => x *. y), // infix * + makeFF2F("divide", (x, y) => x /. y), // infix / + makeFF2F("pow", (x, y) => Js.Math.pow_float(~base=x, ~exp=y)), // infix ^ + makeFF2B("equal", (x, y) => x == y), // infix == + makeFF2B("smaller", (x, y) => x < y), // infix < + makeFF2B("smallerEq", (x, y) => x <= y), // infix <= + makeFF2B("larger", (x, y) => x > y), // infix > + makeFF2B("largerEq", (x, y) => x >= y), // infix >= + makeBB2B("or", (x, y) => x || y), // infix || + makeBB2B("and", (x, y) => x && y), // infix && + makeFn("unaryMinus", [FRTypeNumber], inputs => { // unary prefix - + switch inputs { + | [IEvNumber(x)] => IEvNumber(-.x)->Ok + | _ => Error(impossibleError) + } + }), + makeFn("not", [FRTypeNumber], inputs => { // unary prefix ! + switch inputs { + | [IEvNumber(x)] => IEvBool(x != 0.)->Ok + | _ => Error(impossibleError) + } + }), + makeFn("not", [FRTypeBool], inputs => { // unary prefix ! + switch inputs { + | [IEvBool(x)] => IEvBool(!x)->Ok + | _ => Error(impossibleError) + } + }), + makeFn("concat", [FRTypeString, FRTypeString], inputs => { + switch inputs { + | [IEvString(a), IEvString(b)] => { + let answer = Js.String2.concat(a, b) + answer->Reducer_T.IEvString->Ok + } + | _ => Error(impossibleError) + } + }), + makeFn("concat", [FRTypeArray(FRTypeAny), FRTypeArray(FRTypeAny)], inputs => { + switch inputs { + | [IEvArray(originalA), IEvArray(b)] => { + let a = originalA->Js.Array2.copy + let _ = Js.Array2.pushMany(a, b) + a->Reducer_T.IEvArray->Ok + } + | _ => Error(impossibleError) + } + }), + makeFn("inspect", [FRTypeAny], inputs => { + switch inputs { + | [value] => { + Js.log(value->ReducerInterface_InternalExpressionValue.toString) + value->Ok + } + | _ => Error(impossibleError) + } + }), + makeFn("inspect", [FRTypeAny, FRTypeString], inputs => { + switch inputs { + | [value, IEvString(label)] => { + Js.log(`${label}: ${value->ReducerInterface_InternalExpressionValue.toString}`) + value->Ok + } + | _ => Error(impossibleError) + } + }), +] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res b/packages/squiggle-lang/src/rescript/FR/FR_Danger.res similarity index 92% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res rename to packages/squiggle-lang/src/rescript/FR/FR_Danger.res index 71624f60..f457a8f7 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Danger.res @@ -8,11 +8,11 @@ let requiresNamespace = true module Combinatorics = { module Helpers = { - let laplace = ((successes, trials)) => (successes +. 1.0) /. (trials +. 2.0) + let laplace = (successes, trials) => (successes +. 1.0) /. (trials +. 2.0) let factorial = Stdlib.Math.factorial - let choose = ((n, k)) => factorial(n) /. (factorial(n -. k) *. factorial(k)) + let choose = (n, k) => factorial(n) /. (factorial(n -. k) *. factorial(k)) let pow = (base, exp) => Js.Math.pow_float(~base, ~exp) - let binomial = ((n, k, p)) => choose((n, k)) *. pow(p, k) *. pow(1.0 -. p, n -. k) + let binomial = (n, k, p) => choose(n, k) *. pow(p, k) *. pow(1.0 -. p, n -. k) } module Lib = { let laplace = Function.make( @@ -77,8 +77,7 @@ module Integration = { | Reducer_T.IEvNumber(x) => Ok(x) | _ => Error( - "Error 1 in Danger.integrate. It's possible that your function doesn't return a number, try definining auxiliaryFunction(x) = mean(yourFunction(x)) and integrate auxiliaryFunction instead" - ->Reducer_ErrorValue.REOther + "Error 1 in Danger.integrate. It's possible that your function doesn't return a number, try definining auxiliaryFunction(x) = mean(yourFunction(x)) and integrate auxiliaryFunction instead"->Reducer_ErrorValue.REOther, ) } result @@ -142,11 +141,11 @@ module Integration = { resultWithOuterPoints } | Error(b) => - ( - "Integration error 2 in Danger.integrate. It's possible that your function doesn't return a number, try definining auxiliaryFunction(x) = mean(yourFunction(x)) and integrate auxiliaryFunction instead." ++ - "Original error: " ++ - b->Reducer_ErrorValue.errorToString - )->Reducer_ErrorValue.REOther->Error + ("Integration error 2 in Danger.integrate. It's possible that your function doesn't return a number, try definining auxiliaryFunction(x) = mean(yourFunction(x)) and integrate auxiliaryFunction instead." ++ + "Original error: " ++ + b->Reducer_ErrorValue.errorToString) + ->Reducer_ErrorValue.REOther + ->Error } result } @@ -169,7 +168,9 @@ module Integration = { ~run=(inputs, _, env, reducer) => { let result = switch inputs { | [_, _, _, IEvNumber(0.0)] => - "Integration error 4 in Danger.integrate: Increment can't be 0."->Reducer_ErrorValue.REOther->Error + "Integration error 4 in Danger.integrate: Increment can't be 0." + ->Reducer_ErrorValue.REOther + ->Error | [ IEvLambda(aLambda), IEvNumber(min), @@ -186,7 +187,9 @@ module Integration = { ) | _ => Error( - Reducer_ErrorValue.REOther("Integration error 5 in Danger.integrate. Remember that inputs are (function, number (min), number (max), number(increment))") + Reducer_ErrorValue.REOther( + "Integration error 5 in Danger.integrate. Remember that inputs are (function, number (min), number (max), number(increment))", + ), ) } result @@ -221,8 +224,8 @@ module Integration = { env, reducer, )->E.R2.errMap(b => - ("Integration error 7 in Danger.integrate. Something went wrong along the way: " ++ b->Reducer_ErrorValue.errorToString) - ->Reducer_ErrorValue.REOther + ("Integration error 7 in Danger.integrate. Something went wrong along the way: " ++ + b->Reducer_ErrorValue.errorToString)->Reducer_ErrorValue.REOther ) | _ => "Integration error 8 in Danger.integrate. Remember that inputs are (function, number (min), number (max), number(increment))" @@ -287,23 +290,19 @@ module DiminishingReturns = { ) { | (false, _, _, _) => Error( - "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, number of functions should be greater than 1." - ->Reducer_ErrorValue.REOther + "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, number of functions should be greater than 1."->Reducer_ErrorValue.REOther, ) | (_, false, _, _) => Error( - "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, funds should be greater than 0." - ->Reducer_ErrorValue.REOther + "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, funds should be greater than 0."->Reducer_ErrorValue.REOther, ) | (_, _, false, _) => Error( - "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, approximateIncrement should be greater than 0." - ->Reducer_ErrorValue.REOther + "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, approximateIncrement should be greater than 0."->Reducer_ErrorValue.REOther, ) | (_, _, _, false) => Error( - "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, approximateIncrement should be smaller than funds amount." - ->Reducer_ErrorValue.REOther + "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, approximateIncrement should be smaller than funds amount."->Reducer_ErrorValue.REOther, ) | (true, true, true, true) => { let applyFunctionAtPoint = (lambda, point: float) => { @@ -319,8 +318,7 @@ module DiminishingReturns = { | Reducer_T.IEvNumber(x) => Ok(x) | _ => Error( - "Error 1 in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions. It's possible that your function doesn't return a number, try definining auxiliaryFunction(x) = mean(yourFunction(x)) and integrate auxiliaryFunction instead" - ->Reducer_ErrorValue.REOther + "Error 1 in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions. It's possible that your function doesn't return a number, try definining auxiliaryFunction(x) = mean(yourFunction(x)) and integrate auxiliaryFunction instead"->Reducer_ErrorValue.REOther, ) } } @@ -433,7 +431,10 @@ module DiminishingReturns = { } result } - | _ => "Error in Danger.diminishingMarginalReturnsForTwoFunctions"->Reducer_ErrorValue.REOther->Error + | _ => + "Error in Danger.diminishingMarginalReturnsForTwoFunctions" + ->Reducer_ErrorValue.REOther + ->Error }, (), ), diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Date.res b/packages/squiggle-lang/src/rescript/FR/FR_Date.res new file mode 100644 index 00000000..96f94b9d --- /dev/null +++ b/packages/squiggle-lang/src/rescript/FR/FR_Date.res @@ -0,0 +1,159 @@ +open FunctionRegistry_Core +open FunctionRegistry_Helpers + +let makeFn = ( + name: string, + inputs: array, + fn: array => result, +) => + Function.make( + ~name, + ~nameSpace="", + ~requiresNamespace=false, + ~definitions=[FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ())], + (), + ) + +let makeNumberToDurationFn = (name: string, fn: float => DateTime.Duration.t) => + Function.make( + ~name, + ~nameSpace="", + ~requiresNamespace=false, + ~definitions=[ + FnDefinition.make( + ~name, + ~inputs=[FRTypeNumber], + ~run=(inputs, _, _, _) => + switch inputs { + | [IEvNumber(t)] => IEvTimeDuration(fn(t))->Ok + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ) + +let makeDurationToNumberFn = (name: string, fn: DateTime.Duration.t => float) => + Function.make( + ~name, + ~nameSpace="", + ~requiresNamespace=false, + ~definitions=[ + FnDefinition.make( + ~name, + ~inputs=[FRTypeTimeDuration], + ~run=(inputs, _, _, _) => + switch inputs { + | [IEvTimeDuration(t)] => IEvNumber(fn(t))->Ok + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ) + +let library = [ + makeFn("toString", [FRTypeDate], inputs => + switch inputs { + | [IEvDate(t)] => IEvString(DateTime.Date.toString(t))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("makeDateFromYear", [FRTypeNumber], inputs => + switch inputs { + | [IEvNumber(year)] => + switch DateTime.Date.makeFromYear(year) { + | Ok(t) => IEvDate(t)->Ok + | Error(e) => Reducer_ErrorValue.RETodo(e)->Error + } + | _ => Error(impossibleError) + } + ), + makeFn("dateFromNumber", [FRTypeNumber], inputs => + switch inputs { + | [IEvNumber(f)] => IEvDate(DateTime.Date.fromFloat(f))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("toNumber", [FRTypeDate], inputs => + switch inputs { + | [IEvDate(f)] => IEvNumber(DateTime.Date.toFloat(f))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("subtract", [FRTypeDate, FRTypeDate], inputs => + switch inputs { + | [IEvDate(d1), IEvDate(d2)] => + switch DateTime.Date.subtract(d1, d2) { + | Ok(d) => IEvTimeDuration(d)->Ok + | Error(e) => Error(RETodo(e)) + } + | _ => Error(impossibleError) + } + ), + makeFn("subtract", [FRTypeDate, FRTypeTimeDuration], inputs => + switch inputs { + | [IEvDate(d1), IEvTimeDuration(d2)] => IEvDate(DateTime.Date.subtractDuration(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("add", [FRTypeDate, FRTypeTimeDuration], inputs => + switch inputs { + | [IEvDate(d1), IEvTimeDuration(d2)] => IEvDate(DateTime.Date.addDuration(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("toString", [FRTypeTimeDuration], inputs => + switch inputs { + | [IEvTimeDuration(t)] => IEvString(DateTime.Duration.toString(t))->Ok + | _ => Error(impossibleError) + } + ), + makeNumberToDurationFn("minutes", DateTime.Duration.fromMinutes), + makeNumberToDurationFn("fromUnit_minutes", DateTime.Duration.fromMinutes), + makeNumberToDurationFn("hours", DateTime.Duration.fromHours), + makeNumberToDurationFn("fromUnit_hours", DateTime.Duration.fromHours), + makeNumberToDurationFn("days", DateTime.Duration.fromDays), + makeNumberToDurationFn("fromUnit_days", DateTime.Duration.fromDays), + makeNumberToDurationFn("years", DateTime.Duration.fromYears), + makeNumberToDurationFn("fromUnit_years", DateTime.Duration.fromYears), + makeDurationToNumberFn("toMinutes", DateTime.Duration.toMinutes), + makeDurationToNumberFn("toHours", DateTime.Duration.toHours), + makeDurationToNumberFn("toDays", DateTime.Duration.toDays), + makeDurationToNumberFn("toYears", DateTime.Duration.toYears), + makeFn("add", [FRTypeTimeDuration, FRTypeTimeDuration], inputs => + switch inputs { + | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => + IEvTimeDuration(DateTime.Duration.add(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("subtract", [FRTypeTimeDuration, FRTypeTimeDuration], inputs => + switch inputs { + | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => + IEvTimeDuration(DateTime.Duration.subtract(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("multiply", [FRTypeTimeDuration, FRTypeNumber], inputs => + switch inputs { + | [IEvTimeDuration(d1), IEvNumber(d2)] => + IEvTimeDuration(DateTime.Duration.multiply(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("divide", [FRTypeTimeDuration, FRTypeNumber], inputs => + switch inputs { + | [IEvTimeDuration(d1), IEvNumber(d2)] => IEvTimeDuration(DateTime.Duration.divide(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("divide", [FRTypeTimeDuration, FRTypeTimeDuration], inputs => + switch inputs { + | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => IEvNumber(d1 /. d2)->Ok + | _ => Error(impossibleError) + } + ), +] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res similarity index 98% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res rename to packages/squiggle-lang/src/rescript/FR/FR_Dict.res index f1cd86f3..310d295d 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res @@ -17,7 +17,10 @@ module Internals = { ->E.A2.fmap(((key, value)) => Wrappers.evArray([IEvString(key), value])) ->Wrappers.evArray - let fromList = (items: array): result => + let fromList = (items: array): result< + internalExpressionValue, + errorValue, + > => items ->E.A2.fmap(item => { switch (item: internalExpressionValue) { diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dist.res b/packages/squiggle-lang/src/rescript/FR/FR_Dist.res similarity index 100% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dist.res rename to packages/squiggle-lang/src/rescript/FR/FR_Dist.res diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Fn.res b/packages/squiggle-lang/src/rescript/FR/FR_Fn.res similarity index 100% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Fn.res rename to packages/squiggle-lang/src/rescript/FR/FR_Fn.res diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res b/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res similarity index 94% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res rename to packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res index 5b7d5dca..dc449ee4 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res @@ -315,10 +315,11 @@ module Old = { let dispatch = (call: ReducerInterface_InternalExpressionValue.functionCall, environment) => switch dispatchToGenericOutput(call, environment) { - | Some(o) => genericOutputToReducerValue(o) - | None => Reducer_ErrorValue.REOther("Internal error in FR_GenericDist implementation") - ->Reducer_ErrorValue.ErrorException - ->raise + | Some(o) => genericOutputToReducerValue(o) + | None => + Reducer_ErrorValue.REOther("Internal error in FR_GenericDist implementation") + ->Reducer_ErrorValue.ErrorException + ->raise } } @@ -340,24 +341,32 @@ let makeProxyFn = (name: string, inputs: array) => { } let makeOperationFns = (): array => { - let ops = ["add", "multiply", "subtract", "divide", "pow", "log", "dotAdd", "dotMultiply", "dotSubtract", "dotDivide", "dotPow"] - let twoArgTypes = [ - // can't use numeric+numeric, since number+number should be delegated to builtin arithmetics - [FRTypeDist, FRTypeNumber], - [FRTypeNumber, FRTypeDist], - [FRTypeDist, FRTypeDist], - ] + let ops = [ + "add", + "multiply", + "subtract", + "divide", + "pow", + "log", + "dotAdd", + "dotMultiply", + "dotSubtract", + "dotDivide", + "dotPow", + ] + let twoArgTypes = [ + // can't use numeric+numeric, since number+number should be delegated to builtin arithmetics + [FRTypeDist, FRTypeNumber], + [FRTypeNumber, FRTypeDist], + [FRTypeDist, FRTypeDist], + ] - ops->E.A2.fmap( - op => twoArgTypes->E.A2.fmap( - types => makeProxyFn(op, types) - ) - )->E.A.concatMany + ops->E.A2.fmap(op => twoArgTypes->E.A2.fmap(types => makeProxyFn(op, types)))->E.A.concatMany } // TODO - duplicates the switch above, should rewrite with standard FR APIs let library = E.A.concatMany([ - [ + [ makeProxyFn("triangular", [FRTypeNumber, FRTypeNumber, FRTypeNumber]), makeProxyFn("sample", [FRTypeDist]), makeProxyFn("sampleN", [FRTypeDist, FRTypeNumber]), @@ -394,14 +403,14 @@ let library = E.A.concatMany([ makeProxyFn("log10", [FRTypeDist]), makeProxyFn("unaryMinus", [FRTypeDist]), makeProxyFn("dotExp", [FRTypeDist]), - ], - makeOperationFns() + ], + makeOperationFns(), ]) // FIXME - impossible to implement with FR due to arbitrary parameters length; let mxLambda = Reducer_Expression_Lambda.makeFFILambda((inputs, env, _) => { - switch Old.dispatch(("mx", inputs), env) { - | Ok(value) => value - | Error(e) => e->Reducer_ErrorValue.ErrorException->raise - } + switch Old.dispatch(("mx", inputs), env) { + | Ok(value) => value + | Error(e) => e->Reducer_ErrorValue.ErrorException->raise + } }) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res b/packages/squiggle-lang/src/rescript/FR/FR_List.res similarity index 98% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res rename to packages/squiggle-lang/src/rescript/FR/FR_List.res index da9228ca..eb6a653a 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_List.res @@ -66,12 +66,7 @@ module Internals = { reducer: Reducer_T.reducerFn, ) => { Js.Array2.filter(aValueArray, elem => { - let result = Reducer_Expression_Lambda.doLambdaCall( - aLambdaValue, - [elem], - env, - reducer, - ) + let result = Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, [elem], env, reducer) switch result { | IEvBool(true) => true | _ => false diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Mathjs.res b/packages/squiggle-lang/src/rescript/FR/FR_Mathjs.res new file mode 100644 index 00000000..9bffde42 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/FR/FR_Mathjs.res @@ -0,0 +1,70 @@ +open FunctionRegistry_Core +open FunctionRegistry_Helpers + +// FIXME - copy-pasted (see FR_Date.res and others) +let makeFn = ( + name: string, + inputs: array, + fn: array => result, +) => + Function.make( + ~name, + ~nameSpace="", + ~requiresNamespace=false, + ~definitions=[FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ())], + (), + ) + +@module("mathjs") external dummy_: string => unit = "evaluate" +let dummy1_ = dummy_ //Deceive the compiler to make the import although we wont make a call from rescript. Otherwise the optimizer deletes the import + +let mathjsCall1: (string, float) => 'a = %raw(`function (name, arg) { return Mathjs[name](arg); }`) +let mathjsCall2: (string, float, float) => 'a = %raw(`function (name, arg1, arg2) { return Mathjs[name](arg1, arg2); }`) + +let makeMathjsFn1 = ( + name: string +) => { + makeFn(name, [FRTypeNumber], inputs => { + switch inputs { + | [IEvNumber(x)] => mathjsCall1(name, x)->Reducer_Js_Gate.jsToIEv + | _ => Error(impossibleError) + } + }) +} + +let makeMathjsFn2 = ( + name: string +) => { + makeFn(name, [FRTypeNumber, FRTypeNumber], inputs => { + switch inputs { + | [IEvNumber(x), IEvNumber(y)] => mathjsCall2(name, x, y)->Reducer_Js_Gate.jsToIEv + | _ => Error(impossibleError) + } + }) +} + +let library = [ + // TODO - other MathJS + // https://mathjs.org/docs/reference/functions.html + + // Arithmetic functions + makeMathjsFn1("abs"), + makeMathjsFn1("cbrt"), + makeMathjsFn1("ceil"), + makeMathjsFn1("cube"), + makeMathjsFn1("exp"), + makeMathjsFn1("fix"), + makeMathjsFn1("floor"), + + makeMathjsFn2("gcd"), + makeMathjsFn2("hypot"), + makeMathjsFn2("invmod"), + makeMathjsFn2("lcm"), + makeMathjsFn1("log"), // Do we need makeMathjsFn2 for `log` too? + makeMathjsFn1("log10"), + makeMathjsFn1("log2"), + + makeMathjsFn1("factorial"), + makeMathjsFn1("cos"), + +] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Number.res b/packages/squiggle-lang/src/rescript/FR/FR_Number.res similarity index 94% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Number.res rename to packages/squiggle-lang/src/rescript/FR/FR_Number.res index 90707891..bd05164c 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Number.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Number.res @@ -17,18 +17,6 @@ module ArrayNumberDist = { (), ) } - let make2 = (name, fn) => { - FnDefinition.make( - ~name, - ~inputs=[FRTypeArray(FRTypeAny)], - ~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) - ->E.R2.errMap(wrapError), - (), - ) - } } let library = [ diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res similarity index 96% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res rename to packages/squiggle-lang/src/rescript/FR/FR_Pointset.res index 324843d7..61d03c9d 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res @@ -111,8 +111,7 @@ let library = [ ~name="makeContinuous", ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], ~run=(_, inputs, _, _) => - inputsTodist(inputs, r => Continuous(Continuous.make(r))) - ->E.R2.errMap(wrapError), + inputsTodist(inputs, r => Continuous(Continuous.make(r)))->E.R2.errMap(wrapError), (), ), ], @@ -136,8 +135,7 @@ let library = [ ~name="makeDiscrete", ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], ~run=(_, inputs, _, _) => - inputsTodist(inputs, r => Discrete(Discrete.make(r))) - ->E.R2.errMap(wrapError), + inputsTodist(inputs, r => Discrete(Discrete.make(r)))->E.R2.errMap(wrapError), (), ), ], diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res similarity index 98% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res rename to packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res index b27b423e..4c04489b 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res @@ -120,7 +120,8 @@ let libaryBase = [ Prepare.ToTypedArray.numbers(inputs) |> E.R2.bind(r => SampleSetDist.make(r)->E.R2.errMap(_ => "AM I HERE? WHYERE AMI??") ) - sampleSet->E.R2.fmap(Wrappers.sampleSet) + sampleSet + ->E.R2.fmap(Wrappers.sampleSet) ->E.R2.fmap(Wrappers.evDistribution) ->E.R2.errMap(wrapError) }, @@ -291,7 +292,9 @@ module Comparison = { let wrapper = r => r ->E.R2.fmap(r => r->Wrappers.sampleSet->Wrappers.evDistribution) - ->E.R2.errMap(e => e->DistributionTypes.Error.sampleErrorToDistErr->Reducer_ErrorValue.REDistributionError) + ->E.R2.errMap(e => + e->DistributionTypes.Error.sampleErrorToDistErr->Reducer_ErrorValue.REDistributionError + ) let mkBig = (name, withDist, withFloat) => Function.make( diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Scoring.res b/packages/squiggle-lang/src/rescript/FR/FR_Scoring.res similarity index 100% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Scoring.res rename to packages/squiggle-lang/src/rescript/FR/FR_Scoring.res diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Units.res b/packages/squiggle-lang/src/rescript/FR/FR_Units.res similarity index 72% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Units.res rename to packages/squiggle-lang/src/rescript/FR/FR_Units.res index 90ea56bc..3935b197 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Units.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Units.res @@ -22,14 +22,13 @@ let makeUnitFn = (name: string, multiplier: float) => { ) } - let library = [ - makeUnitFn("n", 1E-9), - makeUnitFn("m", 1E-3), - makeUnitFn("k", 1E3), - makeUnitFn("M", 1E6), - makeUnitFn("B", 1E9), - makeUnitFn("G", 1E9), - makeUnitFn("T", 1E12), - makeUnitFn("P", 1E15), + makeUnitFn("n", 1E-9), + makeUnitFn("m", 1E-3), + makeUnitFn("k", 1E3), + makeUnitFn("M", 1E6), + makeUnitFn("B", 1E9), + makeUnitFn("G", 1E9), + makeUnitFn("T", 1E12), + makeUnitFn("P", 1E15), ] diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res index dabd72a5..ac9c167c 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -212,8 +212,7 @@ let setEnvironment = (project: reducerProject, environment: environment): unit = project->Private.setEnvironment(environment) @genType -let getEnvironment = (project: reducerProject): environment => - project->Private.getEnvironment +let getEnvironment = (project: reducerProject): environment => project->Private.getEnvironment /* Foreign function interface is intentionally demolished. diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index 714456a8..a5685f2e 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -225,9 +225,9 @@ module FnDefinition = { } let make = (~name, ~inputs, ~run, ()): t => { - name, - inputs, - run, + name: name, + inputs: inputs, + run: run, } } @@ -253,14 +253,14 @@ module Function = { ~isExperimental=false, (), ): t => { - name, - nameSpace, - definitions, - output, + name: name, + nameSpace: nameSpace, + definitions: definitions, + output: output, examples: examples |> E.O.default([]), - isExperimental, - requiresNamespace, - description, + isExperimental: isExperimental, + requiresNamespace: requiresNamespace, + description: description, } let toJson = (t: t): functionJson => { @@ -288,12 +288,8 @@ module Registry = { // 1. functions // 2. definitions of each function // 3. name variations of each definition - r->Belt.Array.reduce( - Belt.Map.String.empty, - (acc, fn) => - fn.definitions->Belt.Array.reduce( - acc, - (acc, def) => { + r->Belt.Array.reduce(Belt.Map.String.empty, (acc, fn) => + fn.definitions->Belt.Array.reduce(acc, (acc, def) => { let names = [ fn.nameSpace == "" ? [] : [`${fn.nameSpace}.${def.name}`], @@ -338,8 +334,7 @@ module Registry = { let match = definitions->Js.Array2.find(def => def->FnDefinition.isMatch(args)) switch match { - | Some(def) => - def->FnDefinition.run(args, env, reducer) + | Some(def) => def->FnDefinition.run(args, env, reducer) | None => REOther(showNameMatchDefinitions())->Error } } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index 6a3931af..cf24bfc4 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -225,13 +225,11 @@ module DefineFn = { FnDefinition.make( ~name, ~inputs=[FRTypeNumber], - ~run=(_, inputs, _, _) => { - inputs - ->getOrError(0) - ->E.R.bind(Prepare.oneNumber) - ->E.R2.fmap(fn) - ->E.R2.fmap(Wrappers.evNumber) - ->E.R2.errMap(e => Reducer_ErrorValue.REOther(e)) + ~run=(inputs, _, _, _) => { + switch inputs { + | [IEvNumber(x)] => fn(x)->IEvNumber->Ok + | _ => Error(impossibleError) + } }, (), ) @@ -239,12 +237,11 @@ module DefineFn = { FnDefinition.make( ~name, ~inputs=[FRTypeNumber, FRTypeNumber], - ~run=(_, inputs, _, _) => { - inputs - ->Prepare.ToValueTuple.twoNumbers - ->E.R2.fmap(fn) - ->E.R2.fmap(Wrappers.evNumber) - ->E.R2.errMap(e => Reducer_ErrorValue.REOther(e)) + ~run=(inputs, _, _, _) => { + switch inputs { + | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvNumber->Ok + | _ => Error(impossibleError) + } }, (), ) @@ -252,12 +249,11 @@ module DefineFn = { FnDefinition.make( ~name, ~inputs=[FRTypeNumber, FRTypeNumber, FRTypeNumber], - ~run=(_, inputs, _, _) => { - inputs - ->Prepare.ToValueTuple.threeNumbers - ->E.R2.fmap(fn) - ->E.R2.fmap(Wrappers.evNumber) - ->E.R2.errMap(e => Reducer_ErrorValue.REOther(e)) + ~run=(inputs, _, _, _) => { + switch inputs { + | [IEvNumber(x), IEvNumber(y), IEvNumber(z)] => fn(x, y, z)->IEvNumber->Ok + | _ => Error(impossibleError) + } }, (), ) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res deleted file mode 100644 index b3103add..00000000 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res +++ /dev/null @@ -1,163 +0,0 @@ -open FunctionRegistry_Core -open FunctionRegistry_Helpers - -let nameSpace = "" // no namespaced versions - -type simpleDefinition = { - inputs: array, - fn: array => result, -} - -let makeFnMany = (name: string, definitions: array) => - Function.make( - ~name, - ~nameSpace, - ~requiresNamespace=false, - ~definitions=definitions->Js.Array2.map(({inputs, fn}) => - FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ()) - ), - (), - ) - -let makeFn = ( - name: string, - inputs: array, - fn: array => result, -) => makeFnMany(name, [{ inputs, fn }]) - -let makeBinaryFn = (name: string, fn: (float, float) => float) => { - makeFn( - name, - [FRTypeNumber, FRTypeNumber], - inputs => { - switch inputs { - | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvNumber->Ok - | _ => Error(impossibleError) - } - } - ) -} - -let makeBinaryCmpFn = (name: string, fn: (float, float) => bool) => { - makeFn( - name, - [FRTypeNumber, FRTypeNumber], - inputs => { - switch inputs { - | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvBool->Ok - | _ => Error(impossibleError) - } - } - ) -} - -let makeBinaryBooleanFn = (name: string, fn: (bool, bool) => bool) => { - makeFn( - name, - [FRTypeBool, FRTypeBool], - inputs => { - switch inputs { - | [IEvBool(x), IEvBool(y)] => fn(x, y)->IEvBool->Ok - | _ => Error(impossibleError) - } - } - ) -} - -let library = [ - makeBinaryFn("add", (x, y) => x +. y), - makeBinaryFn("subtract", (x, y) => x -. y), - makeBinaryFn("multiply", (x, y) => x *. y), - makeBinaryFn("divide", (x, y) => x /. y), - makeBinaryFn("pow", (x, y) => Js.Math.pow_float(~base=x, ~exp=y)), - makeBinaryCmpFn("equal", (x, y) => x == y), - makeBinaryCmpFn("smaller", (x, y) => x < y), - makeBinaryCmpFn("smallerEq", (x, y) => x <= y), - makeBinaryCmpFn("larger", (x, y) => x > y), - makeBinaryCmpFn("largerEq", (x, y) => x >= y), - makeBinaryBooleanFn("or", (x, y) => x || y), - makeBinaryBooleanFn("and", (x, y) => x && y), - makeFn( - "unaryMinus", - [FRTypeNumber], - inputs => { - switch inputs { - | [IEvNumber(x)] => IEvNumber(-.x)->Ok - | _ => Error(impossibleError) - } - } - ), - makeFn( - "not", - [FRTypeNumber], - inputs => { - switch inputs { - | [IEvNumber(x)] => IEvBool(x != 0.)->Ok - | _ => Error(impossibleError) - } - } - ), - makeFn( - "not", - [FRTypeBool], - inputs => { - switch inputs { - | [IEvBool(x)] => IEvBool(!x)->Ok - | _ => Error(impossibleError) - } - } - ), - makeFn( - "concat", - [FRTypeString, FRTypeString], - inputs => { - switch inputs { - | [IEvString(a), IEvString(b)] => { - let answer = Js.String2.concat(a, b) - answer->Reducer_T.IEvString->Ok - } - | _ => Error(impossibleError) - } - } - ), - makeFn( - "concat", - [FRTypeArray(FRTypeAny), FRTypeArray(FRTypeAny)], - inputs => { - switch inputs { - | [IEvArray(originalA), IEvArray(b)] => { - let a = originalA->Js.Array2.copy - let _ = Js.Array2.pushMany(a, b) - a->Reducer_T.IEvArray->Ok - } - | _ => Error(impossibleError) - } - } - ), - makeFn( - "inspect", - [FRTypeAny], - inputs => { - switch inputs { - | [value] => { - Js.log(value->ReducerInterface_InternalExpressionValue.toString) - value->Ok - } - | _ => Error(impossibleError) - } - } - ), - makeFn( - "inspect", - [FRTypeAny, FRTypeString], - inputs => { - switch inputs { - | [value, IEvString(label)] => { - Js.log(`${label}: ${value->ReducerInterface_InternalExpressionValue.toString}`) - value->Ok - } - | _ => Error(impossibleError) - } - } - ), -] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Date.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Date.res deleted file mode 100644 index 0e79d8cd..00000000 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Date.res +++ /dev/null @@ -1,155 +0,0 @@ -open FunctionRegistry_Core -open FunctionRegistry_Helpers - -let makeFn = ( - name: string, - inputs: array, - fn: array => result -) => - Function.make( - ~name, - ~nameSpace="", - ~requiresNamespace=false, - ~definitions=[ - FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ()) - ], - () - ) - -let makeNumberToDurationFn = ( - name: string, - fn: float => DateTime.Duration.t, -) => - Function.make( - ~name, - ~nameSpace="", - ~requiresNamespace=false, - ~definitions=[ - FnDefinition.make(~name, ~inputs=[FRTypeNumber], ~run=(inputs, _, _, _) => - switch inputs { - | [IEvNumber(t)] => IEvTimeDuration(fn(t))->Ok - | _ => Error(impossibleError) - }, ()) - ], - () - ) - -let makeDurationToNumberFn = ( - name: string, - fn: DateTime.Duration.t => float, -) => - Function.make( - ~name, - ~nameSpace="", - ~requiresNamespace=false, - ~definitions=[ - FnDefinition.make(~name, ~inputs=[FRTypeTimeDuration], ~run=(inputs, _, _, _) => - switch inputs { - | [IEvTimeDuration(t)] => IEvNumber(fn(t))->Ok - | _ => Error(impossibleError) - }, ()) - ], - () - ) - -let library = [ - makeFn("toString", [FRTypeDate], (inputs) => - switch inputs { - | [IEvDate(t)] => IEvString(DateTime.Date.toString(t))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("makeDateFromYear", [FRTypeNumber], (inputs) => - switch inputs { - | [IEvNumber(year)] => - switch DateTime.Date.makeFromYear(year) { - | Ok(t) => IEvDate(t)->Ok - | Error(e) => Reducer_ErrorValue.RETodo(e)->Error - } - | _ => Error(impossibleError) - } - ), - makeFn("dateFromNumber", [FRTypeNumber], (inputs) => - switch inputs { - | [IEvNumber(f)] => IEvDate(DateTime.Date.fromFloat(f))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("toNumber", [FRTypeDate], (inputs) => - switch inputs { - | [IEvDate(f)] => IEvNumber(DateTime.Date.toFloat(f))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("subtract", [FRTypeDate, FRTypeDate], (inputs) => - switch inputs { - | [IEvDate(d1), IEvDate(d2)] => switch DateTime.Date.subtract(d1, d2) { - | Ok(d) => IEvTimeDuration(d)->Ok - | Error(e) => Error(RETodo(e)) - } - | _ => Error(impossibleError) - } - ), - makeFn("subtract", [FRTypeDate, FRTypeTimeDuration], (inputs) => - switch inputs { - | [IEvDate(d1), IEvTimeDuration(d2)] => - IEvDate(DateTime.Date.subtractDuration(d1, d2))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("add", [FRTypeDate, FRTypeTimeDuration], (inputs) => - switch inputs { - | [IEvDate(d1), IEvTimeDuration(d2)] => - IEvDate(DateTime.Date.addDuration(d1, d2))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("toString", [FRTypeTimeDuration], (inputs) => - switch inputs { - | [IEvTimeDuration(t)] => IEvString(DateTime.Duration.toString(t))->Ok - | _ => Error(impossibleError) - } - ), - makeNumberToDurationFn("minutes", DateTime.Duration.fromMinutes), - makeNumberToDurationFn("fromUnit_minutes", DateTime.Duration.fromMinutes), - makeNumberToDurationFn("hours", DateTime.Duration.fromHours), - makeNumberToDurationFn("fromUnit_hours", DateTime.Duration.fromHours), - makeNumberToDurationFn("days", DateTime.Duration.fromDays), - makeNumberToDurationFn("fromUnit_days", DateTime.Duration.fromDays), - makeNumberToDurationFn("years", DateTime.Duration.fromYears), - makeNumberToDurationFn("fromUnit_years", DateTime.Duration.fromYears), - makeDurationToNumberFn("toMinutes", DateTime.Duration.toMinutes), - makeDurationToNumberFn("toHours", DateTime.Duration.toHours), - makeDurationToNumberFn("toDays", DateTime.Duration.toDays), - makeDurationToNumberFn("toYears", DateTime.Duration.toYears), - makeFn("add", [FRTypeTimeDuration, FRTypeTimeDuration], (inputs) => - switch inputs { - | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => IEvTimeDuration(DateTime.Duration.add(d1, d2))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("subtract", [FRTypeTimeDuration, FRTypeTimeDuration], (inputs) => - switch inputs { - | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => IEvTimeDuration(DateTime.Duration.subtract(d1, d2))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("multiply", [FRTypeTimeDuration, FRTypeNumber], (inputs) => - switch inputs { - | [IEvTimeDuration(d1), IEvNumber(d2)] => IEvTimeDuration(DateTime.Duration.multiply(d1, d2))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("divide", [FRTypeTimeDuration, FRTypeNumber], (inputs) => - switch inputs { - | [IEvTimeDuration(d1), IEvNumber(d2)] => IEvTimeDuration(DateTime.Duration.divide(d1, d2))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("divide", [FRTypeTimeDuration, FRTypeTimeDuration], (inputs) => - switch inputs { - | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => IEvNumber(d1 /. d2)->Ok - | _ => Error(impossibleError) - } - ), -] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Mathjs.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Mathjs.res deleted file mode 100644 index c1141545..00000000 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Mathjs.res +++ /dev/null @@ -1,38 +0,0 @@ -open FunctionRegistry_Core -open FunctionRegistry_Helpers - -// FIXME - copy-pasted (see FR_Date.res and others) -let makeFn = ( - name: string, - inputs: array, - fn: array => result -) => - Function.make( - ~name, - ~nameSpace="", - ~requiresNamespace=false, - ~definitions=[ - FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ()) - ], - () - ) - -@module("mathjs") external dummy_: string => unit = "evaluate" -let dummy1_ = dummy_ //Deceive the compiler to make the import although we wont make a call from rescript. Otherwise the optimizer deletes the import - -let mathjsFactorial: float => 'a = %raw(`function (expr) { return Mathjs.factorial(expr); }`) - -let library = [ - // TODO - other MathJS - // https://mathjs.org/docs/reference/functions.html - makeFn( - "factorial", - [FRTypeNumber], - inputs => { - switch inputs { - | [IEvNumber(x)] => mathjsFactorial(x)->Reducer_Js_Gate.jsToIEv - | _ => Error(impossibleError) - } - } - ), -] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/README.md b/packages/squiggle-lang/src/rescript/FunctionRegistry/README.md index e974b189..cf22d878 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/README.md +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/README.md @@ -42,5 +42,7 @@ Key types, internal functionality, and a `Registry` module with a `matchAndRun` **FunctionRegistry_Library** A list of all the Functions defined in the Function Registry. +The definition arrays are stored in `FR_*` modules, by convention. + **FunctionRegistry_Helpers** A list of helper functions for the FunctionRegistry_Library. diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res new file mode 100644 index 00000000..4ca31638 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res @@ -0,0 +1,89 @@ +/* + Bindings describe the entire set of bound variables accessible to the squiggle code. + Bindings objects are stored as linked lists of scopes: + { localX: ..., localY: ... } <- { globalZ: ..., ... } <- { importedT: ..., ... } <- { stdlibFunction: ..., ... } +*/ + +type t = Reducer_T.bindings +type internalExpressionValue = Reducer_T.value + +let rec get = ({namespace, parent}: t, id: string) => { + switch namespace->Reducer_Namespace.get(id) { + | Some(v) => Some(v) + | None => + switch parent { + | Some(p) => p->get(id) + | None => None + } + } +} + +let set = ({namespace} as bindings: t, id: string, value): t => { + { + ...bindings, + namespace: namespace->Reducer_Namespace.set(id, value), + } +} + +let rec toString = ({namespace, parent}: t) => { + let pairs = namespace->Reducer_Namespace.toString + + switch parent { + | Some(p) => `{${pairs}} / ${toString(p)}` + | None => `{${pairs}}` + } +} + +let extend = (bindings: t): t => {namespace: Reducer_Namespace.make(), parent: bindings->Some} + +let make = (): t => {namespace: Reducer_Namespace.make(), parent: None} + +let removeResult = ({namespace} as bindings: t): t => { + ...bindings, + namespace: namespace->Belt.Map.String.remove("__result__"), +} + +let locals = ({namespace}: t): Reducer_T.namespace => namespace + +let fromNamespace = (namespace: Reducer_Namespace.t): t => {namespace: namespace, parent: None} + +// let typeAliasesKey = "_typeAliases_" +// let typeReferencesKey = "_typeReferences_" + +// let getType = (NameSpace(container): t, id: string) => { +// Belt.Map.String.get(container, typeAliasesKey)->Belt.Option.flatMap(aliases => +// switch aliases { +// | IEvRecord(r) => Belt.Map.String.get(r, id) +// | _ => None +// } +// ) +// } + +// let getTypeOf = (NameSpace(container): t, id: string) => { +// Belt.Map.String.get(container, typeReferencesKey)->Belt.Option.flatMap(defs => +// switch defs { +// | IEvRecord(r) => Belt.Map.String.get(r, id) +// | _ => None +// } +// ) +// } + +// let setTypeAlias = (NameSpace(container): t, id: string, value): t => { +// let rValue = Belt.Map.String.getWithDefault(container, typeAliasesKey, IEvRecord(emptyMap)) +// let r = switch rValue { +// | IEvRecord(r) => r +// | _ => emptyMap +// } +// let r2 = Belt.Map.String.set(r, id, value)->IEvRecord +// NameSpace(Belt.Map.String.set(container, typeAliasesKey, r2)) +// } + +// let setTypeOf = (NameSpace(container): t, id: string, value): t => { +// let rValue = Belt.Map.String.getWithDefault(container, typeReferencesKey, IEvRecord(emptyMap)) +// let r = switch rValue { +// | IEvRecord(r) => r +// | _ => emptyMap +// } +// let r2 = Belt.Map.String.set(r, id, value)->IEvRecord +// NameSpace(Belt.Map.String.set(container, typeReferencesKey, r2)) +// } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings/Reducer_Bindings.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings/Reducer_Bindings.res deleted file mode 100644 index c00dbe5c..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings/Reducer_Bindings.res +++ /dev/null @@ -1,141 +0,0 @@ -// Only Bindings as the global module is supported -// Other module operations such as import export will be preprocessed jobs - -module ExpressionT = Reducer_Expression_T -module T = Reducer_T - -type t = Reducer_T.bindings -type internalExpressionValue = Reducer_T.value - -let rec get = ({ namespace, parent }: t, id: string) => { - switch namespace->Reducer_Namespace.get(id) { - | Some(v) => Some(v) - | None => - switch parent { - | Some(p) => get(p, id) - | None => None - } - } -} - -let set = ({ namespace } as bindings: t, id: string, value): t => { - { - ...bindings, - namespace: namespace->Reducer_Namespace.set(id, value), - } -} - -let rec toString = ({ namespace, parent }: t) => { - let pairs = namespace->Reducer_Namespace.toString - - switch parent { - | Some(p) => `{${pairs}} / ${toString(p)}` - | None => `{${pairs}}` - } -} - -let extend = (bindings: t): t => { namespace: Reducer_Namespace.make(), parent: bindings->Some } - -let make = (): t => { namespace: Reducer_Namespace.make(), parent: None } - -let removeResult = ({ namespace } as bindings: t): t => { - ...bindings, - namespace: namespace->Belt.Map.String.remove("__result__"), -} - -let locals = ({ namespace }: t): Reducer_T.namespace => namespace - -let fromNamespace = (namespace: Reducer_Namespace.t): t => { namespace, parent: None } - -// let typeAliasesKey = "_typeAliases_" -// let typeReferencesKey = "_typeReferences_" - -// let getType = (NameSpace(container): t, id: string) => { -// Belt.Map.String.get(container, typeAliasesKey)->Belt.Option.flatMap(aliases => -// switch aliases { -// | IEvRecord(r) => Belt.Map.String.get(r, id) -// | _ => None -// } -// ) -// } - -// let getTypeOf = (NameSpace(container): t, id: string) => { -// Belt.Map.String.get(container, typeReferencesKey)->Belt.Option.flatMap(defs => -// switch defs { -// | IEvRecord(r) => Belt.Map.String.get(r, id) -// | _ => None -// } -// ) -// } - -// let setTypeAlias = (NameSpace(container): t, id: string, value): t => { -// let rValue = Belt.Map.String.getWithDefault(container, typeAliasesKey, IEvRecord(emptyMap)) -// let r = switch rValue { -// | IEvRecord(r) => r -// | _ => emptyMap -// } -// let r2 = Belt.Map.String.set(r, id, value)->IEvRecord -// NameSpace(Belt.Map.String.set(container, typeAliasesKey, r2)) -// } - -// let setTypeOf = (NameSpace(container): t, id: string, value): t => { -// let rValue = Belt.Map.String.getWithDefault(container, typeReferencesKey, IEvRecord(emptyMap)) -// let r = switch rValue { -// | IEvRecord(r) => r -// | _ => emptyMap -// } -// let r2 = Belt.Map.String.set(r, id, value)->IEvRecord -// NameSpace(Belt.Map.String.set(container, typeReferencesKey, r2)) -// } - -// let functionNotFoundError = (call: functionCall) => -// REFunctionNotFound(call->functionCallToCallSignature->functionCallSignatureToString)->Error - -// let functionNotFoundErrorFFIFn = (functionName: string): ExpressionT.ffiFn => { -// (args: array, _environment: environment): result< -// internalExpressionValue, -// errorValue, -// > => { -// let call = (functionName, args) -// functionNotFoundError(call) -// } -// } - -// let convertOptionToFfiFnReturningResult = ( -// myFunctionName: string, -// myFunction: ExpressionT.optionFfiFnReturningResult, -// ): ExpressionT.ffiFn => { -// (args: array, environment) => { -// myFunction(args, environment)->Belt.Option.getWithDefault( -// functionNotFoundErrorFFIFn(myFunctionName)(args, environment), -// ) -// } -// } - -// let convertOptionToFfiFn = ( -// myFunctionName: string, -// myFunction: ExpressionT.optionFfiFn, -// ): ExpressionT.ffiFn => { -// (args: array, environment) => { -// myFunction(args, environment) -// ->Belt.Option.map(v => v->Ok) -// ->Belt.Option.getWithDefault(functionNotFoundErrorFFIFn(myFunctionName)(args, environment)) -// } -// } - -// -- Module definition -// let define = (NameSpace(container): t, identifier: string, ev: internalExpressionValue): t => { -// NameSpace(Belt.Map.String.set(container, identifier, ev)) -// } - -// let defineNumber = (nameSpace: t, identifier: string, value: float): t => -// nameSpace->define(identifier, IEvNumber(value)) - -// let defineString = (nameSpace: t, identifier: string, value: string): t => -// nameSpace->define(identifier, IEvString(value)) - -// let defineBool = (nameSpace: t, identifier: string, value: bool): t => -// nameSpace->define(identifier, IEvBool(value)) - -// let defineModule = (nameSpace: t, identifier: string, value: t): t => -// nameSpace->define(identifier, toExpressionValue(value)) 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 deleted file mode 100644 index 1ef4a543..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ /dev/null @@ -1,148 +0,0 @@ -module Bindings = Reducer_Bindings -// module Continuation = ReducerInterface_Value_Continuation -module ExpressionT = Reducer_Expression_T -module ExternalLibrary = ReducerInterface.ExternalLibrary -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module Lambda = Reducer_Expression_Lambda -module MathJs = Reducer_MathJs -module Result = Belt.Result -module TypeBuilder = Reducer_Type_TypeBuilder - -module IEV = ReducerInterface_InternalExpressionValue - -open Reducer_ErrorValue - -/* - MathJs provides default implementations for built-ins - This is where all the expected built-ins like + = * / sin cos log ln etc are handled - DO NOT try to add external function mapping here! -*/ - -//TODO: pow to xor - -exception TestRescriptException - -let callInternal = ( - call: IEV.functionCall, - _: Reducer_T.environment, - _: Reducer_T.reducerFn, -): result<'b, errorValue> => { - let callMathJs = (call: IEV.functionCall): result<'b, errorValue> => - switch call { - | ("javascriptraise", [msg]) => Js.Exn.raiseError(IEV.toString(msg)) // For Tests - | ("rescriptraise", _) => raise(TestRescriptException) // For Tests - | call => call->IEV.toStringFunctionCall->MathJs.Eval.eval - } - - // let doAddArray = (originalA, b) => { - // let a = originalA->Js.Array2.copy - // let _ = Js.Array2.pushMany(a, b) - // a->Reducer_T.IEvArray->Ok - // } - // let doAddString = (a, b) => { - // let answer = Js.String2.concat(a, b) - // answer->Reducer_T.IEvString->Ok - // } - - let inspect = (value: Reducer_T.value) => { - Js.log(value->IEV.toString) - value->Ok - } - - let inspectLabel = (value: Reducer_T.value, label: string) => { - Js.log(`${label}: ${value->IEV.toString}`) - value->Ok - } - - // let doSetTypeAliasBindings = ( - // bindings: nameSpace, - // symbol: string, - // value: internalExpressionValue, - // ) => Bindings.setTypeAlias(bindings, symbol, value)->IEvBindings->Ok - - // let doSetTypeOfBindings = (bindings: nameSpace, symbol: string, value: internalExpressionValue) => - // Bindings.setTypeOf(bindings, symbol, value)->IEvBindings->Ok - - // let doExportBindings = (bindings: nameSpace) => bindings->Bindings.toExpressionValue->Ok - - // let doIdentity = (value: Reducer_T.value) => value->Ok - - // let doDumpBindings = (continuation: Reducer_T.nameSpace, value: Reducer_T.value) => { - // // let _ = Continuation.inspect(continuation, "doDumpBindings") - // accessors.states.continuation = continuation->Bindings.set("__result__", value) - // value->Ok - // } - - switch call { - // | ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex) - // | ("$_atIndex_$", [IEvBindings(dict), IEvString(sIndex)]) => moduleAtIndex(dict, sIndex) - // | ("$_atIndex_$", [IEvRecord(dict), IEvString(sIndex)]) => recordAtIndex(dict, sIndex) - // | ("$_constructArray_$", args) => IEvArray(args)->Ok - // | ("$_constructRecord_$", [IEvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) - // | ("$_exportBindings_$", [IEvBindings(nameSpace)]) => doExportBindings(nameSpace) - // | ("$_exportBindings_$", [evValue]) => doIdentity(evValue) - // | ("$_setBindings_$", [IEvBindings(nameSpace), IEvSymbol(symbol), value]) => - // doSetBindings(nameSpace, symbol, value) - // | ("$_setTypeAliasBindings_$", [IEvBindings(nameSpace), IEvTypeIdentifier(symbol), value]) => - // doSetTypeAliasBindings(nameSpace, symbol, value) - // | ("$_setTypeOfBindings_$", [IEvBindings(nameSpace), IEvSymbol(symbol), value]) => - // doSetTypeOfBindings(nameSpace, symbol, value) - // | ("$_dumpBindings_$", [IEvBindings(nameSpace), _, evValue]) => doDumpBindings(nameSpace, evValue) - // | ("$_typeModifier_memberOf_$", [IEvTypeIdentifier(typeIdentifier), IEvArray(arr)]) => - // TypeBuilder.typeModifier_memberOf(IEvTypeIdentifier(typeIdentifier), IEvArray(arr)) - // | ("$_typeModifier_memberOf_$", [IEvType(typeRecord), IEvArray(arr)]) => - // TypeBuilder.typeModifier_memberOf_update(typeRecord, IEvArray(arr)) - // | ("$_typeModifier_min_$", [IEvTypeIdentifier(typeIdentifier), value]) => - // TypeBuilder.typeModifier_min(IEvTypeIdentifier(typeIdentifier), value) - // | ("$_typeModifier_min_$", [IEvType(typeRecord), value]) => - // TypeBuilder.typeModifier_min_update(typeRecord, value) - // | ("$_typeModifier_max_$", [IEvTypeIdentifier(typeIdentifier), value]) => - // TypeBuilder.typeModifier_max(IEvTypeIdentifier(typeIdentifier), value) - // | ("$_typeModifier_max_$", [IEvType(typeRecord), value]) => - // TypeBuilder.typeModifier_max_update(typeRecord, value) - // | ("$_typeModifier_opaque_$", [IEvType(typeRecord)]) => - // TypeBuilder.typeModifier_opaque_update(typeRecord) - // | ("$_typeOr_$", [IEvArray(arr)]) => TypeBuilder.typeOr(IEvArray(arr)) - // | ("$_typeFunction_$", [IEvArray(arr)]) => TypeBuilder.typeFunction(arr) - // | ("$_typeTuple_$", [IEvArray(elems)]) => TypeBuilder.typeTuple(elems) - // | ("$_typeArray_$", [elem]) => TypeBuilder.typeArray(elem) - // | ("$_typeRecord_$", [IEvRecord(propertyMap)]) => TypeBuilder.typeRecord(propertyMap) - // | ("concat", [IEvArray(aValueArray), IEvArray(bValueArray)]) => - // doAddArray(aValueArray, bValueArray) - // | ("concat", [IEvString(aValueString), IEvString(bValueString)]) => - // doAddString(aValueString, bValueString) - | ("inspect", [value, IEvString(label)]) => inspectLabel(value, label) - | ("inspect", [value]) => inspect(value) - | (_, [IEvBool(_)]) - | (_, [IEvNumber(_)]) - | (_, [IEvString(_)]) - | (_, [IEvBool(_), IEvBool(_)]) - | (_, [IEvNumber(_), IEvNumber(_)]) - | (_, [IEvString(_), IEvString(_)]) => - callMathJs(call) - | call => - Error( - REFunctionNotFound(call->IEV.functionCallToCallSignature->IEV.functionCallSignatureToString), - ) // Report full type signature as error - } -} -/* - Reducer uses Result monad while reducing expressions -*/ -let dispatch = ( - call: IEV.functionCall, - env: Reducer_T.environment, - reducer: Reducer_T.reducerFn, -): Reducer_T.value => - try { - let (fn, args) = call - - // There is a bug that prevents string match in patterns - // So we have to recreate a copy of the string - switch ExternalLibrary.dispatch((Js.String.make(fn), args), env, reducer, callInternal) { - | Ok(v) => v - | Error(e) => raise(ErrorException(e)) - } - } catch { - | exn => Reducer_ErrorValue.fromException(exn)->Reducer_ErrorValue.toException - } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res index 1136990b..1bcdc030 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res @@ -13,47 +13,51 @@ let rec evaluate: T.reducerFn = (expression, context): (T.value, T.context) => { switch expression { | T.EBlock(statements) => { let innerContext = {...context, bindings: context.bindings->Bindings.extend} - let (value, _) = statements->Belt.Array.reduce( - (T.IEvVoid, innerContext), - ((_, currentContext), statement) => statement->evaluate(currentContext) - ) - (value, context) // inner context can be dropped + let (value, _) = + statements->Belt.Array.reduce((T.IEvVoid, innerContext), ((_, currentContext), statement) => + statement->evaluate(currentContext) + ) + (value, context) } | T.EProgram(statements) => { // Js.log(`bindings: ${context.bindings->Bindings.locals->Reducer_Namespace.toString}`) - let (value, finalContext) = statements->Belt.Array.reduce( - (T.IEvVoid, context), - ((_, currentContext), statement) => statement->evaluate(currentContext)) + let (value, finalContext) = + statements->Belt.Array.reduce((T.IEvVoid, context), ((_, currentContext), statement) => + statement->evaluate(currentContext) + ) // Js.log(`bindings after: ${finalContext.bindings->Bindings.locals->Reducer_Namespace.toString}`) (value, finalContext) } | T.EArray(elements) => { - let value = elements->Belt.Array.map(element => { - let (value, _) = evaluate(element, context) - value - })->T.IEvArray - (value, context) - } + let value = + elements + ->Belt.Array.map(element => { + let (value, _) = evaluate(element, context) + value + }) + ->T.IEvArray + (value, context) + } | T.ERecord(pairs) => { - let value = - pairs - ->Belt.Array.map(((eKey, eValue)) => { - let (key, _) = eKey->evaluate(context) - let keyString = switch key { - | IEvString(s) => s - | _ => REOther("Record keys must be strings")->Reducer_ErrorValue.ErrorException->raise - } - let (value, _) = eValue->evaluate(context) - (keyString, value) - }) - ->Belt.Map.String.fromArray - ->T.IEvRecord - (value, context) - } + let value = + pairs + ->Belt.Array.map(((eKey, eValue)) => { + let (key, _) = eKey->evaluate(context) + let keyString = switch key { + | IEvString(s) => s + | _ => REOther("Record keys must be strings")->Reducer_ErrorValue.ErrorException->raise + } + let (value, _) = eValue->evaluate(context) + (keyString, value) + }) + ->Belt.Map.String.fromArray + ->T.IEvRecord + (value, context) + } | T.EAssign(left, right) => { let (result, _) = right->evaluate(context) @@ -62,7 +66,7 @@ let rec evaluate: T.reducerFn = (expression, context): (T.value, T.context) => { { ...context, bindings: context.bindings->Bindings.set(left, result), - } + }, ) } @@ -82,8 +86,10 @@ let rec evaluate: T.reducerFn = (expression, context): (T.value, T.context) => { } } - | T.ELambda(parameters, body) => - (Lambda.makeLambda(parameters, context.bindings, body)->T.IEvLambda, context) + | T.ELambda(parameters, body) => ( + Lambda.makeLambda(parameters, context.bindings, body)->T.IEvLambda, + context, + ) | T.ECall(fn, args) => { let (lambda, _) = fn->evaluate(context) @@ -92,8 +98,14 @@ let rec evaluate: T.reducerFn = (expression, context): (T.value, T.context) => { argValue }) switch lambda { - | T.IEvLambda(lambda) => (Lambda.doLambdaCall(lambda, argValues, context.environment, evaluate), context) - | _ => RENotAFunction(lambda->ReducerInterface_InternalExpressionValue.toString)->Reducer_ErrorValue.ErrorException->raise + | T.IEvLambda(lambda) => ( + Lambda.doLambdaCall(lambda, argValues, context.environment, evaluate), + context, + ) + | _ => + RENotAFunction(lambda->ReducerInterface_InternalExpressionValue.toString) + ->Reducer_ErrorValue.ErrorException + ->raise } } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res index f6cc4ffa..bb4e80c5 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res @@ -34,13 +34,18 @@ let makeLambda = ( } let localBindings = bindings->Reducer_Bindings.extend - let localBindingsWithParameters = parameters->Belt.Array.reduceWithIndex( - localBindings, - (currentBindings, parameter, index) => { + let localBindingsWithParameters = parameters->Belt.Array.reduceWithIndex(localBindings, ( + currentBindings, + parameter, + index, + ) => { currentBindings->Reducer_Bindings.set(parameter, arguments[index]) }) - let (value, _) = reducer(body, {bindings: localBindingsWithParameters, environment: environment}) + let (value, _) = reducer( + body, + {bindings: localBindingsWithParameters, environment: environment}, + ) value } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res index 1aa64246..365d0836 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res @@ -7,17 +7,20 @@ module InternalExpressionValue = ReducerInterface_InternalExpressionValue type t = Reducer_T.expression let commaJoin = values => values->Reducer_Extra_Array.intersperse(", ")->Js.String.concatMany("") -let semicolonJoin = values => values->Reducer_Extra_Array.intersperse("; ")->Js.String.concatMany("") +let semicolonJoin = values => + values->Reducer_Extra_Array.intersperse("; ")->Js.String.concatMany("") /* Converts the expression to String */ let rec toString = (expression: t) => switch expression { - | EBlock(statements) => `{${Js.Array2.map(statements, aValue => toString(aValue))->semicolonJoin}}` + | EBlock(statements) => + `{${Js.Array2.map(statements, aValue => toString(aValue))->semicolonJoin}}` | EProgram(statements) => Js.Array2.map(statements, aValue => toString(aValue))->semicolonJoin | EArray(aList) => `[${Js.Array2.map(aList, aValue => toString(aValue))->commaJoin}]` - | ERecord(map) => `{${map->Belt.Array.map(((key, value)) => `${key->toString}: ${value->toString}`)->commaJoin}}` + | ERecord(map) => + `{${map->Belt.Array.map(((key, value)) => `${key->toString}: ${value->toString}`)->commaJoin}}` | ESymbol(name) => name | ETernary(predicate, trueCase, falseCase) => `${predicate->toString} ? (${trueCase->toString}) : (${falseCase->toString})` diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res index 638bdbcd..5793fe07 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res @@ -1,9 +1,12 @@ +/* + Namespace is a flat mapping of names to Squiggle values. + The full context of variables accessible to Squiggle is called "bindings"; see Reducer_Bindings module for details on it. +*/ type t = Reducer_T.namespace let make = (): t => Belt.Map.String.empty -let get = (namespace: t, id: string): option => - namespace->Belt.Map.String.get(id) +let get = (namespace: t, id: string): option => namespace->Belt.Map.String.get(id) let set = (namespace: t, id: string, value): t => { namespace->Belt.Map.String.set(id, value) @@ -16,19 +19,18 @@ let mergeFrom = (from: t, to: t): t => { } let mergeMany = (namespaces: array): t => - Belt.Array.reduce(namespaces, make(), (acc, ns) => acc->mergeFrom(ns)) + Belt.Array.reduce(namespaces, make(), (acc, ns) => acc->mergeFrom(ns)) let toString = (namespace: t) => namespace ->Belt.Map.String.toArray - ->Belt.Array.map(((eachKey, eachValue)) => `${eachKey}: ${eachValue->ReducerInterface_InternalExpressionValue.toString}`) + ->Belt.Array.map(((eachKey, eachValue)) => + `${eachKey}: ${eachValue->ReducerInterface_InternalExpressionValue.toString}` + ) ->Js.Array2.toString -let fromArray = (a): t => - Belt.Map.String.fromArray(a) +let fromArray = (a): t => Belt.Map.String.fromArray(a) -let toMap = (namespace: t): Reducer_T.map => - namespace +let toMap = (namespace: t): Reducer_T.map => namespace -let toRecord = (namespace: t): Reducer_T.value => - namespace->toMap->IEvRecord +let toRecord = (namespace: t): Reducer_T.value => namespace->toMap->IEvRecord 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 469fcba1..3bf11162 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 @@ -11,7 +11,7 @@ zeroOMoreArgumentsBlockOrExpression = innerBlockOrExpression / lambda outerBlock = statements:array_statements finalExpression: (statementSeparator @expression)? - { if (finalExpression) statements.push(finalExpression) + { if (finalExpression) statements.push(finalExpression) return h.nodeProgram(statements) } / finalExpression: expression { return h.nodeProgram([finalExpression]) } @@ -23,7 +23,7 @@ innerBlockOrExpression quotedInnerBlock = '{' _nl statements:array_statements finalExpression: (statementSeparator @expression) _nl '}' - { if (finalExpression) statements.push(finalExpression) + { if (finalExpression) statements.push(finalExpression) return h.nodeBlock(statements) } / '{' _nl finalExpression: expression _nl '}' { return h.nodeBlock([finalExpression]) } 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 4dd66205..f24fd819 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts @@ -1,8 +1,8 @@ import { LocationRange } from "peggy"; export const toFunction = { + "+": "add", "-": "subtract", - "->": "pipe", "!=": "unequal", ".-": "dotSubtract", ".*": "dotMultiply", @@ -13,7 +13,6 @@ export const toFunction = { "/": "divide", "&&": "and", "^": "pow", // or xor - "+": "add", "<": "smaller", "<=": "smallerEq", "==": "equal", diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res index 4ce11eea..0922c8a7 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res @@ -9,12 +9,11 @@ let dispatch = ( reducer: Reducer_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, reducer), + 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, reducer), ])->E.O2.defaultFn(() => chain(call, environment, reducer)) } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index 27b0a546..dd0d6e51 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -2,7 +2,6 @@ // (value methods should be moved to Reducer_Value.res) module ErrorValue = Reducer_ErrorValue -module Extra_Array = Reducer_Extra_Array type environment = GenericDist.env module T = Reducer_T diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res index dc74135a..18957474 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -10,49 +10,37 @@ let internalStdLib: Reducer_T.namespace = { "$_atIndex_$", Reducer_Expression_Lambda.makeFFILambda((inputs, _, _) => { switch inputs { - | [IEvArray(aValueArray), IEvNumber(fIndex)] => switch Belt.Array.get( - aValueArray, - Belt.Int.fromFloat(fIndex), - ) { + | [IEvArray(aValueArray), IEvNumber(fIndex)] => { + let index = Belt.Int.fromFloat(fIndex) // TODO - fail on non-integer indices? + + switch Belt.Array.get(aValueArray, index) { | Some(value) => value | None => - REArrayIndexNotFound("Array index not found", Belt.Int.fromFloat(fIndex)) + REArrayIndexNotFound("Array index not found", index) ->ErrorException ->raise } - | [IEvRecord(dict), IEvString(sIndex)] => switch Belt.Map.String.get(dict, sIndex) { + } + | [IEvRecord(dict), IEvString(sIndex)] => + switch Belt.Map.String.get(dict, sIndex) { | Some(value) => value - | None => RERecordPropertyNotFound("Record property not found", sIndex)->ErrorException->raise + | None => + RERecordPropertyNotFound("Record property not found", sIndex)->ErrorException->raise } | _ => REOther("Trying to access key on wrong value")->ErrorException->raise } })->Reducer_T.IEvLambda, ) - let res = FunctionRegistry_Library.nonRegistryLambdas->Belt.Array.reduce( - res, - (cur, (name, lambda)) => { - cur->Reducer_Namespace.set(name, lambda->Reducer_T.IEvLambda) - } - ) - - // TODO: - // () => ReducerInterface_GenericDistribution.dispatch(call, environment), - // () => ReducerInterface_Date.dispatch(call, environment), - // () => ReducerInterface_Duration.dispatch(call, environment), - // () => ReducerInterface_Number.dispatch(call, environment), + let res = FunctionRegistry_Library.nonRegistryLambdas->Belt.Array.reduce(res, ( + cur, + (name, lambda), + ) => { + cur->Reducer_Namespace.set(name, lambda->Reducer_T.IEvLambda) + }) // Reducer_Dispatch_BuiltIn: - // [x] | ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex) - // [ ] | ("$_atIndex_$", [IEvBindings(dict), IEvString(sIndex)]) => moduleAtIndex(dict, sIndex) - // [x] | ("$_atIndex_$", [IEvRecord(dict), IEvString(sIndex)]) => recordAtIndex(dict, sIndex) - // [x] | ("$_constructArray_$", args) => IEvArray(args)->Ok - // [x] | ("$_constructRecord_$", [IEvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) - // [ ] | ("concat", [IEvArray(aValueArray), IEvArray(bValueArray)]) => doAddArray(aValueArray, bValueArray) - // [ ] | ("concat", [IEvString(aValueString), IEvString(bValueString)]) => doAddString(aValueString, bValueString) - // [ ] | ("inspect", [value, IEvString(label)]) => inspectLabel(value, label) - // [ ] | ("inspect", [value]) => inspect(value) // [ ] | (_, [IEvBool(_)]) // [ ] | (_, [IEvNumber(_)]) // [ ] | (_, [IEvString(_)]) @@ -60,19 +48,20 @@ let internalStdLib: Reducer_T.namespace = { // [ ] | (_, [IEvNumber(_), IEvNumber(_)]) // [ ] | (_, [IEvString(_), IEvString(_)]) => callMathJs(call) - let res = FunctionRegistry_Library.registry - ->FunctionRegistry_Core.Registry.allNames - ->Belt.Array.reduce(res, (cur, name) => { - cur->Reducer_Namespace.set( - name, - Reducer_Expression_Lambda.makeFFILambda((arguments, environment, reducer) => { - switch FunctionRegistry_Library.call(name, arguments, environment, reducer) { - | Ok(value) => value - | Error(error) => error->Reducer_ErrorValue.ErrorException->raise - } - })->Reducer_T.IEvLambda, - ) - }) + let res = + FunctionRegistry_Library.registry + ->FunctionRegistry_Core.Registry.allNames + ->Belt.Array.reduce(res, (cur, name) => { + cur->Reducer_Namespace.set( + name, + Reducer_Expression_Lambda.makeFFILambda((arguments, environment, reducer) => { + switch FunctionRegistry_Library.call(name, arguments, environment, reducer) { + | Ok(value) => value + | Error(error) => error->Reducer_ErrorValue.ErrorException->raise + } + })->Reducer_T.IEvLambda, + ) + }) res } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index 12933e21..01996b32 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -166,23 +166,25 @@ let linkDependencies = (project: t, sourceId: string): Reducer_T.namespace => { Belt.Array.concatMany([ [project->getStdLib], pastChain->Belt.Array.map(project->getBindings), - pastChain->Belt.Array.map( - id => Reducer_Namespace.fromArray([ - ("__result__", - switch project->getResult(id) { + pastChain->Belt.Array.map(id => + Reducer_Namespace.fromArray([ + ( + "__result__", + switch project->getResult(id) { | Ok(result) => result | Error(error) => error->Reducer_ErrorValue.ErrorException->raise - }) + }, + ), ]) ), - ]) + ]), ) let includesAsVariables = project->getIncludesAsVariables(sourceId) Belt.Array.reduce(includesAsVariables, namespace, (acc, (variable, includeFile)) => acc->Reducer_Namespace.set( variable, - project->getBindings(includeFile)->Reducer_Namespace.toRecord + project->getBindings(includeFile)->Reducer_Namespace.toRecord, ) ) } @@ -190,7 +192,7 @@ let linkDependencies = (project: t, sourceId: string): Reducer_T.namespace => { let doLinkAndRun = (project: t, sourceId: string): unit => { let context = Reducer_Context.createContext( project->linkDependencies(sourceId), - project->getEnvironment + project->getEnvironment, ) let newItem = project->getItem(sourceId)->ProjectItem.run(context) // Js.log("after run " ++ newItem.continuation->Reducer_Bindings.toString) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res index e51f7d4b..93d434a3 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res @@ -172,10 +172,14 @@ let failRun = (this: t, e: Reducer_ErrorValue.errorValue): t => let doRun = (this: t, context: Reducer_T.context): t => switch this->getExpression { - | Some(expressionResult) => switch expressionResult { - | Ok(expression) => try { + | Some(expressionResult) => + switch expressionResult { + | Ok(expression) => + try { let (result, contextAfterEvaluation) = Reducer_Expression.evaluate(expression, context) - this->setResult(result->Ok)->setContinuation(contextAfterEvaluation.bindings->Reducer_Bindings.locals) + this + ->setResult(result->Ok) + ->setContinuation(contextAfterEvaluation.bindings->Reducer_Bindings.locals) } catch { | Reducer_ErrorValue.ErrorException(e) => this->failRun(e) | _ => this->failRun(RETodo("unhandled rescript exception")) diff --git a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res index 4682fa01..631b05fb 100644 --- a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res +++ b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res @@ -12,4 +12,6 @@ let availableNumbers: array<(string, float)> = [ ] let make = (): Reducer_Namespace.t => - availableNumbers->E.A2.fmap(((name, v)) => (name, Reducer_T.IEvNumber(v)))->Reducer_Namespace.fromArray + availableNumbers + ->E.A2.fmap(((name, v)) => (name, Reducer_T.IEvNumber(v))) + ->Reducer_Namespace.fromArray