From 417f0060b6ccb0d817d32210a71f765b52a13dd4 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 22 Apr 2022 15:43:37 +0200 Subject: [PATCH 001/146] inspect and inspect with label (tested) --- .../Reducer/Reducer_debugging_test.res | 12 ++++++++++++ .../Reducer_Dispatch_BuiltIn.res | 17 +++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res new file mode 100644 index 00000000..588dd842 --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res @@ -0,0 +1,12 @@ +open Jest +open Reducer_TestHelpers + +/* + You can wrap around any expression with inspect(expr) to log the value of that expression. + This is useful for debugging. inspect(expr) returns the value of expr, but also prints it out. + There is a second version of inspect that takes a label, which will print out the label and the value. +*/ +describe("Debugging", () => { + testEvalToBe("inspect(1)", "Ok(1)") + testEvalToBe("inspect(1, \"one\")", "Ok(1)") +}) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 21c91dc2..fc14b5d6 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -43,16 +43,25 @@ let callInternal = (call: functionCall): result<'b, errorValue> => { | None => RERecordPropertyNotFound("Record property not found", sIndex)->Error } + let inspect = (value: expressionValue) => { + Js.log(`${value->toString}`) + value->Ok + } + + let inspectLabel = (value: expressionValue, label: string) => { + Js.log(`${label}: ${value->toString}`) + value->Ok + } + switch call { - // | ("$constructRecord", pairArray) - // | ("$atIndex", [EvArray(anArray), EvNumber(fIndex)]) => arrayAtIndex(anArray, fIndex) - // | ("$atIndex", [EvRecord(aRecord), EvString(sIndex)]) => recordAtIndex(aRecord, sIndex) - | ("$constructRecord", [EvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) | ("$atIndex", [EvArray(aValueArray), EvArray([EvNumber(fIndex)])]) => arrayAtIndex(aValueArray, fIndex) | ("$atIndex", [EvRecord(dict), EvArray([EvString(sIndex)])]) => recordAtIndex(dict, sIndex) | ("$atIndex", [obj, index]) => (toStringWithType(obj) ++ "??~~~~" ++ toStringWithType(index))->EvString->Ok + | ("$constructRecord", [EvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) + | ("inspect", [value, EvString(label)]) => inspectLabel(value, label) + | ("inspect", [value]) => inspect(value) | call => callMathJs(call) } } From 9ce5ed53d28c7602ec71b662a47f7bc1b1fbba99 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 22 Apr 2022 16:18:00 +0200 Subject: [PATCH 002/146] inspectPerformance (tested) --- .../__tests__/Reducer/Reducer_debugging_test.res | 5 +++++ .../Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res index 588dd842..0ce1a90d 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res @@ -4,9 +4,14 @@ open Reducer_TestHelpers /* You can wrap around any expression with inspect(expr) to log the value of that expression. This is useful for debugging. inspect(expr) returns the value of expr, but also prints it out. + There is a second version of inspect that takes a label, which will print out the label and the value. + + inpsectPerformace(expr, label) will print out the value of expr, the label, and the time it took to evaluate expr. */ describe("Debugging", () => { testEvalToBe("inspect(1)", "Ok(1)") testEvalToBe("inspect(1, \"one\")", "Ok(1)") + testEvalToBe("inspect(1, \"one\")", "Ok(1)") + testEvalToBe("inspectPerformance(1, \"one\")", "Ok(1)") }) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index fc14b5d6..0c1f6c04 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -53,6 +53,15 @@ let callInternal = (call: functionCall): result<'b, errorValue> => { value->Ok } + let inspectPerformance = (value: expressionValue, label: string) => { + let _ = %raw("{performance} = require('perf_hooks')") + let start = %raw(`performance.now()`) + let finish = %raw(`performance.now()`) + let performance = finish - start + Js.log(`${label}: ${value->toString} performance: ${Js.String.make(performance)}ms`) + value->Ok + } + switch call { | ("$atIndex", [EvArray(aValueArray), EvArray([EvNumber(fIndex)])]) => arrayAtIndex(aValueArray, fIndex) @@ -62,6 +71,7 @@ let callInternal = (call: functionCall): result<'b, errorValue> => { | ("$constructRecord", [EvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) | ("inspect", [value, EvString(label)]) => inspectLabel(value, label) | ("inspect", [value]) => inspect(value) + | ("inspectPerformance", [value, EvString(label)]) => inspectPerformance(value, label) | call => callMathJs(call) } } From 99906446c5d5a8d1ab7c80e74e09c1f5c758a9d8 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Sat, 23 Apr 2022 15:40:04 +0200 Subject: [PATCH 003/146] resi declaration consistency --- packages/squiggle-lang/src/rescript/Reducer/Reducer.res | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res index d2e4858f..63e1f3a7 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res @@ -5,8 +5,8 @@ module Extra = Reducer_Extra module Js = Reducer_Js module MathJs = Reducer_MathJs -type expressionValue = Reducer_Expression.expressionValue -type externalBindings = Expression.externalBindings +type expressionValue = ReducerInterface_ExpressionValue.expressionValue +type externalBindings = ReducerInterface_ExpressionValue.externalBindings let evaluate = Expression.eval let evaluateUsingExternalBindings = Expression.evalUsingExternalBindings let evaluatePartialUsingExternalBindings = Expression.evalPartialUsingExternalBindings From a915e6804951327258867835e03893980fb4196b Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Sat, 23 Apr 2022 17:55:34 +0200 Subject: [PATCH 004/146] MathJs functionAssingmentNode parsed, comments passed (tested) Just found out that comments were already done --- .../Reducer_MathJsParse_test.res | 19 ++++++++++--------- .../Reducer_MathJs/Reducer_MathJs_Parse.res | 11 +++++++++-- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res index 6282c14d..988d5a88 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res @@ -18,6 +18,12 @@ module MySkip = { Skip.test(desc, () => expectParseToBe(expr, answer)) } +module MyOnly = { + let testParse = (expr, answer) => Only.test(expr, () => expectParseToBe(expr, answer)) + let testDescriptionParse = (desc, expr, answer) => + Only.test(desc, () => expectParseToBe(expr, answer)) +} + describe("MathJs parse", () => { describe("literals operators paranthesis", () => { testParse("1", "1") @@ -40,15 +46,15 @@ describe("MathJs parse", () => { }) describe("functions", () => { - MySkip.testParse("identity(x) = x", "???") - MySkip.testParse("identity(x)", "???") + testParse("identity(x) = x", "identity = (x) => x") + testParse("identity(x)", "identity(x)") }) describe("arrays", () => { testDescriptionParse("empty", "[]", "[]") testDescriptionParse("define", "[0, 1, 2]", "[0, 1, 2]") testDescriptionParse("define with strings", "['hello', 'world']", "['hello', 'world']") - MySkip.testParse("range(0, 4)", "range(0, 4)") + testParse("range(0, 4)", "range(0, 4)") testDescriptionParse("index", "([0,1,2])[1]", "([0, 1, 2])[1]") }) @@ -58,11 +64,6 @@ describe("MathJs parse", () => { }) describe("comments", () => { - MySkip.testDescriptionParse("define", "# This is a comment", "???") - }) - - describe("if statement", () => { - // TODO Tertiary operator instead - MySkip.testDescriptionParse("define", "if (true) { 1 } else { 0 }", "???") + testDescriptionParse("define", "1 # This is a comment", "1") }) }) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res index e3e2955c..e2acbe55 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res @@ -11,11 +11,10 @@ type block = {"node": node} type blockNode = {...node, "blocks": array} //conditionalNode type constantNode = {...node, "value": unit} -//functionAssignmentNode +type functionAssignmentNode = {...node, "name": string, "params": array, "expr": node} type indexNode = {...node, "dimensions": array} type objectNode = {...node, "properties": Js.Dict.t} type accessorNode = {...node, "object": node, "index": indexNode, "name": string} - type parenthesisNode = {...node, "content": node} //rangeNode //relationalNode @@ -33,6 +32,7 @@ external castAssignmentNodeWAccessor: node => assignmentNodeWAccessor = "%identi external castAssignmentNodeWIndex: node => assignmentNodeWIndex = "%identity" external castBlockNode: node => blockNode = "%identity" external castConstantNode: node => constantNode = "%identity" +external castFunctionAssignmentNode: node => functionAssignmentNode ="%identity" external castFunctionNode: node => functionNode = "%identity" external castIndexNode: node => indexNode = "%identity" external castObjectNode: node => objectNode = "%identity" @@ -59,6 +59,7 @@ type mathJsNode = | MjAssignmentNode(assignmentNode) | MjBlockNode(blockNode) | MjConstantNode(constantNode) + | MjFunctionAssignmentNode(functionAssignmentNode) | MjFunctionNode(functionNode) | MjIndexNode(indexNode) | MjObjectNode(objectNode) @@ -82,6 +83,7 @@ let castNodeType = (node: node) => { | "AssignmentNode" => node->decideAssignmentNode | "BlockNode" => node->castBlockNode->MjBlockNode->Ok | "ConstantNode" => node->castConstantNode->MjConstantNode->Ok + | "FunctionAssignmentNode" => node->castFunctionAssignmentNode->MjFunctionAssignmentNode->Ok | "FunctionNode" => node->castFunctionNode->MjFunctionNode->Ok | "IndexNode" => node->castIndexNode->MjIndexNode->Ok | "ObjectNode" => node->castObjectNode->MjObjectNode->Ok @@ -118,6 +120,10 @@ let rec toString = (mathJsNode: mathJsNode): string => { ->Extra.Array.interperse(", ") ->Js.String.concatMany("") + let toStringFunctionAssignmentNode = (faNode: functionAssignmentNode): string => { + let paramNames = Js.Array2.toString(faNode["params"]) + `${faNode["name"]} = (${paramNames}) => ${toStringMathJsNode(faNode["expr"])}` + } let toStringFunctionNode = (fnode: functionNode): string => `${fnode->nameOfFunctionNode}(${fnode["args"]->toStringNodeArray})` @@ -152,6 +158,7 @@ let rec toString = (mathJsNode: mathJsNode): string => { `${aNode["object"]->toStringSymbolNode} = ${aNode["value"]->toStringMathJsNode}` | MjBlockNode(bNode) => `{${bNode["blocks"]->toStringBlocks}}` | MjConstantNode(cNode) => cNode["value"]->toStringValue + | MjFunctionAssignmentNode(faNode) => faNode->toStringFunctionAssignmentNode | MjFunctionNode(fNode) => fNode->toStringFunctionNode | MjIndexNode(iNode) => iNode->toStringIndexNode | MjObjectNode(oNode) => oNode->toStringObjectNode From 88b6d49ad3b910e12738f5db5d8a32a43165e12d Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Sat, 23 Apr 2022 21:13:43 +0200 Subject: [PATCH 005/146] function definition parse (tested) --- .../Reducer/Reducer_functionAssignment_test.res | 12 ++++++++++++ .../Reducer_Dispatch_BuiltInMacros.res | 1 + .../Reducer_Expression/Reducer_Expression.res | 3 +++ .../Reducer_Expression/Reducer_Expression_T.res | 3 ++- .../Reducer_MathJs/Reducer_MathJs_ToExpression.res | 14 ++++++++++++++ 5 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res new file mode 100644 index 00000000..ebc0896f --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res @@ -0,0 +1,12 @@ +open Jest +open Reducer_TestHelpers + +describe("Parse function assignment", () => { + testParseToBe("f(x)=x", "Ok((:$let :f (:$lambda (x) :x)))") + testParseToBe("f(x)=2*x", "Ok((:$let :f (:$lambda (x) (:multiply 2 :x))))") + //MathJs does not allow blocks in function definitions +}) + +Skip.describe("Evaluate function assignment", () => { + testParseToBe("f(x)=x; f(1)", "Ok(1)") +}) \ No newline at end of file diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index d1219f79..7da85124 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -33,6 +33,7 @@ let dispatchMacroCall = ( } | ExpressionT.EValue(_) => expression->Ok | ExpressionT.EBindings(_) => expression->Ok + | ExpressionT.EParameters(_) => expression->Ok | ExpressionT.EList(list) => { let racc = list->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) => racc->Result.flatMap(acc => { 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 68881496..30f8d96c 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 @@ -16,6 +16,7 @@ type t = expression let rec toString = expression => switch expression { | T.EBindings(_) => "$$bound" + | T.EParameters(params) => `(${Js.Array2.toString(params->Belt.List.toArray)})` | T.EList(aList) => `(${Belt.List.map(aList, aValue => toString(aValue)) ->Extra.List.interperse(" ") @@ -72,6 +73,7 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result expression->Ok | T.EBindings(_value) => expression->Ok + | T.EParameters(_value) => expression->Ok | T.EList(list) => { let racc: result, 'e> = list->Belt.List.reduceReverse(Ok(list{}), ( racc, @@ -108,6 +110,7 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): resultResult.flatMap(acc => acc->reduceValueList) } | EBindings(_bindings) => RETodo("Error: Bindings cannot be reduced to values")->Error + | EParameters(_parameters) => RETodo("Error: Lambda Parameters cannot be reduced to values")->Error } let rExpandedExpression: result = expression->seekMacros(bindings) 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 fe938316..5f141195 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 @@ -11,5 +11,6 @@ open ReducerInterface.ExpressionValue type rec expression = | EList(list) // A list to map-reduce | EValue(expressionValue) // Irreducible built-in value. Reducer should not know the internals. External libraries are responsible - | EBindings(bindings) // let/def kind of statements return bindings + | EBindings(bindings) // $let kind of statements return bindings; for internal use only + | EParameters(list) // for $defun; for internal use only and bindings = Belt.Map.String.t diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res index a8b7b39a..2d0bcdd6 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res @@ -99,6 +99,19 @@ let rec fromNode = (mathJsNode: Parse.node): result => }) } + let caseFunctionAssignmentNode = faNode => { + let symbol = faNode["name"]->toEvSymbolValue + let rValueExpression = fromNode(faNode["expr"]) + + rValueExpression->Result.flatMap(valueExpression => { + let lispParams = faNode["params"]->Belt.List.fromArray->ExpressionT.EParameters + let rLambda = passToFunction("$lambda", list{lispParams, valueExpression}->Ok) + rLambda -> Result.flatMap( lambda => { + passToFunction("$let", list{symbol, lambda}->Ok) + }) + }) + } + let caseArrayNode = aNode => { aNode["items"]->Belt.List.fromArray->fromNodeList->Result.map(list => ExpressionT.EList(list)) } @@ -115,6 +128,7 @@ let rec fromNode = (mathJsNode: Parse.node): result => | MjBlockNode(bNode) => bNode["blocks"]->Belt.Array.map(toTagOrNode)->caseTagOrNodes | MjConstantNode(cNode) => cNode["value"]->JavaScript.Gate.jsToEv->Result.flatMap(v => v->ExpressionT.EValue->Ok) + | MjFunctionAssignmentNode(faNode) => caseFunctionAssignmentNode(faNode) | MjFunctionNode(fNode) => fNode->caseFunctionNode | MjIndexNode(iNode) => caseIndexNode(iNode) | MjObjectNode(oNode) => caseObjectNode(oNode) From fe4e355fbef8412b3db2c5bfad4cc2da228d7159 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Sun, 24 Apr 2022 18:42:54 +0200 Subject: [PATCH 006/146] format --- .../__tests__/Reducer/Reducer_TestHelpers.res | 5 ++++- .../__tests__/Reducer/Reducer_debugging_test.res | 8 ++++---- .../Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res | 2 +- .../Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res | 6 +++--- .../Reducer_MathJs/Reducer_MathJs_ToExpression.res | 4 ++-- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res index 0790c078..581f6c8a 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res @@ -17,7 +17,10 @@ let expectEvalToBe = (expr: string, answer: string) => Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toBe(answer) let expectEvalBindingsToBe = (expr: string, bindings: Reducer.externalBindings, answer: string) => - Reducer.evaluateUsingExternalBindings(expr, bindings)->ExpressionValue.toStringResult->expect->toBe(answer) + Reducer.evaluateUsingExternalBindings(expr, bindings) + ->ExpressionValue.toStringResult + ->expect + ->toBe(answer) let expectEvalPartialBindingsToBe = ( expr: string, diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res index 0ce1a90d..3a2eea97 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res @@ -10,8 +10,8 @@ open Reducer_TestHelpers inpsectPerformace(expr, label) will print out the value of expr, the label, and the time it took to evaluate expr. */ describe("Debugging", () => { - testEvalToBe("inspect(1)", "Ok(1)") - testEvalToBe("inspect(1, \"one\")", "Ok(1)") - testEvalToBe("inspect(1, \"one\")", "Ok(1)") - testEvalToBe("inspectPerformance(1, \"one\")", "Ok(1)") + testEvalToBe("inspect(1)", "Ok(1)") + testEvalToBe("inspect(1, \"one\")", "Ok(1)") + testEvalToBe("inspect(1, \"one\")", "Ok(1)") + testEvalToBe("inspectPerformance(1, \"one\")", "Ok(1)") }) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 0c1f6c04..e107016f 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -44,7 +44,7 @@ let callInternal = (call: functionCall): result<'b, errorValue> => { } let inspect = (value: expressionValue) => { - Js.log(`${value->toString}`) + Js.log(value->toString) value->Ok } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res index e2acbe55..1f5df97d 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res @@ -32,7 +32,7 @@ external castAssignmentNodeWAccessor: node => assignmentNodeWAccessor = "%identi external castAssignmentNodeWIndex: node => assignmentNodeWIndex = "%identity" external castBlockNode: node => blockNode = "%identity" external castConstantNode: node => constantNode = "%identity" -external castFunctionAssignmentNode: node => functionAssignmentNode ="%identity" +external castFunctionAssignmentNode: node => functionAssignmentNode = "%identity" external castFunctionNode: node => functionNode = "%identity" external castIndexNode: node => indexNode = "%identity" external castObjectNode: node => objectNode = "%identity" @@ -123,7 +123,7 @@ let rec toString = (mathJsNode: mathJsNode): string => { let toStringFunctionAssignmentNode = (faNode: functionAssignmentNode): string => { let paramNames = Js.Array2.toString(faNode["params"]) `${faNode["name"]} = (${paramNames}) => ${toStringMathJsNode(faNode["expr"])}` - } + } let toStringFunctionNode = (fnode: functionNode): string => `${fnode->nameOfFunctionNode}(${fnode["args"]->toStringNodeArray})` @@ -158,7 +158,7 @@ let rec toString = (mathJsNode: mathJsNode): string => { `${aNode["object"]->toStringSymbolNode} = ${aNode["value"]->toStringMathJsNode}` | MjBlockNode(bNode) => `{${bNode["blocks"]->toStringBlocks}}` | MjConstantNode(cNode) => cNode["value"]->toStringValue - | MjFunctionAssignmentNode(faNode) => faNode->toStringFunctionAssignmentNode + | MjFunctionAssignmentNode(faNode) => faNode->toStringFunctionAssignmentNode | MjFunctionNode(fNode) => fNode->toStringFunctionNode | MjIndexNode(iNode) => iNode->toStringIndexNode | MjObjectNode(oNode) => oNode->toStringObjectNode diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res index 2d0bcdd6..45184a89 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res @@ -106,12 +106,12 @@ let rec fromNode = (mathJsNode: Parse.node): result => rValueExpression->Result.flatMap(valueExpression => { let lispParams = faNode["params"]->Belt.List.fromArray->ExpressionT.EParameters let rLambda = passToFunction("$lambda", list{lispParams, valueExpression}->Ok) - rLambda -> Result.flatMap( lambda => { + rLambda->Result.flatMap(lambda => { passToFunction("$let", list{symbol, lambda}->Ok) }) }) } - + let caseArrayNode = aNode => { aNode["items"]->Belt.List.fromArray->fromNodeList->Result.map(list => ExpressionT.EList(list)) } From 5d88fae40c80fca73b65f56eaa6dd241c3b88cb5 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 01:09:51 +0200 Subject: [PATCH 007/146] internalCode --- .../ReducerInterface/ReducerInterface_ExpressionValue.res | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res index 2cbd1ead..f81bcbe4 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res @@ -5,12 +5,16 @@ module Extra_Array = Reducer_Extra_Array module ErrorValue = Reducer_ErrorValue +@genType.opaque +type internalCode = Object + @genType type rec expressionValue = | EvArray(array) | EvBool(bool) | EvCall(string) // External function call | EvDistribution(GenericDist_Types.genericDist) + | EvLambda(array, internalCode) | EvNumber(float) | EvRecord(Js.Dict.t) | EvString(string) @@ -25,6 +29,7 @@ let rec toString = aValue => switch aValue { | EvBool(aBool) => Js.String.make(aBool) | EvCall(fName) => `:${fName}` + | EvLambda(parameters, _internalCode) => `lambda(${Js.Array2.toString(parameters)}=>internal)` | EvNumber(aNumber) => Js.String.make(aNumber) | EvString(aString) => `'${aString}'` | EvSymbol(aString) => `:${aString}` From 1f989de11c4fcfd87cbec1a96339ce870b4efb1c Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 01:53:37 +0200 Subject: [PATCH 008/146] lambda binding --- .../Reducer_Dispatch_BuiltInMacros.res | 88 +++++++++++++------ .../Reducer_Expression/Reducer_Expression.res | 3 + 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index 7da85124..a17036de 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -16,37 +16,73 @@ type reducerFn = ( ExpressionT.bindings, ) => result +let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings): result< + expression, + errorValue, +> => { + let getParameters = (bindings: ExpressionT.bindings): list => { + let eParameters = Belt.Map.String.getWithDefault(bindings, "$parameters", EParameters(list{})) + switch eParameters { + | EParameters(parameters) => parameters + | _ => list{} + } + } + + let putParameters = ( + bindings: ExpressionT.bindings, + parameters: list, + ): ExpressionT.bindings => + Belt.Map.String.set(bindings, "$parameters", ExpressionT.EParameters(parameters)) + switch expression { + | ExpressionT.EValue(EvSymbol(aSymbol)) => { + let parameters = getParameters(bindings) + switch Belt.List.has(parameters, aSymbol, (a, b) => a == b) { + | true => expression->Ok // We cannot bind the parameters with global values + | false => + switch bindings->Belt.Map.String.get(aSymbol) { + | Some(boundExpression) => boundExpression->Ok + | None => RESymbolNotFound(aSymbol)->Error + } + } + } + | ExpressionT.EValue(_) => expression->Ok + | ExpressionT.EBindings(_) => expression->Ok + | ExpressionT.EParameters(_) => expression->Ok + | ExpressionT.EList(list{ + ExpressionT.EValue(EvCall("$lambda")), + ExpressionT.EParameters(parameters), + expr, + }) => { + let oldParameters = getParameters(bindings) + let newParameters = oldParameters->Belt.List.concat(parameters) + let newBindings = putParameters(bindings, newParameters) + let rNewExpr = replaceSymbols(expr, newBindings) + rNewExpr -> Result.flatMap(newExpr => ExpressionT.EList(list{ + ExpressionT.EValue(EvCall("$lambda")), + ExpressionT.EParameters(parameters), + newExpr + })->Ok) + } + | ExpressionT.EList(list) => { + let racc = list->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) => + racc->Result.flatMap(acc => { + each + ->replaceSymbols(bindings) + ->Result.flatMap(newNode => { + acc->Belt.List.add(newNode)->Ok + }) + }) + ) + racc->Result.map(acc => acc->ExpressionT.EList) + } + } +} + let dispatchMacroCall = ( list: list, bindings: ExpressionT.bindings, reduceExpression: reducerFn, ): result => { - let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings): result< - expression, - errorValue, - > => - switch expression { - | ExpressionT.EValue(EvSymbol(aSymbol)) => - switch bindings->Belt.Map.String.get(aSymbol) { - | Some(boundExpression) => boundExpression->Ok - | None => RESymbolNotFound(aSymbol)->Error - } - | ExpressionT.EValue(_) => expression->Ok - | ExpressionT.EBindings(_) => expression->Ok - | ExpressionT.EParameters(_) => expression->Ok - | ExpressionT.EList(list) => { - let racc = list->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) => - racc->Result.flatMap(acc => { - each - ->replaceSymbols(bindings) - ->Result.flatMap(newNode => { - acc->Belt.List.add(newNode)->Ok - }) - }) - ) - racc->Result.map(acc => acc->ExpressionT.EList) - } - } let doBindStatement = (statement: expression, bindings: ExpressionT.bindings) => { switch statement { 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 30f8d96c..1153491b 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 @@ -93,6 +93,9 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result => switch expression { + // | T.EList(list{T.EValue(EvCall("$lambda")), T.EParameters(parameters), functionDefinition}) => { + // let lambda = T.ELambda(parameters, functionDefinition) + // lambda->Ok} | T.EValue(value) => value->Ok | T.EList(list) => { let racc: result, 'e> = list->Belt.List.reduceReverse(Ok(list{}), ( From e3ef08839f4d3749a6801cf1874e30068b3bf95e Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 02:37:35 +0200 Subject: [PATCH 009/146] Function definition evaluated --- .../Reducer_functionAssignment_test.res | 6 ++-- .../Reducer_Dispatch_BuiltInMacros.res | 34 ++++++++++--------- .../Reducer_Expression/Reducer_Expression.res | 21 ++++++++---- .../Reducer_Expression_T.res | 2 +- .../Reducer_MathJs_ToExpression.res | 2 +- .../ReducerInterface_ExpressionValue.res | 7 ++-- 6 files changed, 42 insertions(+), 30 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res index ebc0896f..9259dacd 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res @@ -7,6 +7,6 @@ describe("Parse function assignment", () => { //MathJs does not allow blocks in function definitions }) -Skip.describe("Evaluate function assignment", () => { - testParseToBe("f(x)=x; f(1)", "Ok(1)") -}) \ No newline at end of file +describe("Evaluate function assignment", () => { + testEvalToBe("f(x)=x; f(1)", "Ok(1)") +}) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index a17036de..0785d2a9 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -20,28 +20,29 @@ let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings expression, errorValue, > => { - let getParameters = (bindings: ExpressionT.bindings): list => { - let eParameters = Belt.Map.String.getWithDefault(bindings, "$parameters", EParameters(list{})) + let getParameters = (bindings: ExpressionT.bindings): array => { + let eParameters = Belt.Map.String.getWithDefault(bindings, "$parameters", EParameters([])) switch eParameters { | EParameters(parameters) => parameters - | _ => list{} + | _ => [] } } let putParameters = ( bindings: ExpressionT.bindings, - parameters: list, + parameters: array, ): ExpressionT.bindings => Belt.Map.String.set(bindings, "$parameters", ExpressionT.EParameters(parameters)) + switch expression { | ExpressionT.EValue(EvSymbol(aSymbol)) => { let parameters = getParameters(bindings) - switch Belt.List.has(parameters, aSymbol, (a, b) => a == b) { + switch Js.Array2.some(parameters, a => a == aSymbol) { | true => expression->Ok // We cannot bind the parameters with global values | false => - switch bindings->Belt.Map.String.get(aSymbol) { - | Some(boundExpression) => boundExpression->Ok - | None => RESymbolNotFound(aSymbol)->Error + switch bindings->Belt.Map.String.get(aSymbol) { + | Some(boundExpression) => boundExpression->Ok + | None => RESymbolNotFound(aSymbol)->Error } } } @@ -54,14 +55,16 @@ let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings expr, }) => { let oldParameters = getParameters(bindings) - let newParameters = oldParameters->Belt.List.concat(parameters) + let newParameters = oldParameters->Js.Array2.concat(parameters) let newBindings = putParameters(bindings, newParameters) let rNewExpr = replaceSymbols(expr, newBindings) - rNewExpr -> Result.flatMap(newExpr => ExpressionT.EList(list{ - ExpressionT.EValue(EvCall("$lambda")), - ExpressionT.EParameters(parameters), - newExpr - })->Ok) + rNewExpr->Result.flatMap(newExpr => + ExpressionT.EList(list{ + ExpressionT.EValue(EvCall("$lambda")), + ExpressionT.EParameters(parameters), + newExpr, + })->Ok + ) } | ExpressionT.EList(list) => { let racc = list->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) => @@ -77,13 +80,12 @@ let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings } } } - + let dispatchMacroCall = ( list: list, bindings: ExpressionT.bindings, reduceExpression: reducerFn, ): result => { - let doBindStatement = (statement: expression, bindings: ExpressionT.bindings) => { switch statement { | ExpressionT.EList(list{ 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 1153491b..7923db48 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 @@ -8,15 +8,19 @@ open Reducer_ErrorValue type expression = T.expression type expressionValue = ExpressionValue.expressionValue +type internalCode = ExpressionValue.internalCode type t = expression +external castExpressionToInternalCode: expression => internalCode = "%identity" +external castInternalCodeToInternalCode: internalCode => expression = "%identity" + /* Shows the expression as text of expression */ let rec toString = expression => switch expression { | T.EBindings(_) => "$$bound" - | T.EParameters(params) => `(${Js.Array2.toString(params->Belt.List.toArray)})` + | T.EParameters(params) => `(${Js.Array2.toString(params)})` | T.EList(aList) => `(${Belt.List.map(aList, aValue => toString(aValue)) ->Extra.List.interperse(" ") @@ -93,9 +97,11 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result => switch expression { - // | T.EList(list{T.EValue(EvCall("$lambda")), T.EParameters(parameters), functionDefinition}) => { - // let lambda = T.ELambda(parameters, functionDefinition) - // lambda->Ok} + | T.EList(list{ + T.EValue(EvCall("$lambda")), + T.EParameters(parameters), + functionDefinition, + }) => EvLambda(parameters, functionDefinition->castExpressionToInternalCode)->Ok | T.EValue(value) => value->Ok | T.EList(list) => { let racc: result, 'e> = list->Belt.List.reduceReverse(Ok(list{}), ( @@ -113,7 +119,8 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): resultResult.flatMap(acc => acc->reduceValueList) } | EBindings(_bindings) => RETodo("Error: Bindings cannot be reduced to values")->Error - | EParameters(_parameters) => RETodo("Error: Lambda Parameters cannot be reduced to values")->Error + | EParameters(_parameters) => + RETodo("Error: Lambda Parameters cannot be reduced to values")->Error } let rExpandedExpression: result = expression->seekMacros(bindings) @@ -142,7 +149,9 @@ let evalPartialUsingExternalBindings_ = (codeText: string, bindings: T.bindings) Therefore all statments are assignments. */ let evalOuterWBindings_ = (codeText: string, bindings: T.bindings) => { - parseOuter(codeText)->Result.flatMap(expression => expression->evalUsingExternalBindingsExpression_(bindings)) + parseOuter(codeText)->Result.flatMap(expression => + expression->evalUsingExternalBindingsExpression_(bindings) + ) } /* 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 5f141195..c3fd822c 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 @@ -12,5 +12,5 @@ type rec expression = | EList(list) // A list to map-reduce | EValue(expressionValue) // Irreducible built-in value. Reducer should not know the internals. External libraries are responsible | EBindings(bindings) // $let kind of statements return bindings; for internal use only - | EParameters(list) // for $defun; for internal use only + | EParameters(array) // for $defun; for internal use only and bindings = Belt.Map.String.t diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res index 45184a89..bf1fcafc 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res @@ -104,7 +104,7 @@ let rec fromNode = (mathJsNode: Parse.node): result => let rValueExpression = fromNode(faNode["expr"]) rValueExpression->Result.flatMap(valueExpression => { - let lispParams = faNode["params"]->Belt.List.fromArray->ExpressionT.EParameters + let lispParams = faNode["params"]->ExpressionT.EParameters let rLambda = passToFunction("$lambda", list{lispParams, valueExpression}->Ok) rLambda->Result.flatMap(lambda => { passToFunction("$let", list{symbol, lambda}->Ok) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res index f81bcbe4..1536be74 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res @@ -56,14 +56,15 @@ and toStringRecord = aRecord => { let toStringWithType = aValue => switch aValue { + | EvArray(_) => `Array::${toString(aValue)}` | EvBool(_) => `Bool::${toString(aValue)}` | EvCall(_) => `Call::${toString(aValue)}` + | EvDistribution(_) => `Distribution::${toString(aValue)}` + | EvLambda(_parameters, _internalCode) => `Lambda::${toString(aValue)}` | EvNumber(_) => `Number::${toString(aValue)}` + | EvRecord(_) => `Record::${toString(aValue)}` | EvString(_) => `String::${toString(aValue)}` | EvSymbol(_) => `Symbol::${toString(aValue)}` - | EvArray(_) => `Array::${toString(aValue)}` - | EvRecord(_) => `Record::${toString(aValue)}` - | EvDistribution(_) => `Distribution::${toString(aValue)}` } let argsToString = (args: array): string => { From 7b080ff4c2ce9da98d8000f27c9998ef5eadeece Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 03:01:58 +0200 Subject: [PATCH 010/146] bind function calls --- .../Reducer_Dispatch_BuiltInMacros.res | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index 0785d2a9..a9432757 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -34,17 +34,24 @@ let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings ): ExpressionT.bindings => Belt.Map.String.set(bindings, "$parameters", ExpressionT.EParameters(parameters)) - switch expression { - | ExpressionT.EValue(EvSymbol(aSymbol)) => { - let parameters = getParameters(bindings) - switch Js.Array2.some(parameters, a => a == aSymbol) { - | true => expression->Ok // We cannot bind the parameters with global values + let answerBindingIfNotParameter = (aSymbol, defaultExpression, parameters, bindings) => + switch Js.Array2.some(parameters, a => a == aSymbol) { + | true => defaultExpression->Ok // We cannot bind the parameters with global values | false => switch bindings->Belt.Map.String.get(aSymbol) { | Some(boundExpression) => boundExpression->Ok | None => RESymbolNotFound(aSymbol)->Error } } + + switch expression { + | ExpressionT.EValue(EvSymbol(aSymbol)) => { + let parameters = getParameters(bindings) + answerBindingIfNotParameter(aSymbol, expression, parameters, bindings) + } + | ExpressionT.EValue(EvCall(aSymbol)) => { + let parameters = getParameters(bindings) + answerBindingIfNotParameter(aSymbol, expression, parameters, bindings) } | ExpressionT.EValue(_) => expression->Ok | ExpressionT.EBindings(_) => expression->Ok From d214bddc82fccd01b3e991bf8588f4474e117215 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 06:30:25 +0200 Subject: [PATCH 011/146] lambda expressions bound to function call symbols --- .../Reducer_Dispatch_BuiltInMacros.res | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index a9432757..b32c430d 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -44,6 +44,16 @@ let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings } } + let answerCallBindingIfNotParameter = (aSymbol, defaultExpression, parameters, bindings) => + switch Js.Array2.some(parameters, a => a == aSymbol) { + | true => defaultExpression->Ok // We cannot bind the parameters with global values + | false => + switch bindings->Belt.Map.String.get(aSymbol) { + | Some(boundExpression) => boundExpression->Ok + | None => defaultExpression->Ok + } + } + switch expression { | ExpressionT.EValue(EvSymbol(aSymbol)) => { let parameters = getParameters(bindings) @@ -51,7 +61,7 @@ let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings } | ExpressionT.EValue(EvCall(aSymbol)) => { let parameters = getParameters(bindings) - answerBindingIfNotParameter(aSymbol, expression, parameters, bindings) + answerCallBindingIfNotParameter(aSymbol, expression, parameters, bindings) } | ExpressionT.EValue(_) => expression->Ok | ExpressionT.EBindings(_) => expression->Ok From 1fb9218a94bbbccccb0ee00f4b35cd7b61125aa2 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 08:17:44 +0200 Subject: [PATCH 012/146] refactor passToFunction --- .../Reducer_Dispatch_BuiltInMacros.res | 28 +++++----- .../Reducer_Expression/Reducer_Expression.res | 33 +++++++++-- .../Reducer_Expression_Builder.res | 16 ++++++ .../Reducer_MathJs_ToExpression.res | 55 ++++++++----------- 4 files changed, 80 insertions(+), 52 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Builder.res diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index b32c430d..a8775590 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -34,25 +34,25 @@ let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings ): ExpressionT.bindings => Belt.Map.String.set(bindings, "$parameters", ExpressionT.EParameters(parameters)) - let answerBindingIfNotParameter = (aSymbol, defaultExpression, parameters, bindings) => + let answerBindingIfNotParameter = (aSymbol, defaultExpression, parameters, bindings) => switch Js.Array2.some(parameters, a => a == aSymbol) { - | true => defaultExpression->Ok // We cannot bind the parameters with global values - | false => - switch bindings->Belt.Map.String.get(aSymbol) { - | Some(boundExpression) => boundExpression->Ok - | None => RESymbolNotFound(aSymbol)->Error - } + | true => defaultExpression->Ok // We cannot bind the parameters with global values + | false => + switch bindings->Belt.Map.String.get(aSymbol) { + | Some(boundExpression) => boundExpression->Ok + | None => RESymbolNotFound(aSymbol)->Error } + } - let answerCallBindingIfNotParameter = (aSymbol, defaultExpression, parameters, bindings) => + let answerCallBindingIfNotParameter = (aSymbol, defaultExpression, parameters, bindings) => switch Js.Array2.some(parameters, a => a == aSymbol) { - | true => defaultExpression->Ok // We cannot bind the parameters with global values - | false => - switch bindings->Belt.Map.String.get(aSymbol) { - | Some(boundExpression) => boundExpression->Ok - | None => defaultExpression->Ok - } + | true => defaultExpression->Ok // We cannot bind the parameters with global values + | false => + switch bindings->Belt.Map.String.get(aSymbol) { + | Some(boundExpression) => boundExpression->Ok + | None => defaultExpression->Ok } + } switch expression { | ExpressionT.EValue(EvSymbol(aSymbol)) => { 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 7923db48..3e670a17 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 @@ -12,7 +12,7 @@ type internalCode = ExpressionValue.internalCode type t = expression external castExpressionToInternalCode: expression => internalCode = "%identity" -external castInternalCodeToInternalCode: internalCode => expression = "%identity" +external castInternalCodeToExpression: internalCode => expression = "%identity" /* Shows the expression as text of expression @@ -64,12 +64,36 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result, bindings: T.bindings): result => Reducer_Dispatch_BuiltInMacros.dispatchMacroCall(list, bindings, reduceExpression) + let applyParametersToLambda = ( + internal: internalCode, + parameters: array, + args: list, + ): result => { + let expr = castInternalCodeToExpression(internal) + let parameterList = parameters->Belt.List.fromArray + let zippedParameterList = parameterList->Belt.List.zip(args) + let bindings = Belt.List.reduce(zippedParameterList, defaultBindings, (a, (p, e)) => + a->Belt.Map.String.set(p, e->EValue) + ) + Js.log(`applyParametersToLambda: ${toString(expr)}`) + let inspectBindings = + bindings + ->Belt.Map.String.mapWithKey((k, v) => `${k}: ${toString(v)}`) + ->Belt.Map.String.valuesToArray + ->Js.Array2.toString + Js.log(` inspectBindings: ${inspectBindings}`) + reduceExpression(expr, bindings) + } + /* After reducing each level of expression(Lisp AST), we have a value list to evaluate */ let reduceValueList = (valueList: list): result => switch valueList { | list{EvCall(fName), ...args} => (fName, args->Belt.List.toArray)->BuiltIn.dispatch + // "(lambda(x=>internal) param)" + | list{EvLambda(parameters, internal), ...args} => + applyParametersToLambda(internal, parameters, args) | _ => valueList->Belt.List.toArray->ExpressionValue.EvArray->Ok } @@ -97,11 +121,8 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result => switch expression { - | T.EList(list{ - T.EValue(EvCall("$lambda")), - T.EParameters(parameters), - functionDefinition, - }) => EvLambda(parameters, functionDefinition->castExpressionToInternalCode)->Ok + | T.EList(list{T.EValue(EvCall("$lambda")), T.EParameters(parameters), functionDefinition}) => + EvLambda(parameters, functionDefinition->castExpressionToInternalCode)->Ok | T.EValue(value) => value->Ok | T.EList(list) => { let racc: result, 'e> = list->Belt.List.reduceReverse(Ok(list{}), ( diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Builder.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Builder.res new file mode 100644 index 00000000..4e5a988e --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Builder.res @@ -0,0 +1,16 @@ +module ErrorValue = Reducer_ErrorValue +module ExpressionT = Reducer_Expression_T +module ExpressionValue = ReducerInterface.ExpressionValue +module Result = Belt.Result + +type errorValue = ErrorValue.errorValue +type expression = ExpressionT.expression + +let passToFunction = (fName: string, lispArgs: list): expression => { + let toEvCallValue = (name: string): expression => name->ExpressionValue.EvCall->ExpressionT.EValue + let fn = fName->toEvCallValue + list{fn, ...lispArgs}->ExpressionT.EList +} + +let toEvSymbolValue = (name: string): expression => + name->ExpressionValue.EvSymbol->ExpressionT.EValue diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res index bf1fcafc..5dc53413 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res @@ -1,6 +1,7 @@ +module Builder = Reducer_Expression_Builder module ErrorValue = Reducer_ErrorValue -module ExpressionValue = ReducerInterface.ExpressionValue module ExpressionT = Reducer_Expression_T +module ExpressionValue = ReducerInterface.ExpressionValue module JavaScript = Reducer_Js module Parse = Reducer_MathJs_Parse module Result = Belt.Result @@ -9,13 +10,6 @@ type expression = ExpressionT.expression type expressionValue = ExpressionValue.expressionValue type errorValue = ErrorValue.errorValue -let passToFunction = (fName: string, rLispArgs): result => { - let toEvCallValue = (name: string): expression => name->ExpressionValue.EvCall->ExpressionT.EValue - - let fn = fName->toEvCallValue - rLispArgs->Result.flatMap(lispArgs => list{fn, ...lispArgs}->ExpressionT.EList->Ok) -} - type blockTag = | ImportVariablesStatement | ExportVariablesExpression @@ -34,12 +28,11 @@ let rec fromNode = (mathJsNode: Parse.node): result => ) ) - let toEvSymbolValue = (name: string): expression => - name->ExpressionValue.EvSymbol->ExpressionT.EValue - let caseFunctionNode = fNode => { - let lispArgs = fNode["args"]->Belt.List.fromArray->fromNodeList - passToFunction(fNode->Parse.nameOfFunctionNode, lispArgs) + let rLispArgs = fNode["args"]->Belt.List.fromArray->fromNodeList + rLispArgs->Result.flatMap(lispArgs => + Builder.passToFunction(fNode->Parse.nameOfFunctionNode, lispArgs)->Ok + ) } let caseObjectNode = oNode => { @@ -60,8 +53,8 @@ let rec fromNode = (mathJsNode: Parse.node): result => ) ) rargs->Result.flatMap(args => - passToFunction("$constructRecord", list{ExpressionT.EList(args)}->Ok) - ) // $consturctRecord gets a single argument: List of key-value paiers + Builder.passToFunction("$constructRecord", list{ExpressionT.EList(args)})->Ok + ) // $constructRecord gets a single argument: List of key-value paiers } oNode["properties"]->Js.Dict.entries->Belt.List.fromArray->fromObjectEntries @@ -85,30 +78,27 @@ let rec fromNode = (mathJsNode: Parse.node): result => let caseAccessorNode = (objectNode, indexNode) => { caseIndexNode(indexNode)->Result.flatMap(indexCode => { fromNode(objectNode)->Result.flatMap(objectCode => - passToFunction("$atIndex", list{objectCode, indexCode}->Ok) + Builder.passToFunction("$atIndex", list{objectCode, indexCode})->Ok ) }) } let caseAssignmentNode = aNode => { - let symbol = aNode["object"]["name"]->toEvSymbolValue + let symbol = aNode["object"]["name"]->Builder.toEvSymbolValue let rValueExpression = fromNode(aNode["value"]) - rValueExpression->Result.flatMap(valueExpression => { - let lispArgs = list{symbol, valueExpression}->Ok - passToFunction("$let", lispArgs) - }) + rValueExpression->Result.flatMap(valueExpression => + Builder.passToFunction("$let", list{symbol, valueExpression})->Ok + ) } let caseFunctionAssignmentNode = faNode => { - let symbol = faNode["name"]->toEvSymbolValue + let symbol = faNode["name"]->Builder.toEvSymbolValue let rValueExpression = fromNode(faNode["expr"]) rValueExpression->Result.flatMap(valueExpression => { let lispParams = faNode["params"]->ExpressionT.EParameters - let rLambda = passToFunction("$lambda", list{lispParams, valueExpression}->Ok) - rLambda->Result.flatMap(lambda => { - passToFunction("$let", list{symbol, lambda}->Ok) - }) + let lambda = Builder.passToFunction("$lambda", list{lispParams, valueExpression}) + Builder.passToFunction("$let", list{symbol, lambda})->Ok }) } @@ -121,7 +111,7 @@ let rec fromNode = (mathJsNode: Parse.node): result => | MjArrayNode(aNode) => caseArrayNode(aNode) | MjAssignmentNode(aNode) => caseAssignmentNode(aNode) | MjSymbolNode(sNode) => { - let expr: expression = toEvSymbolValue(sNode["name"]) + let expr: expression = Builder.toEvSymbolValue(sNode["name"]) let rExpr: result = expr->Ok rExpr } @@ -138,7 +128,7 @@ let rec fromNode = (mathJsNode: Parse.node): result => rFinalExpression }) and caseTagOrNodes = (tagOrNodes): result => { - let initialBindings = passToFunction("$$bindings", list{}->Ok) + let initialBindings = Builder.passToFunction("$$bindings", list{})->Ok let lastIndex = Belt.Array.length(tagOrNodes) - 1 tagOrNodes->Belt.Array.reduceWithIndex(initialBindings, (rPreviousBindings, tagOrNode, i) => { rPreviousBindings->Result.flatMap(previousBindings => { @@ -146,8 +136,10 @@ and caseTagOrNodes = (tagOrNodes): result => { | BlockNode(node) => fromNode(node) | BlockTag(tag) => switch tag { - | ImportVariablesStatement => passToFunction("$importVariablesStatement", list{}->Ok) - | ExportVariablesExpression => passToFunction("$exportVariablesExpression", list{}->Ok) + | ImportVariablesStatement => + Builder.passToFunction("$importVariablesStatement", list{})->Ok + | ExportVariablesExpression => + Builder.passToFunction("$exportVariablesExpression", list{})->Ok } } @@ -158,8 +150,7 @@ and caseTagOrNodes = (tagOrNodes): result => { } rStatement->Result.flatMap((statement: expression) => { - let lispArgs = list{previousBindings, statement}->Ok - passToFunction(bindName, lispArgs) + Builder.passToFunction(bindName, list{previousBindings, statement})->Ok }) }) }) From eba087329fd5d9128a69d09a703e31ae123ee704 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 08:33:48 +0200 Subject: [PATCH 013/146] called lamda with arguments (tested) --- .../Reducer_Expression/Reducer_Expression.res | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) 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 3e670a17..6243b380 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 @@ -1,9 +1,11 @@ +module Builder = Reducer_Expression_Builder module BuiltIn = Reducer_Dispatch_BuiltIn module ExpressionValue = ReducerInterface.ExpressionValue module Extra = Reducer_Extra module MathJs = Reducer_MathJs module Result = Belt.Result module T = Reducer_Expression_T + open Reducer_ErrorValue type expression = T.expression @@ -75,14 +77,11 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result a->Belt.Map.String.set(p, e->EValue) ) - Js.log(`applyParametersToLambda: ${toString(expr)}`) - let inspectBindings = - bindings - ->Belt.Map.String.mapWithKey((k, v) => `${k}: ${toString(v)}`) - ->Belt.Map.String.valuesToArray - ->Js.Array2.toString - Js.log(` inspectBindings: ${inspectBindings}`) - reduceExpression(expr, bindings) + let newExpression = Builder.passToFunction( + "$$bindExpression", + list{Builder.passToFunction("$$bindings", list{}), expr}, + ) + reduceExpression(newExpression, bindings) } /* From c5e08cfdb6f385f95055abc17655877ed6adbd44 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 09:17:38 +0200 Subject: [PATCH 014/146] modify lambda --- .../Reducer/Reducer_Expression/Reducer_Expression.res | 4 ++-- .../ReducerInterface/ReducerInterface_ExpressionValue.res | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) 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 6243b380..0fdb890d 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 @@ -91,7 +91,7 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result (fName, args->Belt.List.toArray)->BuiltIn.dispatch // "(lambda(x=>internal) param)" - | list{EvLambda(parameters, internal), ...args} => + | list{EvLambda((parameters, internal)), ...args} => applyParametersToLambda(internal, parameters, args) | _ => valueList->Belt.List.toArray->ExpressionValue.EvArray->Ok } @@ -121,7 +121,7 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result => switch expression { | T.EList(list{T.EValue(EvCall("$lambda")), T.EParameters(parameters), functionDefinition}) => - EvLambda(parameters, functionDefinition->castExpressionToInternalCode)->Ok + EvLambda((parameters, functionDefinition->castExpressionToInternalCode))->Ok | T.EValue(value) => value->Ok | T.EList(list) => { let racc: result, 'e> = list->Belt.List.reduceReverse(Ok(list{}), ( diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res index 1536be74..2b11a62f 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res @@ -14,7 +14,7 @@ type rec expressionValue = | EvBool(bool) | EvCall(string) // External function call | EvDistribution(GenericDist_Types.genericDist) - | EvLambda(array, internalCode) + | EvLambda((array, internalCode)) | EvNumber(float) | EvRecord(Js.Dict.t) | EvString(string) @@ -29,7 +29,7 @@ let rec toString = aValue => switch aValue { | EvBool(aBool) => Js.String.make(aBool) | EvCall(fName) => `:${fName}` - | EvLambda(parameters, _internalCode) => `lambda(${Js.Array2.toString(parameters)}=>internal)` + | EvLambda((parameters, _internalCode)) => `lambda(${Js.Array2.toString(parameters)}=>internal)` | EvNumber(aNumber) => Js.String.make(aNumber) | EvString(aString) => `'${aString}'` | EvSymbol(aString) => `:${aString}` @@ -60,7 +60,7 @@ let toStringWithType = aValue => | EvBool(_) => `Bool::${toString(aValue)}` | EvCall(_) => `Call::${toString(aValue)}` | EvDistribution(_) => `Distribution::${toString(aValue)}` - | EvLambda(_parameters, _internalCode) => `Lambda::${toString(aValue)}` + | EvLambda((_parameters, _internalCode)) => `Lambda::${toString(aValue)}` | EvNumber(_) => `Number::${toString(aValue)}` | EvRecord(_) => `Record::${toString(aValue)}` | EvString(_) => `String::${toString(aValue)}` From 6a87e8db28b486fc58eef26f1eded516d737626a Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 09:20:27 +0200 Subject: [PATCH 015/146] index.ts FAILURE!!!! --- packages/squiggle-lang/src/js/index.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 6ff022e0..c8731b0f 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -81,10 +81,13 @@ function tag(x: a, y: b): tagged { return { tag: x, value: y }; } +export abstract class internalCode { protected opaque!: any }; /* simulate opaque types */ + export type squiggleExpression = | tagged<"symbol", string> | tagged<"string", string> | tagged<"call", string> + | tagged<"lambda", [string[], internalCode]> | tagged<"array", squiggleExpression[]> | tagged<"boolean", boolean> | tagged<"distribution", Distribution> @@ -115,6 +118,8 @@ function createTsExport( return tag("boolean", x.value); case "EvCall": return tag("call", x.value); + case "EvLambda": + return tag("lambda", x.value); case "EvDistribution": return tag("distribution", new Distribution(x.value, sampEnv)); case "EvNumber": From c7be29346626797b6ea645e62c8db9d9a2c2573a Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 09:57:02 +0200 Subject: [PATCH 016/146] remove duplicate debug test case --- .../squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res index 3a2eea97..4baee94d 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res @@ -12,6 +12,5 @@ open Reducer_TestHelpers describe("Debugging", () => { testEvalToBe("inspect(1)", "Ok(1)") testEvalToBe("inspect(1, \"one\")", "Ok(1)") - testEvalToBe("inspect(1, \"one\")", "Ok(1)") testEvalToBe("inspectPerformance(1, \"one\")", "Ok(1)") }) From 3788cb0c9a8de21f52590b4bef65c8a86eb02e2f Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 10:52:13 +0200 Subject: [PATCH 017/146] fix variant warnings --- .../Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res | 4 ++-- .../Reducer/Reducer_Expression/Reducer_Expression.res | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index a8775590..5facc9e7 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -140,13 +140,13 @@ let dispatchMacroCall = ( expressionValue, ) => { let value = switch expressionValue { - | EValue(aValue) => aValue + | ExpressionT.EValue(aValue) => aValue | _ => EvSymbol("internal") } Js.Dict.set(acc, key, value) acc }) - externalBindings->EvRecord->ExpressionT.EValue->Ok + externalBindings->ExpressionValue.EvRecord->ExpressionT.EValue->Ok } let doBindExpression = (expression: expression, bindings: ExpressionT.bindings) => 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 0fdb890d..d27ece78 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 @@ -75,7 +75,7 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): resultBelt.List.fromArray let zippedParameterList = parameterList->Belt.List.zip(args) let bindings = Belt.List.reduce(zippedParameterList, defaultBindings, (a, (p, e)) => - a->Belt.Map.String.set(p, e->EValue) + a->Belt.Map.String.set(p, e->T.EValue) ) let newExpression = Builder.passToFunction( "$$bindExpression", From 4d801c0b10ca4399d58848a4959271f96be116a4 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 15:05:31 +0200 Subject: [PATCH 018/146] ternary operator mathjs parse (tested) --- .../Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res | 5 +++++ .../Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res index 988d5a88..ff9fd12c 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res @@ -66,4 +66,9 @@ describe("MathJs parse", () => { describe("comments", () => { testDescriptionParse("define", "1 # This is a comment", "1") }) + + describe("ternary operator", () => { + testParse("1 ? 2 : 3", "ternary(1, 2, 3)") + testParse("1 ? 2 : 3 ? 4 : 5", "ternary(1, 2, ternary(3, 4, 5))") + }) }) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res index 1f5df97d..704d1d38 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res @@ -9,7 +9,7 @@ type node = {"type": string, "isNode": bool, "comment": string} type arrayNode = {...node, "items": array} type block = {"node": node} type blockNode = {...node, "blocks": array} -//conditionalNode +type conditionalNode = {...node, "condition": node, "trueExpr": node, "falseExpr": node} type constantNode = {...node, "value": unit} type functionAssignmentNode = {...node, "name": string, "params": array, "expr": node} type indexNode = {...node, "dimensions": array} @@ -31,6 +31,7 @@ external castAssignmentNode: node => assignmentNode = "%identity" external castAssignmentNodeWAccessor: node => assignmentNodeWAccessor = "%identity" external castAssignmentNodeWIndex: node => assignmentNodeWIndex = "%identity" external castBlockNode: node => blockNode = "%identity" +external castConditionalNode: node => conditionalNode = "%identity" external castConstantNode: node => constantNode = "%identity" external castFunctionAssignmentNode: node => functionAssignmentNode = "%identity" external castFunctionNode: node => functionNode = "%identity" @@ -58,6 +59,7 @@ type mathJsNode = | MjArrayNode(arrayNode) | MjAssignmentNode(assignmentNode) | MjBlockNode(blockNode) + | MjConditionalNode(conditionalNode) | MjConstantNode(constantNode) | MjFunctionAssignmentNode(functionAssignmentNode) | MjFunctionNode(functionNode) @@ -82,6 +84,7 @@ let castNodeType = (node: node) => { | "ArrayNode" => node->castArrayNode->MjArrayNode->Ok | "AssignmentNode" => node->decideAssignmentNode | "BlockNode" => node->castBlockNode->MjBlockNode->Ok + | "ConditionalNode" => node->castConditionalNode->MjConditionalNode->Ok | "ConstantNode" => node->castConstantNode->MjConstantNode->Ok | "FunctionAssignmentNode" => node->castFunctionAssignmentNode->MjFunctionAssignmentNode->Ok | "FunctionNode" => node->castFunctionNode->MjFunctionNode->Ok @@ -157,6 +160,10 @@ let rec toString = (mathJsNode: mathJsNode): string => { | MjAssignmentNode(aNode) => `${aNode["object"]->toStringSymbolNode} = ${aNode["value"]->toStringMathJsNode}` | MjBlockNode(bNode) => `{${bNode["blocks"]->toStringBlocks}}` + | MjConditionalNode(cNode) => + `ternary(${toStringMathJsNode(cNode["condition"])}, ${toStringMathJsNode( + cNode["trueExpr"], + )}, ${toStringMathJsNode(cNode["falseExpr"])})` | MjConstantNode(cNode) => cNode["value"]->toStringValue | MjFunctionAssignmentNode(faNode) => faNode->toStringFunctionAssignmentNode | MjFunctionNode(fNode) => fNode->toStringFunctionNode From c810c4576d4a67039d4829e69c20c99756d494df Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 15:30:27 +0200 Subject: [PATCH 019/146] reducer semantics ternary (tested) --- .../Reducer/Reducer_ternaryOperator_test.res | 6 +++--- .../Reducer_MathJs/Reducer_MathJs_ToExpression.res | 13 +++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res index 61bfc8c7..b04944b9 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res @@ -1,9 +1,9 @@ open Jest open Reducer_TestHelpers -Skip.describe("Parse ternary operator", () => { - testParseToBe("true ? 'YES' : 'NO'", "Ok('YES')") - testParseToBe("false ? 'YES' : 'NO'", "Ok('NO')") +describe("Parse ternary operator", () => { + testParseToBe("true ? 'YES' : 'NO'", "Ok((:$$ternary true 'YES' 'NO'))") + testParseToBe("2>1 ? 'YES' : 'NO'", "Ok((:$$ternary (:larger 2 1) 'YES' 'NO'))") }) Skip.describe("Evaluate ternary operator", () => { diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res index 5dc53413..e600a156 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res @@ -116,6 +116,19 @@ let rec fromNode = (mathJsNode: Parse.node): result => rExpr } | MjBlockNode(bNode) => bNode["blocks"]->Belt.Array.map(toTagOrNode)->caseTagOrNodes + | MjConditionalNode(cndNode) => { + let rCondition = fromNode(cndNode["condition"]) + let rTrueExpr = fromNode(cndNode["trueExpr"]) + let rFalse = fromNode(cndNode["falseExpr"]) + + rCondition->Result.flatMap(condition => + rTrueExpr->Result.flatMap(trueExpr => + rFalse->Result.flatMap(falseExpr => + Builder.passToFunction("$$ternary", list{condition, trueExpr, falseExpr})->Ok + ) + ) + ) + } | MjConstantNode(cNode) => cNode["value"]->JavaScript.Gate.jsToEv->Result.flatMap(v => v->ExpressionT.EValue->Ok) | MjFunctionAssignmentNode(faNode) => caseFunctionAssignmentNode(faNode) From 7e4477aeda4f9e4b169f72cd300e7a5648800031 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 25 Apr 2022 10:00:27 -0400 Subject: [PATCH 020/146] Format Reducer code Value: [0.0000001 to 0.0005] --- packages/squiggle-lang/src/js/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index c8731b0f..ded1581e 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -81,7 +81,9 @@ function tag(x: a, y: b): tagged { return { tag: x, value: y }; } -export abstract class internalCode { protected opaque!: any }; /* simulate opaque types */ +export abstract class internalCode { + protected opaque!: any; +} /* simulate opaque types */ export type squiggleExpression = | tagged<"symbol", string> From d60aaa57f7333c6e04f468ef102b34293586ecc5 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 25 Apr 2022 10:10:07 -0400 Subject: [PATCH 021/146] Get tests to pass for Reducer code Value: [0.0001 to 0.04] --- packages/squiggle-lang/src/js/index.ts | 5 +---- packages/squiggle-lang/src/rescript/TypescriptInterface.res | 3 +++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index ded1581e..bed78695 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -10,6 +10,7 @@ import { continuousShape, discreteShape, distributionErrorToString, + internalCode, } from "../rescript/TypescriptInterface.gen"; export { makeSampleSetDist, @@ -81,10 +82,6 @@ function tag(x: a, y: b): tagged { return { tag: x, value: y }; } -export abstract class internalCode { - protected opaque!: any; -} /* simulate opaque types */ - export type squiggleExpression = | tagged<"symbol", string> | tagged<"string", string> diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index 8704bf5e..e200fbea 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -54,3 +54,6 @@ let errorValueToString = Reducer_ErrorValue.errorToString @genType let distributionErrorToString = DistributionTypes.Error.toString + +@genType +type internalCode = ReducerInterface_ExpressionValue.internalCode From cbc2b73b205dc8eeb3be4e705f0ae3439843c68a Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 16:01:02 +0200 Subject: [PATCH 022/146] Evaluate ternary operator (tested) --- .../Reducer/Reducer_ternaryOperator_test.res | 2 +- .../Reducer_Dispatch_BuiltInMacros.res | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res index b04944b9..940ff3c7 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res @@ -6,7 +6,7 @@ describe("Parse ternary operator", () => { testParseToBe("2>1 ? 'YES' : 'NO'", "Ok((:$$ternary (:larger 2 1) 'YES' 'NO'))") }) -Skip.describe("Evaluate ternary operator", () => { +describe("Evaluate ternary operator", () => { testEvalToBe("true ? 'YES' : 'NO'", "Ok('YES')") testEvalToBe("false ? 'YES' : 'NO'", "Ok('NO')") }) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index 5facc9e7..7174a5f7 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -158,6 +158,21 @@ let dispatchMacroCall = ( | _ => replaceSymbols(expression, bindings) } + let doTernary = ( + conditionExpr: expression, + trueExpression: expression, + falseExpression: expression, + bindings: ExpressionT.bindings, + ) => { + let rCondition = conditionExpr->reduceExpression(bindings) + rCondition->Result.flatMap(condition => + switch condition { + | EvBool(true) => trueExpression->Ok + | EvBool(false) => falseExpression->Ok + | _ => RESyntaxError("Boolean value expected for conditional")->Error + } + ) + } switch list { | list{ExpressionT.EValue(EvCall("$$bindings"))} => bindings->ExpressionT.EBindings->Ok @@ -173,6 +188,8 @@ let dispatchMacroCall = ( expression, } => doBindExpression(expression, bindings) + | list{ExpressionT.EValue(EvCall("$$ternary")), conditionExpr, trueExpr, falseExpr} => + doTernary(conditionExpr, trueExpr, falseExpr, bindings) | _ => list->ExpressionT.EList->Ok } } From ac8827da287ab1d3c88776800f20174eb93145b3 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 17:15:28 +0200 Subject: [PATCH 023/146] ternary with bindings (failed) --- .../Reducer/Reducer_ternaryOperator_test.res | 9 +++++++++ .../Reducer_Dispatch_BuiltInMacros.res | 12 ++++++++++++ .../Reducer_Expression/Reducer_Expression.res | 6 +----- .../Reducer_Expression_Builder.res | 3 +++ 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res index 940ff3c7..79bd870a 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res @@ -4,9 +4,18 @@ open Reducer_TestHelpers describe("Parse ternary operator", () => { testParseToBe("true ? 'YES' : 'NO'", "Ok((:$$ternary true 'YES' 'NO'))") testParseToBe("2>1 ? 'YES' : 'NO'", "Ok((:$$ternary (:larger 2 1) 'YES' 'NO'))") + MyOnly.testParseToBe( + "x = true; x ? 'YES' : 'NO' in x", + "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :x true)) (:$$ternary :x 'YES' (:multiply (:multiply 'NO' :in) :x))))", + ) }) describe("Evaluate ternary operator", () => { testEvalToBe("true ? 'YES' : 'NO'", "Ok('YES')") + MyOnly.testEvalToBe("x = true; x ? 'YES' : 'NO' in x", "Ok('YES')") testEvalToBe("false ? 'YES' : 'NO'", "Ok('NO')") }) + +describe("Evaluate ternary operator in subscope", () => { + testEvalToBe("x = true ? 'YES' : 'NO' in x", "Ok('YES')") +}) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index 7174a5f7..b174eb88 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -3,6 +3,7 @@ they take expressions as parameters and return a new expression. Macros are used to define language building blocks. They are like Lisp macros. */ +module Builder = Reducer_Expression_Builder module ExpressionT = Reducer_Expression_T module ExpressionValue = ReducerInterface.ExpressionValue module Result = Belt.Result @@ -164,6 +165,17 @@ let dispatchMacroCall = ( falseExpression: expression, bindings: ExpressionT.bindings, ) => { + // let rCondition = conditionExpr->Builder.asBindableExpression->reduceExpression(bindings) + let xString = switch Belt.Map.String.get(bindings, "x") { + | Some(EValue(value)) => value->ExpressionValue.toString + | None => "x Not Found" + } + + let bindingsString= Belt.Map.String.toArray(bindings)->Js.Array2.map( keyValue => { + let (key, ExpressionT.EValue(value)) = keyValue + `${key} = ${value->ExpressionValue.toString}` + })->Js.Array2.toString + Js.log(`ternary; bindings: {${bindingsString}}`) let rCondition = conditionExpr->reduceExpression(bindings) rCondition->Result.flatMap(condition => switch condition { 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 d27ece78..8829b4af 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 @@ -77,11 +77,7 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result a->Belt.Map.String.set(p, e->T.EValue) ) - let newExpression = Builder.passToFunction( - "$$bindExpression", - list{Builder.passToFunction("$$bindings", list{}), expr}, - ) - reduceExpression(newExpression, bindings) + reduceExpression(Builder.asBindableExpression(expr), bindings) } /* diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Builder.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Builder.res index 4e5a988e..eab60bd2 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Builder.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Builder.res @@ -14,3 +14,6 @@ let passToFunction = (fName: string, lispArgs: list): expression => let toEvSymbolValue = (name: string): expression => name->ExpressionValue.EvSymbol->ExpressionT.EValue + +let asBindableExpression = (expr: expression): expression => + passToFunction("$$bindExpression", list{passToFunction("$$bindings", list{}), expr}) From d00834bbe0f8f8f005b15819dc2369f94ed9e859 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 17:39:38 +0200 Subject: [PATCH 024/146] fix spelling - PR#366 --- .../Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res | 2 +- .../squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res index 988d5a88..a79ff024 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res @@ -25,7 +25,7 @@ module MyOnly = { } describe("MathJs parse", () => { - describe("literals operators paranthesis", () => { + describe("literals operators parenthesis", () => { testParse("1", "1") testParse("'hello'", "'hello'") testParse("true", "true") diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res index 4baee94d..f005c1fc 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res @@ -7,7 +7,7 @@ open Reducer_TestHelpers There is a second version of inspect that takes a label, which will print out the label and the value. - inpsectPerformace(expr, label) will print out the value of expr, the label, and the time it took to evaluate expr. + inspectPerformace(expr, label) will print out the value of expr, the label, and the time it took to evaluate expr. */ describe("Debugging", () => { testEvalToBe("inspect(1)", "Ok(1)") From 6878523186b32cdd74d5600b086ae96866d8c8c5 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 18:27:04 +0200 Subject: [PATCH 025/146] cancel performance hook --- .../Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index e107016f..47c39140 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -54,11 +54,13 @@ let callInternal = (call: functionCall): result<'b, errorValue> => { } let inspectPerformance = (value: expressionValue, label: string) => { - let _ = %raw("{performance} = require('perf_hooks')") - let start = %raw(`performance.now()`) - let finish = %raw(`performance.now()`) - let performance = finish - start - Js.log(`${label}: ${value->toString} performance: ${Js.String.make(performance)}ms`) + // let _ = %raw("{performance} = require('perf_hooks')") + // let start = %raw(`performance.now()`) + // let finish = %raw(`performance.now()`) + // let performance = finish - start + // Js.log(`${label}: ${value->toString} performance: ${Js.String.make(performance)}ms`) + // TODO find a way of failing the hook gracefully, also needs a block parameter + Js.log(`${label}: ${value->toString}`) value->Ok } From 7d4e3072b89696301ca16287ba942f247a813df1 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 18:35:15 +0200 Subject: [PATCH 026/146] commite related issue note --- .../Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 47c39140..3e365fd4 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -53,6 +53,10 @@ let callInternal = (call: functionCall): result<'b, errorValue> => { value->Ok } + /* + NOTE: This function is cancelled. The related issue is + https://github.com/webpack/webpack/issues/13435 + */ let inspectPerformance = (value: expressionValue, label: string) => { // let _ = %raw("{performance} = require('perf_hooks')") // let start = %raw(`performance.now()`) From 54f8b10a9577a376cfd67e35f425c957f37248ae Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Wed, 27 Apr 2022 22:00:42 +0200 Subject: [PATCH 027/146] Reducer: Environment (Give environement to all function dispatches) - closes #169 --- .../__tests__/Reducer/Reducer_TestHelpers.res | 13 +- .../src/rescript/Reducer/Reducer.res | 7 +- .../src/rescript/Reducer/Reducer.resi | 39 +++--- .../Reducer_Dispatch_BuiltIn.res | 6 +- .../Reducer_Dispatch_BuiltInMacros.res | 5 +- .../Reducer_Expression/Reducer_Expression.res | 114 +++++++++--------- .../ReducerInterface_ExpressionValue.res | 8 ++ .../ReducerInterface_ExternalLibrary.res | 4 +- .../ReducerInterface_GenericDistribution.res | 6 +- .../ReducerInterface_GenericDistribution.resi | 2 +- 10 files changed, 119 insertions(+), 85 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res index 581f6c8a..c56d4130 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res @@ -1,9 +1,17 @@ module Expression = Reducer.Expression module ExpressionValue = ReducerInterface.ExpressionValue +module ErrorValue = Reducer_ErrorValue open Jest open Expect +let unwrapRecord = rValue => + rValue->Belt.Result.flatMap(value => switch value { + | ExpressionValue.EvRecord(aRecord) => Ok(aRecord) + | _ => ErrorValue.RETodo("TODO: External bindings must be returned")->Error + } +) + let expectParseToBe = (expr: string, answer: string) => Reducer.parse(expr)->Expression.toStringResult->expect->toBe(answer) @@ -17,7 +25,7 @@ let expectEvalToBe = (expr: string, answer: string) => Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toBe(answer) let expectEvalBindingsToBe = (expr: string, bindings: Reducer.externalBindings, answer: string) => - Reducer.evaluateUsingExternalBindings(expr, bindings) + Reducer.evaluateUsingOptions(expr, ~externalBindings=Some(bindings), ~isPartial=None, ~environment=None) ->ExpressionValue.toStringResult ->expect ->toBe(answer) @@ -27,7 +35,8 @@ let expectEvalPartialBindingsToBe = ( bindings: Reducer.externalBindings, answer: string, ) => - Reducer.evaluatePartialUsingExternalBindings(expr, bindings) + Reducer.evaluateUsingOptions(expr, ~externalBindings=Some(bindings), ~isPartial=Some(true), ~environment=None) + ->unwrapRecord ->ExpressionValue.toStringResultRecord ->expect ->toBe(answer) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res index 63e1f3a7..a403ccd3 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res @@ -5,11 +5,12 @@ module Extra = Reducer_Extra module Js = Reducer_Js module MathJs = Reducer_MathJs +type environment = ReducerInterface_ExpressionValue.environment +type errorValue = Reducer_ErrorValue.errorValue type expressionValue = ReducerInterface_ExpressionValue.expressionValue type externalBindings = ReducerInterface_ExpressionValue.externalBindings -let evaluate = Expression.eval -let evaluateUsingExternalBindings = Expression.evalUsingExternalBindings -let evaluatePartialUsingExternalBindings = Expression.evalPartialUsingExternalBindings +let evaluate = Expression.evaluate +let evaluateUsingOptions = Expression.evaluateUsingOptions let parse = Expression.parse let parseOuter = Expression.parseOuter let parsePartial = Expression.parsePartial diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi index 8bbfc0b5..d71f9a5a 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi @@ -5,22 +5,29 @@ module Extra = Reducer_Extra module Js = Reducer_Js module MathJs = Reducer_MathJs -@genType +@genType +type environment = ReducerInterface_ExpressionValue.environment +@genType +type errorValue = Reducer_ErrorValue.errorValue +@genType type expressionValue = ReducerInterface_ExpressionValue.expressionValue -@genType +@genType type externalBindings = ReducerInterface_ExpressionValue.externalBindings -@genType -let evaluate: string => result -@genType -let evaluateUsingExternalBindings: ( + +@genType +let evaluateUsingOptions: ( + ~environment: option< + QuriSquiggleLang.ReducerInterface_ExpressionValue.environment, + >, + ~externalBindings: option< + QuriSquiggleLang.ReducerInterface_ExpressionValue.externalBindings, + >, + ~isPartial: option, string, - externalBindings, -) => result -@genType -let evaluatePartialUsingExternalBindings: ( - string, - externalBindings, -) => result -let parse: string => result -let parseOuter: string => result -let parsePartial: string => result +) => result +@genType +let evaluate: string => result + +let parse: string => result +let parseOuter: string => result +let parsePartial: string => result diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 3e365fd4..3733d7e2 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -11,7 +11,7 @@ open Reducer_ErrorValue exception TestRescriptException -let callInternal = (call: functionCall): result<'b, errorValue> => { +let callInternal = (call: functionCall, _environment): result<'b, errorValue> => { let callMathJs = (call: functionCall): result<'b, errorValue> => switch call { | ("javascriptraise", [msg]) => Js.Exn.raiseError(toString(msg)) // For Tests @@ -85,12 +85,12 @@ let callInternal = (call: functionCall): result<'b, errorValue> => { /* Reducer uses Result monad while reducing expressions */ -let dispatch = (call: functionCall): result => +let dispatch = (call: functionCall, environment): result => 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 - ExternalLibrary.dispatch((Js.String.make(fn), args), callInternal) + ExternalLibrary.dispatch((Js.String.make(fn), args), environment, callInternal) } catch { | Js.Exn.Error(obj) => REJavaScriptExn(Js.Exn.message(obj), Js.Exn.name(obj))->Error | _ => RETodo("unhandled rescript exception")->Error diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index 5facc9e7..185897e9 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -10,10 +10,12 @@ module Result = Belt.Result open Reducer_ErrorValue type expression = ExpressionT.expression +type environment = ExpressionValue.environment type reducerFn = ( expression, ExpressionT.bindings, + environment, ) => result let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings): result< @@ -101,6 +103,7 @@ let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings let dispatchMacroCall = ( list: list, bindings: ExpressionT.bindings, + environment, reduceExpression: reducerFn, ): result => { let doBindStatement = (statement: expression, bindings: ExpressionT.bindings) => { @@ -114,7 +117,7 @@ let dispatchMacroCall = ( let rNewValue = rNewExpressionToReduce->Result.flatMap(newExpressionToReduce => - reduceExpression(newExpressionToReduce, bindings) + reduceExpression(newExpressionToReduce, bindings, environment) ) let rNewExpression = rNewValue->Result.map(newValue => ExpressionT.EValue(newValue)) 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 d27ece78..052648ed 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 @@ -8,9 +8,12 @@ module T = Reducer_Expression_T open Reducer_ErrorValue +type environment = ReducerInterface_ExpressionValue.environment +type errorValue = Reducer_ErrorValue.errorValue type expression = T.expression -type expressionValue = ExpressionValue.expressionValue -type internalCode = ExpressionValue.internalCode +type expressionValue = ReducerInterface_ExpressionValue.expressionValue +type externalBindings = ReducerInterface_ExpressionValue.externalBindings +type internalCode = ReducerInterface_ExpressionValue.internalCode type t = expression external castExpressionToInternalCode: expression => internalCode = "%identity" @@ -57,19 +60,20 @@ let defaultBindings: T.bindings = Belt.Map.String.empty /* Recursively evaluate/reduce the expression (Lisp AST) */ -let rec reduceExpression = (expression: t, bindings: T.bindings): result => { +let rec reduceExpression = (expression: t, bindings: T.bindings, environment: environment): result => { /* Macros are like functions but instead of taking values as parameters, they take expressions as parameters and return a new expression. Macros are used to define language building blocks. They are like Lisp macros. */ - let doMacroCall = (list: list, bindings: T.bindings): result => - Reducer_Dispatch_BuiltInMacros.dispatchMacroCall(list, bindings, reduceExpression) + let doMacroCall = (list: list, bindings: T.bindings, environment: environment): result => + Reducer_Dispatch_BuiltInMacros.dispatchMacroCall(list, bindings, environment, reduceExpression) let applyParametersToLambda = ( internal: internalCode, parameters: array, args: list, + environment ): result => { let expr = castInternalCodeToExpression(internal) let parameterList = parameters->Belt.List.fromArray @@ -81,22 +85,22 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result): result => + let reduceValueList = (valueList: list, environment): result => switch valueList { - | list{EvCall(fName), ...args} => (fName, args->Belt.List.toArray)->BuiltIn.dispatch + | list{EvCall(fName), ...args} => (fName, args->Belt.List.toArray)->BuiltIn.dispatch(environment) // "(lambda(x=>internal) param)" | list{EvLambda((parameters, internal)), ...args} => - applyParametersToLambda(internal, parameters, args) + applyParametersToLambda(internal, parameters, args, environment) | _ => valueList->Belt.List.toArray->ExpressionValue.EvArray->Ok } - let rec seekMacros = (expression: t, bindings: T.bindings): result => + let rec seekMacros = (expression: t, bindings: T.bindings, environment): result => switch expression { | T.EValue(_value) => expression->Ok | T.EBindings(_value) => expression->Ok @@ -108,17 +112,17 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result racc->Result.flatMap(acc => { each - ->seekMacros(bindings) + ->seekMacros(bindings, environment) ->Result.flatMap(newNode => { acc->Belt.List.add(newNode)->Ok }) }) ) - racc->Result.flatMap(acc => acc->doMacroCall(bindings)) + racc->Result.flatMap(acc => acc->doMacroCall(bindings, environment)) } } - let rec reduceExpandedExpression = (expression: t): result => + let rec reduceExpandedExpression = (expression: t, environment): result => switch expression { | T.EList(list{T.EValue(EvCall("$lambda")), T.EParameters(parameters), functionDefinition}) => EvLambda((parameters, functionDefinition->castExpressionToInternalCode))->Ok @@ -130,36 +134,36 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result racc->Result.flatMap(acc => { each - ->reduceExpandedExpression + ->reduceExpandedExpression(environment) ->Result.flatMap(newNode => { acc->Belt.List.add(newNode)->Ok }) }) ) - racc->Result.flatMap(acc => acc->reduceValueList) + racc->Result.flatMap(acc => acc->reduceValueList(environment)) } | EBindings(_bindings) => RETodo("Error: Bindings cannot be reduced to values")->Error | EParameters(_parameters) => RETodo("Error: Lambda Parameters cannot be reduced to values")->Error } - let rExpandedExpression: result = expression->seekMacros(bindings) + let rExpandedExpression: result = expression->seekMacros(bindings, environment) rExpandedExpression->Result.flatMap(expandedExpression => - expandedExpression->reduceExpandedExpression + expandedExpression->reduceExpandedExpression(environment) ) } -let evalUsingExternalBindingsExpression_ = (aExpression, bindings): result => - reduceExpression(aExpression, bindings) +let evalUsingExternalBindingsExpression_ = (aExpression, bindings, environment): result => + reduceExpression(aExpression, bindings, environment) /* Evaluates MathJs code via Reducer using bindings and answers the result. When bindings are used, the code is a partial code as if it is cut from a larger code. Therefore all statements are assignments. */ -let evalPartialUsingExternalBindings_ = (codeText: string, bindings: T.bindings) => { +let evalPartial_ = (codeText: string, bindings: T.bindings, environment: environment) => { parsePartial(codeText)->Result.flatMap(expression => - expression->evalUsingExternalBindingsExpression_(bindings) + expression->evalUsingExternalBindingsExpression_(bindings, environment) ) } @@ -168,23 +172,12 @@ let evalPartialUsingExternalBindings_ = (codeText: string, bindings: T.bindings) When bindings are used, the code is a partial code as if it is cut from a larger code. Therefore all statments are assignments. */ -let evalOuterWBindings_ = (codeText: string, bindings: T.bindings) => { +let evalOuter_ = (codeText: string, bindings: T.bindings, environment: environment) => { parseOuter(codeText)->Result.flatMap(expression => - expression->evalUsingExternalBindingsExpression_(bindings) + expression->evalUsingExternalBindingsExpression_(bindings, environment) ) } -/* - Evaluates MathJs code and bindings via Reducer and answers the result -*/ -let eval = (codeText: string) => { - parse(codeText)->Result.flatMap(expression => - expression->evalUsingExternalBindingsExpression_(defaultBindings) - ) -} - -type externalBindings = ReducerInterface.ExpressionValue.externalBindings //Js.Dict.t - let externalBindingsToBindings = (externalBindings: externalBindings): T.bindings => { let keys = Js.Dict.keys(externalBindings) keys->Belt.Array.reduce(defaultBindings, (acc, key) => { @@ -192,28 +185,41 @@ let externalBindingsToBindings = (externalBindings: externalBindings): T.binding acc->Belt.Map.String.set(key, T.EValue(value)) }) } -/* - Evaluates code with external bindings. External bindings are a record of expression values. -*/ -let evalUsingExternalBindings = (code: string, externalBindings: externalBindings) => { - let bindings = externalBindings->externalBindingsToBindings - evalOuterWBindings_(code, bindings) + +let evaluateUsingOptions = ( + ~environment: option, + ~externalBindings: option, + ~isPartial: option, + code: string): result => { + + let anEnvironment = switch environment { + | Some(env) => env + | None => ReducerInterface_ExpressionValue.defaultEnvironment + } + + let anExternalBindings = switch externalBindings { + | Some(bindings) => bindings + | None => ReducerInterface_ExpressionValue.defaultExternalBindings + } + + let anIsPartial = switch isPartial { + | Some(isPartial) => isPartial + | None => false + } + + let bindings = anExternalBindings->externalBindingsToBindings + + if anIsPartial { + evalPartial_(code, bindings, anEnvironment) + } else { + evalOuter_(code, bindings, anEnvironment) + } } /* - Evaluates code with external bindings. External bindings are a record of expression values. - The code is a partial code as if it is cut from a larger code. Therefore all statments are assignments. + Evaluates MathJs code and bindings via Reducer and answers the result */ -let evalPartialUsingExternalBindings = (code: string, externalBindings: externalBindings): result< - externalBindings, - 'e, -> => { - let bindings = externalBindings->externalBindingsToBindings - let answer = evalPartialUsingExternalBindings_(code, bindings) - answer->Result.flatMap(answer => - switch answer { - | EvRecord(aRecord) => Ok(aRecord) - | _ => RETodo("TODO: External bindings must be returned")->Error - } - ) +let evaluate = (code: string): result => { + evaluateUsingOptions(~environment=None, ~externalBindings=None, ~isPartial=None, code) } +let eval = evaluate diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res index 6c15536b..96068dca 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res @@ -22,6 +22,9 @@ type rec expressionValue = @genType type externalBindings = Js.Dict.t +@genType +let defaultExternalBindings: externalBindings = Js.Dict.empty() + type functionCall = (string, array) @@ -84,3 +87,8 @@ let toStringResultRecord = x => | Ok(a) => `Ok(${toStringRecord(a)})` | Error(m) => `Error(${ErrorValue.errorToString(m)})` } + +@genType +type environment = {dummy: int} +@genType +let defaultEnvironment: environment = {dummy: 0} diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res index 84d37d95..fde0faf2 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res @@ -14,8 +14,8 @@ type expressionValue = ExpressionValue.expressionValue Map external calls of Reducer */ -let dispatch = (call: ExpressionValue.functionCall, chain): result => - ReducerInterface_GenericDistribution.dispatch(call) |> E.O.default(chain(call)) +let dispatch = (call: ExpressionValue.functionCall, environment, chain): result => + ReducerInterface_GenericDistribution.dispatch(call, environment) |> E.O.default(chain(call, environment)) /* If your dispatch is too big you can divide it into smaller dispatches and pass the call so that it gets called finally. diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index f39dc932..5ed33809 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -180,7 +180,7 @@ module Math = { let e = 2.718281828459 } -let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option< +let dispatchToGenericOutput = (call: ExpressionValue.functionCall, _environment): option< DistributionOperation.outputType, > => { let (fnName, args) = call @@ -266,6 +266,6 @@ let genericOutputToReducerValue = (o: DistributionOperation.outputType): result< | GenDistError(err) => Error(REDistributionError(err)) } -let dispatch = call => { - dispatchToGenericOutput(call)->E.O2.fmap(genericOutputToReducerValue) +let dispatch = (call, environment) => { + dispatchToGenericOutput(call, environment)->E.O2.fmap(genericOutputToReducerValue) } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi index fc7ebabc..26464d44 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi @@ -1,3 +1,3 @@ -let dispatch: ReducerInterface_ExpressionValue.functionCall => option< +let dispatch: (ReducerInterface_ExpressionValue.functionCall, ReducerInterface_ExpressionValue.environment) => option< result, > From 5c1ce71a40d838cb29c229976b065e061728d464 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Wed, 27 Apr 2022 22:09:25 +0200 Subject: [PATCH 028/146] fix TypescriptInterface.res --- packages/squiggle-lang/src/rescript/TypescriptInterface.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index 5e2a59b6..a16e6875 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -32,7 +32,7 @@ let makeSampleSetDist = SampleSetDist.make let evaluate = Reducer.evaluate @genType -let evaluateUsingExternalBindings = Reducer.evaluateUsingExternalBindings +let evaluateUsingOptions = Reducer.evaluateUsingOptions @genType type expressionValue = ReducerInterface_ExpressionValue.expressionValue From 7b052ee3c34a87c5d9edd0a1325f5a806ff12378 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Wed, 27 Apr 2022 22:24:06 +0200 Subject: [PATCH 029/146] format --- .../__tests__/Reducer/Reducer_TestHelpers.res | 25 +++++++--- .../src/rescript/Reducer/Reducer.resi | 20 ++++---- .../Reducer_Dispatch_BuiltIn.res | 2 +- .../Reducer_Expression/Reducer_Expression.res | 48 ++++++++++++------- .../ReducerInterface_ExpressionValue.res | 1 - .../ReducerInterface_ExternalLibrary.res | 9 +++- .../ReducerInterface_GenericDistribution.resi | 7 +-- 7 files changed, 68 insertions(+), 44 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res index c56d4130..a38624dc 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res @@ -6,11 +6,12 @@ open Jest open Expect let unwrapRecord = rValue => - rValue->Belt.Result.flatMap(value => switch value { - | ExpressionValue.EvRecord(aRecord) => Ok(aRecord) - | _ => ErrorValue.RETodo("TODO: External bindings must be returned")->Error - } -) + rValue->Belt.Result.flatMap(value => + switch value { + | ExpressionValue.EvRecord(aRecord) => Ok(aRecord) + | _ => ErrorValue.RETodo("TODO: External bindings must be returned")->Error + } + ) let expectParseToBe = (expr: string, answer: string) => Reducer.parse(expr)->Expression.toStringResult->expect->toBe(answer) @@ -25,7 +26,12 @@ let expectEvalToBe = (expr: string, answer: string) => Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toBe(answer) let expectEvalBindingsToBe = (expr: string, bindings: Reducer.externalBindings, answer: string) => - Reducer.evaluateUsingOptions(expr, ~externalBindings=Some(bindings), ~isPartial=None, ~environment=None) + Reducer.evaluateUsingOptions( + expr, + ~externalBindings=Some(bindings), + ~isPartial=None, + ~environment=None, + ) ->ExpressionValue.toStringResult ->expect ->toBe(answer) @@ -35,7 +41,12 @@ let expectEvalPartialBindingsToBe = ( bindings: Reducer.externalBindings, answer: string, ) => - Reducer.evaluateUsingOptions(expr, ~externalBindings=Some(bindings), ~isPartial=Some(true), ~environment=None) + Reducer.evaluateUsingOptions( + expr, + ~externalBindings=Some(bindings), + ~isPartial=Some(true), + ~environment=None, + ) ->unwrapRecord ->ExpressionValue.toStringResultRecord ->expect diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi index d71f9a5a..8ea6047a 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi @@ -5,27 +5,23 @@ module Extra = Reducer_Extra module Js = Reducer_Js module MathJs = Reducer_MathJs -@genType +@genType type environment = ReducerInterface_ExpressionValue.environment -@genType +@genType type errorValue = Reducer_ErrorValue.errorValue -@genType +@genType type expressionValue = ReducerInterface_ExpressionValue.expressionValue -@genType +@genType type externalBindings = ReducerInterface_ExpressionValue.externalBindings -@genType +@genType let evaluateUsingOptions: ( - ~environment: option< - QuriSquiggleLang.ReducerInterface_ExpressionValue.environment, - >, - ~externalBindings: option< - QuriSquiggleLang.ReducerInterface_ExpressionValue.externalBindings, - >, + ~environment: option, + ~externalBindings: option, ~isPartial: option, string, ) => result -@genType +@genType let evaluate: string => result let parse: string => result diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 3733d7e2..93960cf6 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -56,7 +56,7 @@ let callInternal = (call: functionCall, _environment): result<'b, errorValue> => /* NOTE: This function is cancelled. The related issue is https://github.com/webpack/webpack/issues/13435 - */ + */ let inspectPerformance = (value: expressionValue, label: string) => { // let _ = %raw("{performance} = require('perf_hooks')") // let start = %raw(`performance.now()`) 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 052648ed..1713476f 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 @@ -60,20 +60,26 @@ let defaultBindings: T.bindings = Belt.Map.String.empty /* Recursively evaluate/reduce the expression (Lisp AST) */ -let rec reduceExpression = (expression: t, bindings: T.bindings, environment: environment): result => { +let rec reduceExpression = (expression: t, bindings: T.bindings, environment: environment): result< + expressionValue, + 'e, +> => { /* Macros are like functions but instead of taking values as parameters, they take expressions as parameters and return a new expression. Macros are used to define language building blocks. They are like Lisp macros. */ - let doMacroCall = (list: list, bindings: T.bindings, environment: environment): result => + let doMacroCall = (list: list, bindings: T.bindings, environment: environment): result< + t, + 'e, + > => Reducer_Dispatch_BuiltInMacros.dispatchMacroCall(list, bindings, environment, reduceExpression) let applyParametersToLambda = ( internal: internalCode, parameters: array, args: list, - environment + environment, ): result => { let expr = castInternalCodeToExpression(internal) let parameterList = parameters->Belt.List.fromArray @@ -91,9 +97,13 @@ let rec reduceExpression = (expression: t, bindings: T.bindings, environment: en /* After reducing each level of expression(Lisp AST), we have a value list to evaluate */ - let reduceValueList = (valueList: list, environment): result => + let reduceValueList = (valueList: list, environment): result< + expressionValue, + 'e, + > => switch valueList { - | list{EvCall(fName), ...args} => (fName, args->Belt.List.toArray)->BuiltIn.dispatch(environment) + | list{EvCall(fName), ...args} => + (fName, args->Belt.List.toArray)->BuiltIn.dispatch(environment) // "(lambda(x=>internal) param)" | list{EvLambda((parameters, internal)), ...args} => applyParametersToLambda(internal, parameters, args, environment) @@ -153,8 +163,10 @@ let rec reduceExpression = (expression: t, bindings: T.bindings, environment: en ) } -let evalUsingExternalBindingsExpression_ = (aExpression, bindings, environment): result => - reduceExpression(aExpression, bindings, environment) +let evalUsingExternalBindingsExpression_ = (aExpression, bindings, environment): result< + expressionValue, + 'e, +> => reduceExpression(aExpression, bindings, environment) /* Evaluates MathJs code via Reducer using bindings and answers the result. @@ -187,24 +199,24 @@ let externalBindingsToBindings = (externalBindings: externalBindings): T.binding } let evaluateUsingOptions = ( - ~environment: option, - ~externalBindings: option, - ~isPartial: option, - code: string): result => { - + ~environment: option, + ~externalBindings: option, + ~isPartial: option, + code: string, +): result => { let anEnvironment = switch environment { - | Some(env) => env - | None => ReducerInterface_ExpressionValue.defaultEnvironment + | Some(env) => env + | None => ReducerInterface_ExpressionValue.defaultEnvironment } let anExternalBindings = switch externalBindings { - | Some(bindings) => bindings - | None => ReducerInterface_ExpressionValue.defaultExternalBindings + | Some(bindings) => bindings + | None => ReducerInterface_ExpressionValue.defaultExternalBindings } let anIsPartial = switch isPartial { - | Some(isPartial) => isPartial - | None => false + | Some(isPartial) => isPartial + | None => false } let bindings = anExternalBindings->externalBindingsToBindings diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res index 96068dca..7e8d1150 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res @@ -25,7 +25,6 @@ type externalBindings = Js.Dict.t @genType let defaultExternalBindings: externalBindings = Js.Dict.empty() - type functionCall = (string, array) let rec toString = aValue => diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res index fde0faf2..0bdb0748 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res @@ -14,8 +14,13 @@ type expressionValue = ExpressionValue.expressionValue Map external calls of Reducer */ -let dispatch = (call: ExpressionValue.functionCall, environment, chain): result => - ReducerInterface_GenericDistribution.dispatch(call, environment) |> E.O.default(chain(call, environment)) +let dispatch = (call: ExpressionValue.functionCall, environment, chain): result< + expressionValue, + 'e, +> => + ReducerInterface_GenericDistribution.dispatch(call, environment) |> E.O.default( + chain(call, environment), + ) /* If your dispatch is too big you can divide it into smaller dispatches and pass the call so that it gets called finally. diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi index 26464d44..7f26a610 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi @@ -1,3 +1,4 @@ -let dispatch: (ReducerInterface_ExpressionValue.functionCall, ReducerInterface_ExpressionValue.environment) => option< - result, -> +let dispatch: ( + ReducerInterface_ExpressionValue.functionCall, + ReducerInterface_ExpressionValue.environment, +) => option> From dde28e54f084c751bdbc24a75cf625efabbe1e7b Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 28 Apr 2022 10:17:29 -0400 Subject: [PATCH 030/146] Restructuring of E Sorted --- .../AlgebraicShapeCombination.res | 2 +- .../SampleSetDist_ToPointSet.res | 2 +- .../squiggle-lang/src/rescript/Utility/E.res | 126 +++++++++--------- 3 files changed, 63 insertions(+), 67 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/AlgebraicShapeCombination.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/AlgebraicShapeCombination.res index 63600e43..a51de00d 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/AlgebraicShapeCombination.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/AlgebraicShapeCombination.res @@ -263,4 +263,4 @@ let combineShapesContinuousDiscrete = ( ) } -let isOrdered = (a: XYShape.T.t): bool => E.A.Sorted.Floats.isSorted(a.xs) +let isOrdered = (a: XYShape.T.t): bool => E.A.Floats.isSorted(a.xs) diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res index 90537a12..da9f941f 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res @@ -85,7 +85,7 @@ let toPointSetDist = ( (), ): Internals.Types.outputs => { Array.fast_sort(compare, samples) - let (continuousPart, discretePart) = E.A.Sorted.Floats.split(samples) + let (continuousPart, discretePart) = E.A.Sorted.split(samples) let length = samples |> E.A.length |> float_of_int let discrete: PointSetTypes.discreteShape = discretePart diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index 030c2961..9c11426a 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -475,42 +475,73 @@ module A = { } } - module Sorted = { - let min = first - let max = last - let range = (~min=min, ~max=max, a) => - switch (min(a), max(a)) { - | (Some(min), Some(max)) => Some(max -. min) - | _ => None - } + module Floats = { + let mean = Jstat.mean + let geomean = Jstat.geomean + let mode = Jstat.mode + let variance = Jstat.variance + let stdev = Jstat.stdev + let sum = Jstat.sum + let random = Js.Math.random_int let floatCompare: (float, float) => int = compare + let sort = t => { + let r = t + r |> Array.fast_sort(floatCompare) + r + } - let binarySearchFirstElementGreaterIndex = (ar: array<'a>, el: 'a) => { - let el = Belt.SortArray.binarySearchBy(ar, el, floatCompare) - let el = el < 0 ? el * -1 - 1 : el - switch el { - | e if e >= length(ar) => #overMax - | e if e == 0 => #underMin - | e => #firstHigher(e) + let isSorted = (ar: array): bool => + reduce(zip(ar, tail(ar)), true, (acc, (first, second)) => acc && first < second) + + //Passing true for the exclusive parameter excludes both endpoints of the range. + //https://jstat.github.io/all.html + let percentile = (a, b) => Jstat.percentile(a, b, false) + + // Gives an array with all the differences between values + // diff([1,5,3,7]) = [4,-2,4] + let diff = (arr: array): array => + Belt.Array.zipBy(arr, Belt.Array.sliceToEnd(arr, 1), (left, right) => right -. left) + + exception RangeError(string) + let range = (min: float, max: float, n: int): array => + switch n { + | 0 => [] + | 1 => [min] + | 2 => [min, max] + | _ if min == max => Belt.Array.make(n, min) + | _ if n < 0 => raise(RangeError("n must be greater than 0")) + | _ if min > max => raise(RangeError("Min value is less then max value")) + | _ => + let diff = (max -. min) /. Belt.Float.fromInt(n - 1) + Belt.Array.makeBy(n, i => min +. Belt.Float.fromInt(i) *. diff) } - } - let concat = (t1: array<'a>, t2: array<'a>) => { - let ts = Belt.Array.concat(t1, t2) - ts |> Array.fast_sort(floatCompare) - ts - } + let min = Js.Math.minMany_float + let max = Js.Math.maxMany_float - let concatMany = (t1: array>) => { - let ts = Belt.Array.concatMany(t1) - ts |> Array.fast_sort(floatCompare) - ts - } + module Sorted = { + let min = first + let max = last + let range = (~min=min, ~max=max, a) => + switch (min(a), max(a)) { + | (Some(min), Some(max)) => Some(max -. min) + | _ => None + } - module Floats = { - let isSorted = (ar: array): bool => - reduce(zip(ar, tail(ar)), true, (acc, (first, second)) => acc && first < second) + let binarySearchFirstElementGreaterIndex = (ar: array<'a>, el: 'a) => { + let el = Belt.SortArray.binarySearchBy(ar, el, floatCompare) + let el = el < 0 ? el * -1 - 1 : el + switch el { + | e if e >= length(ar) => #overMax + | e if e == 0 => #underMin + | e => #firstHigher(e) + } + } + + let concat = (t1: array<'a>, t2: array<'a>) => Belt.Array.concat(t1, t2)->sort + + let concatMany = (t1: array>) => Belt.Array.concatMany(t1)->sort let makeIncrementalUp = (a, b) => Array.make(b - a + 1, a) |> Array.mapi((i, c) => c + i) |> Belt.Array.map(_, float_of_int) @@ -543,42 +574,7 @@ module A = { } } } - - module Floats = { - let mean = Jstat.mean - let geomean = Jstat.geomean - let mode = Jstat.mode - let variance = Jstat.variance - let stdev = Jstat.stdev - let sum = Jstat.sum - let random = Js.Math.random_int - - //Passing true for the exclusive parameter excludes both endpoints of the range. - //https://jstat.github.io/all.html - let percentile = (a, b) => Jstat.percentile(a, b, false) - - // Gives an array with all the differences between values - // diff([1,5,3,7]) = [4,-2,4] - let diff = (arr: array): array => - Belt.Array.zipBy(arr, Belt.Array.sliceToEnd(arr, 1), (left, right) => right -. left) - - exception RangeError(string) - let range = (min: float, max: float, n: int): array => - switch n { - | 0 => [] - | 1 => [min] - | 2 => [min, max] - | _ if min == max => Belt.Array.make(n, min) - | _ if n < 0 => raise(RangeError("n must be greater than 0")) - | _ if min > max => raise(RangeError("Min value is less then max value")) - | _ => - let diff = (max -. min) /. Belt.Float.fromInt(n - 1) - Belt.Array.makeBy(n, i => min +. Belt.Float.fromInt(i) *. diff) - } - - let min = Js.Math.minMany_float - let max = Js.Math.maxMany_float - } + module Sorted = Floats.Sorted; } module A2 = { From d1ffac492cb0c4147ace407c3f36418081459887 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 28 Apr 2022 11:39:29 -0400 Subject: [PATCH 031/146] Draft of Validates for XYShape --- packages/squiggle-lang/src/rescript/Utility/E.res | 14 +++++++++----- .../squiggle-lang/src/rescript/Utility/XYShape.res | 10 ++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index 9c11426a..45051578 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -476,6 +476,7 @@ module A = { } module Floats = { + type t = array let mean = Jstat.mean let geomean = Jstat.geomean let mode = Jstat.mode @@ -491,8 +492,11 @@ module A = { r } - let isSorted = (ar: array): bool => - reduce(zip(ar, tail(ar)), true, (acc, (first, second)) => acc && first < second) + let getNonFinite = (t: t) => Belt.Array.getBy(t, r => !Js.Float.isFinite(r)) + let getBelowZero = (t: t) => Belt.Array.getBy(t, r => r < 0.0) + + let isSorted = (t: t): bool => + reduce(zip(t, tail(t)), true, (acc, (first, second)) => acc && first < second) //Passing true for the exclusive parameter excludes both endpoints of the range. //https://jstat.github.io/all.html @@ -500,8 +504,8 @@ module A = { // Gives an array with all the differences between values // diff([1,5,3,7]) = [4,-2,4] - let diff = (arr: array): array => - Belt.Array.zipBy(arr, Belt.Array.sliceToEnd(arr, 1), (left, right) => right -. left) + let diff = (t: t): array => + Belt.Array.zipBy(t, Belt.Array.sliceToEnd(t, 1), (left, right) => right -. left) exception RangeError(string) let range = (min: float, max: float, n: int): array => @@ -574,7 +578,7 @@ module A = { } } } - module Sorted = Floats.Sorted; + module Sorted = Floats.Sorted } module A2 = { diff --git a/packages/squiggle-lang/src/rescript/Utility/XYShape.res b/packages/squiggle-lang/src/rescript/Utility/XYShape.res index 97974884..e22dc5fd 100644 --- a/packages/squiggle-lang/src/rescript/Utility/XYShape.res +++ b/packages/squiggle-lang/src/rescript/Utility/XYShape.res @@ -62,6 +62,16 @@ module T = { let toJs = (t: t) => {"xs": t.xs, "ys": t.ys} } +module Validates = { + type t = T.t + let areXsSorted = (t:t) => E.A.Floats.isSorted(T.xs(t)) + let validate = (t:t) => { + let xsNotSorted = E.A.Floats.isSorted(T.xs(t)) ? None : Some("Xs are not sorted") + let xsNotFinite = E.A.Floats.getNonFinite(T.xs(t)) |> E.O.fmap(r => `Xs contain non-finite values: ${E.Float.toString(r)}`) + let ysNotFinite = E.A.Floats.getNonFinite(T.ys(t)) |> E.O.fmap(r => `Ys contain non-finite values: ${E.Float.toString(r)}`) + } +} + module Ts = { type t = T.ts let minX = (t: t) => t |> E.A.fmap(T.minX) |> E.A.Floats.min From 03cd887084db7354751312bd9c3e43872c36354b Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 28 Apr 2022 12:47:04 -0400 Subject: [PATCH 032/146] Adding better error messages to XYShape validator --- .../squiggle-lang/src/rescript/Utility/E.res | 1 + .../src/rescript/Utility/Errors.res | 29 ++++++++++++++ .../src/rescript/Utility/XYShape.res | 38 ++++++++++++++++--- 3 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/Utility/Errors.res diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index 45051578..88024c3b 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -584,6 +584,7 @@ module A = { module A2 = { let fmap = (a, b) => A.fmap(b, a) let joinWith = (a, b) => A.joinWith(b, a) + let filter = (a,b) => A.filter(b, a) } module JsArray = { diff --git a/packages/squiggle-lang/src/rescript/Utility/Errors.res b/packages/squiggle-lang/src/rescript/Utility/Errors.res new file mode 100644 index 00000000..6f52b21c --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/Errors.res @@ -0,0 +1,29 @@ +type property = {fnName: string, propertyName: string} + +type rec error = + | NotSorted(property) + | IsEmpty(property) + | NotFinite(property, float) + | DifferentLengths({fnName: string, p1Name: string, p2Name: string, p1Length: int, p2Length: int}) + | Multiple(array) + +let mapErrorArrayToError = (errors: array): option => { + switch errors { + | [] => None + | [error] => Some(error) + | _ => Some(Multiple(errors)) + } +} + +let rec toString = (t: error) => + switch t { + | NotSorted({fnName, propertyName}) => `${fnName} ${propertyName} is not sorted` + | IsEmpty({fnName, propertyName}) => `${fnName} ${propertyName} is empty` + | NotFinite({fnName, propertyName}, exampleValue) => + `${fnName} ${propertyName} is not finite. Example value: ${E.Float.toString(exampleValue)}` + | DifferentLengths({fnName, p1Name, p2Name, p1Length, p2Length}) => + `${fnName} ${p1Name} and ${p2Name} have different lengths. ${p1Name} has length ${E.I.toString( + p1Length, + )} and ${p2Name} has length ${E.I.toString(p2Length)}` + | Multiple(errors) => `Multiple Errors: ${E.A2.fmap(errors, toString) |> E.A.joinWith(", ")}` + } diff --git a/packages/squiggle-lang/src/rescript/Utility/XYShape.res b/packages/squiggle-lang/src/rescript/Utility/XYShape.res index e22dc5fd..9368c1ee 100644 --- a/packages/squiggle-lang/src/rescript/Utility/XYShape.res +++ b/packages/squiggle-lang/src/rescript/Utility/XYShape.res @@ -62,13 +62,39 @@ module T = { let toJs = (t: t) => {"xs": t.xs, "ys": t.ys} } -module Validates = { +module Validator = { type t = T.t - let areXsSorted = (t:t) => E.A.Floats.isSorted(T.xs(t)) - let validate = (t:t) => { - let xsNotSorted = E.A.Floats.isSorted(T.xs(t)) ? None : Some("Xs are not sorted") - let xsNotFinite = E.A.Floats.getNonFinite(T.xs(t)) |> E.O.fmap(r => `Xs contain non-finite values: ${E.Float.toString(r)}`) - let ysNotFinite = E.A.Floats.getNonFinite(T.ys(t)) |> E.O.fmap(r => `Ys contain non-finite values: ${E.Float.toString(r)}`) + let fnName = "XYShape validate" + let property = (propertyName: string): Errors.property => { + fnName: fnName, + propertyName: propertyName, + } + let notSortedError = (p: string): Errors.error => NotSorted(property(p)) + let notFiniteError = (p, exampleValue): Errors.error => NotFinite(property(p), exampleValue) + let isEmptyError = (propertyName): Errors.error => IsEmpty(property(propertyName)) + let differentLengthsError = (t): Errors.error => DifferentLengths({ + fnName: fnName, + p1Name: "Xs", + p2Name: "Ys", + p1Length: E.A.length(T.xs(t)), + p2Length: E.A.length(T.ys(t)), + }) + + let areXsSorted = (t: t) => E.A.Floats.isSorted(T.xs(t)) + let areXsEmpty = (t: t) => E.A.length(t.xs) == 0 + let getNonFiniteXs = (t: t) => t->T.xs->E.A.Floats.getNonFinite + let getNonFiniteYs = (t: t) => t->T.ys->E.A.Floats.getNonFinite + + let validate = (t: t) => { + let xsNotSorted = areXsSorted(t) ? None : Some(notSortedError("Xs")) + let xsEmpty = areXsEmpty(t) ? None : Some(isEmptyError("Xs")) + let differentLengths = + E.A.length(T.xs(t)) !== E.A.length(T.ys(t)) ? Some(differentLengthsError(t)) : None + let xsNotFinite = getNonFiniteXs(t)->E.O2.fmap(notFiniteError("Xs")) + let ysNotFinite = getNonFiniteYs(t)->E.O2.fmap(notFiniteError("Ys")) + [xsNotSorted, xsEmpty, differentLengths, xsNotFinite, ysNotFinite] + ->E.A.O.concatSomes + ->Errors.mapErrorArrayToError } } From 5dd0292b52fb9cbabe22bd5e886b6c7dd40c321e Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 28 Apr 2022 14:52:44 -0400 Subject: [PATCH 033/146] Added tests for XYShape validator --- .../squiggle-lang/__tests__/XYShape_test.res | 28 ++++++--- .../squiggle-lang/src/rescript/Utility/E.res | 8 ++- .../src/rescript/Utility/Errors.res | 6 +- .../src/rescript/Utility/XYShape.res | 63 +++++++++---------- 4 files changed, 59 insertions(+), 46 deletions(-) diff --git a/packages/squiggle-lang/__tests__/XYShape_test.res b/packages/squiggle-lang/__tests__/XYShape_test.res index 701d82e1..9f5be4fd 100644 --- a/packages/squiggle-lang/__tests__/XYShape_test.res +++ b/packages/squiggle-lang/__tests__/XYShape_test.res @@ -19,6 +19,24 @@ let pointSetDist3: PointSetTypes.xyShape = { } describe("XYShapes", () => { + describe("Validator", () => { + makeTest("with no errors", XYShape.T.Validator.validate(pointSetDist1), None) + makeTest( + "when empty", + XYShape.T.Validator.validate({xs: [], ys: []})->E.O2.fmap(Errors.toString), + Some("XYShape validate Xs is empty"), + ) + makeTest( + "when not sorted, different lengths, and not finite", + XYShape.T.Validator.validate({xs: [2.0, 1.0, infinity, 0.0], ys: [3.0, infinity]})->E.O2.fmap( + Errors.toString, + ), + Some( + "Multiple Errors: [XYShape validate Xs is not sorted], [XYShape validate Xs and Ys have different lengths. Xs has length 4 and Ys has length 2], [XYShape validate Xs is not finite. Example value: Infinity], [XYShape validate Ys is not finite. Example value: Infinity]", + ), + ) + }) + describe("logScorePoint", () => { makeTest("When identical", XYShape.logScorePoint(30, pointSetDist1, pointSetDist1), Some(0.0)) makeTest( @@ -32,16 +50,6 @@ describe("XYShapes", () => { Some(210.3721280423322), ) }) - // describe("transverse", () => { - // makeTest( - // "When very different", - // XYShape.Transversal._transverse( - // (aCurrent, aLast) => aCurrent +. aLast, - // [|1.0, 2.0, 3.0, 4.0|], - // ), - // [|1.0, 3.0, 6.0, 10.0|], - // ) - // }); describe("integrateWithTriangles", () => makeTest( "integrates correctly", diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index af3d9f7f..aab3d160 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -500,7 +500,11 @@ module A = { let getBelowZero = (t: t) => Belt.Array.getBy(t, r => r < 0.0) let isSorted = (t: t): bool => - reduce(zip(t, tail(t)), true, (acc, (first, second)) => acc && first < second) + if Array.length(t) < 1 { + true + } else { + reduce(zip(t, tail(t)), true, (acc, (first, second)) => acc && first < second) + } //Passing true for the exclusive parameter excludes both endpoints of the range. //https://jstat.github.io/all.html @@ -618,7 +622,7 @@ module A = { module A2 = { let fmap = (a, b) => A.fmap(b, a) let joinWith = (a, b) => A.joinWith(b, a) - let filter = (a,b) => A.filter(b, a) + let filter = (a, b) => A.filter(b, a) } module JsArray = { diff --git a/packages/squiggle-lang/src/rescript/Utility/Errors.res b/packages/squiggle-lang/src/rescript/Utility/Errors.res index 6f52b21c..bdd41869 100644 --- a/packages/squiggle-lang/src/rescript/Utility/Errors.res +++ b/packages/squiggle-lang/src/rescript/Utility/Errors.res @@ -20,10 +20,12 @@ let rec toString = (t: error) => | NotSorted({fnName, propertyName}) => `${fnName} ${propertyName} is not sorted` | IsEmpty({fnName, propertyName}) => `${fnName} ${propertyName} is empty` | NotFinite({fnName, propertyName}, exampleValue) => - `${fnName} ${propertyName} is not finite. Example value: ${E.Float.toString(exampleValue)}` + `${fnName} ${propertyName} is not finite. Example value: ${E.Float.toString(exampleValue)}` | DifferentLengths({fnName, p1Name, p2Name, p1Length, p2Length}) => `${fnName} ${p1Name} and ${p2Name} have different lengths. ${p1Name} has length ${E.I.toString( p1Length, )} and ${p2Name} has length ${E.I.toString(p2Length)}` - | Multiple(errors) => `Multiple Errors: ${E.A2.fmap(errors, toString) |> E.A.joinWith(", ")}` + | Multiple(errors) => + `Multiple Errors: ${E.A2.fmap(errors, toString)->E.A2.fmap(r => `[${r}]`) + |> E.A.joinWith(", ")}` } diff --git a/packages/squiggle-lang/src/rescript/Utility/XYShape.res b/packages/squiggle-lang/src/rescript/Utility/XYShape.res index 9368c1ee..1d96a3ee 100644 --- a/packages/squiggle-lang/src/rescript/Utility/XYShape.res +++ b/packages/squiggle-lang/src/rescript/Utility/XYShape.res @@ -60,41 +60,40 @@ module T = { let fromZippedArray = (pairs: array<(float, float)>): t => pairs |> Belt.Array.unzip |> fromArray let equallyDividedXs = (t: t, newLength) => E.A.Floats.range(minX(t), maxX(t), newLength) let toJs = (t: t) => {"xs": t.xs, "ys": t.ys} -} -module Validator = { - type t = T.t - let fnName = "XYShape validate" - let property = (propertyName: string): Errors.property => { - fnName: fnName, - propertyName: propertyName, - } - let notSortedError = (p: string): Errors.error => NotSorted(property(p)) - let notFiniteError = (p, exampleValue): Errors.error => NotFinite(property(p), exampleValue) - let isEmptyError = (propertyName): Errors.error => IsEmpty(property(propertyName)) - let differentLengthsError = (t): Errors.error => DifferentLengths({ - fnName: fnName, - p1Name: "Xs", - p2Name: "Ys", - p1Length: E.A.length(T.xs(t)), - p2Length: E.A.length(T.ys(t)), - }) + module Validator = { + let fnName = "XYShape validate" + let property = (propertyName: string): Errors.property => { + fnName: fnName, + propertyName: propertyName, + } + let notSortedError = (p: string): Errors.error => NotSorted(property(p)) + let notFiniteError = (p, exampleValue): Errors.error => NotFinite(property(p), exampleValue) + let isEmptyError = (propertyName): Errors.error => IsEmpty(property(propertyName)) + let differentLengthsError = (t): Errors.error => DifferentLengths({ + fnName: fnName, + p1Name: "Xs", + p2Name: "Ys", + p1Length: E.A.length(xs(t)), + p2Length: E.A.length(ys(t)), + }) - let areXsSorted = (t: t) => E.A.Floats.isSorted(T.xs(t)) - let areXsEmpty = (t: t) => E.A.length(t.xs) == 0 - let getNonFiniteXs = (t: t) => t->T.xs->E.A.Floats.getNonFinite - let getNonFiniteYs = (t: t) => t->T.ys->E.A.Floats.getNonFinite + let areXsSorted = (t: t) => E.A.Floats.isSorted(xs(t)) + let areXsEmpty = (t: t) => E.A.length(xs(t)) == 0 + let getNonFiniteXs = (t: t) => t->xs->E.A.Floats.getNonFinite + let getNonFiniteYs = (t: t) => t->ys->E.A.Floats.getNonFinite - let validate = (t: t) => { - let xsNotSorted = areXsSorted(t) ? None : Some(notSortedError("Xs")) - let xsEmpty = areXsEmpty(t) ? None : Some(isEmptyError("Xs")) - let differentLengths = - E.A.length(T.xs(t)) !== E.A.length(T.ys(t)) ? Some(differentLengthsError(t)) : None - let xsNotFinite = getNonFiniteXs(t)->E.O2.fmap(notFiniteError("Xs")) - let ysNotFinite = getNonFiniteYs(t)->E.O2.fmap(notFiniteError("Ys")) - [xsNotSorted, xsEmpty, differentLengths, xsNotFinite, ysNotFinite] - ->E.A.O.concatSomes - ->Errors.mapErrorArrayToError + let validate = (t: t) => { + let xsNotSorted = areXsSorted(t) ? None : Some(notSortedError("Xs")) + let xsEmpty = areXsEmpty(t) ? Some(isEmptyError("Xs")) : None + let differentLengths = + E.A.length(xs(t)) !== E.A.length(ys(t)) ? Some(differentLengthsError(t)) : None + let xsNotFinite = getNonFiniteXs(t)->E.O2.fmap(notFiniteError("Xs")) + let ysNotFinite = getNonFiniteYs(t)->E.O2.fmap(notFiniteError("Ys")) + [xsNotSorted, xsEmpty, differentLengths, xsNotFinite, ysNotFinite] + ->E.A.O.concatSomes + ->Errors.mapErrorArrayToError + } } } From 00f862725cdac0083a6130620ba8605eabf92b8f Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Thu, 28 Apr 2022 18:59:15 +0000 Subject: [PATCH 034/146] Add Dictionary Viewer and Recursive Array viewer --- .../src/components/SquiggleChart.tsx | 13 ++ packages/squiggle-lang/src/js/index.ts | 148 +++++++++++++++++- 2 files changed, 158 insertions(+), 3 deletions(-) diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 534d164d..7dda92e4 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -44,6 +44,8 @@ export const VariableBox: React.FC<{ ); }; +let RecordKeyHeader = styled.h3``; + export interface SquiggleItemProps { /** The input string for squiggle */ expression: squiggleExpression; @@ -104,6 +106,17 @@ const SquiggleItem: React.FC = ({ ))} ); + case "record": + return ( + + {Object.entries(expression.value).map(([key, r]) => ( + <> + {key} + + + ))} + + ); default: return ( diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 6ff022e0..57c09e1a 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -50,6 +50,67 @@ export let defaultSamplingInputs: samplingParams = { xyPointLength: 10000, }; +import type { t as SampleSetDist_t } from "../rescript/Distributions/SampleSetDist/SampleSetDist.gen"; +import type { mixedShape } from "../rescript/Distributions/PointSetDist/PointSetTypes.gen"; + +import type { symbolicDist as SymbolicDistTypes_symbolicDist } from "../rescript/Distributions/SymbolicDist/SymbolicDistTypes.gen"; + +type rescriptPointSetDist = + | { + TAG: 0; // Mixed + _0: mixedShape; + } + | { + TAG: 1; // Discrete + _0: discreteShape; + } + | { + TAG: 2; // ContinuousShape + _0: continuousShape; + }; + +type rescriptDist = + | { TAG: 0; _0: rescriptPointSetDist } + | { TAG: 1; _0: SampleSetDist_t } + | { TAG: 2; _0: SymbolicDistTypes_symbolicDist }; + +// This is a raw rescript export. genType for some reason only converts half +// the data structure into the format it claims it is. This here is so that +// we can be guided in converting the other half +type rescriptExport = + | { + TAG: 0; // EvArray + _0: rescriptExport[]; + } + | { + TAG: 1; // EvBool + _0: boolean; + } + | { + TAG: 2; // EvCall + _0: string; + } + | { + TAG: 3; // EvDistribution + _0: rescriptDist; + } + | { + TAG: 4; // EvNumber + _0: number; + } + | { + TAG: 5; // EvRecord + _0: { [key: string]: rescriptExport }; + } + | { + TAG: 6; // EvString + _0: string; + } + | { + TAG: 7; // EvSymbol + _0: string; + }; + export type result = | { tag: "Ok"; @@ -90,6 +151,7 @@ export type squiggleExpression = | tagged<"distribution", Distribution> | tagged<"number", number> | tagged<"record", { [key: string]: squiggleExpression }>; + export function run( squiggleString: string, samplingInputs?: samplingParams @@ -101,6 +163,63 @@ export function run( return resultMap(result, (x) => createTsExport(x, si)); } +// Recript half converts recursive data structures +function convertRawToTypescript( + result: rescriptExport, + sampEnv: samplingParams +): squiggleExpression { + switch (result.TAG) { + case 0: // EvArray + return tag( + "array", + result._0.map((x) => convertRawToTypescript(x, sampEnv)) + ); + case 1: // EvBool + return tag("boolean", result._0); + case 2: // EvCall + return tag("call", result._0); + case 3: // EvDistribution + return tag( + "distribution", + new Distribution( + convertRawDistributionToGenericDist(result._0), + sampEnv + ) + ); + case 4: // EvNumber + return tag("number", result._0); + case 5: // EvRecord + return tag( + "record", + _.mapValues(result._0, (x) => convertRawToTypescript(x, sampEnv)) + ); + case 6: // EvString + return tag("string", result._0); + case 7: // EvSymbol + return tag("symbol", result._0); + } +} + +function convertRawDistributionToGenericDist( + result: rescriptDist +): genericDist { + switch (result.TAG) { + case 0: // Point Set Dist + switch (result._0.TAG) { + case 0: // Mixed + return tag("PointSet", tag("Mixed", result._0._0)); + case 1: // Discrete + return tag("PointSet", tag("Discrete", result._0._0)); + case 2: // Continuous + return tag("PointSet", tag("Continuous", result._0._0)); + } + case 1: // Sample Set Dist + return tag("SampleSet", result._0); + case 2: // Symbolic Dist + return tag("Symbolic", result._0); + } +} + function createTsExport( x: expressionValue, sampEnv: samplingParams @@ -109,7 +228,27 @@ function createTsExport( case "EvArray": return tag( "array", - x.value.map((x) => createTsExport(x, sampEnv)) + x.value.map((arrayItem): squiggleExpression => { + switch (arrayItem.tag) { + case "EvRecord": + return tag( + "record", + _.mapValues(arrayItem.value, (recordValue: unknown) => + convertRawToTypescript(recordValue as rescriptExport, sampEnv) + ) + ); + case "EvArray": + let y = arrayItem.value as unknown as rescriptExport[]; + return tag( + "array", + y.map((childArrayItem) => + convertRawToTypescript(childArrayItem, sampEnv) + ) + ); + default: + return createTsExport(arrayItem, sampEnv); + } + }) ); case "EvBool": return tag("boolean", x.value); @@ -120,10 +259,13 @@ function createTsExport( case "EvNumber": return tag("number", x.value); case "EvRecord": - return tag( + let result: tagged<"record", { [key: string]: squiggleExpression }> = tag( "record", - _.mapValues(x.value, (x) => createTsExport(x, sampEnv)) + _.mapValues(x.value, (x: unknown) => + convertRawToTypescript(x as rescriptExport, sampEnv) + ) ); + return result; case "EvString": return tag("string", x.value); case "EvSymbol": From 95a4bac49bf19801b9e3bed690e9b88c847ab427 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 28 Apr 2022 15:01:57 -0400 Subject: [PATCH 035/146] Added NaN to test to make sure its caught --- packages/squiggle-lang/__tests__/XYShape_test.res | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/__tests__/XYShape_test.res b/packages/squiggle-lang/__tests__/XYShape_test.res index 9f5be4fd..c63e1ce2 100644 --- a/packages/squiggle-lang/__tests__/XYShape_test.res +++ b/packages/squiggle-lang/__tests__/XYShape_test.res @@ -28,11 +28,11 @@ describe("XYShapes", () => { ) makeTest( "when not sorted, different lengths, and not finite", - XYShape.T.Validator.validate({xs: [2.0, 1.0, infinity, 0.0], ys: [3.0, infinity]})->E.O2.fmap( + XYShape.T.Validator.validate({xs: [2.0, 1.0, infinity, 0.0], ys: [3.0, Js.Float._NaN]})->E.O2.fmap( Errors.toString, ), Some( - "Multiple Errors: [XYShape validate Xs is not sorted], [XYShape validate Xs and Ys have different lengths. Xs has length 4 and Ys has length 2], [XYShape validate Xs is not finite. Example value: Infinity], [XYShape validate Ys is not finite. Example value: Infinity]", + "Multiple Errors: [XYShape validate Xs is not sorted], [XYShape validate Xs and Ys have different lengths. Xs has length 4 and Ys has length 2], [XYShape validate Xs is not finite. Example value: Infinity], [XYShape validate Ys is not finite. Example value: NaN]", ), ) }) From 44215f540f4e3512392859394d671275d36d712a Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Thu, 28 Apr 2022 15:20:58 -0400 Subject: [PATCH 036/146] v0.2.6: packaging fixed Value: [1e-1 to 8e-1] --- packages/squiggle-lang/.npmignore | 1 - packages/squiggle-lang/package.json | 16 +++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/squiggle-lang/.npmignore b/packages/squiggle-lang/.npmignore index bfbe051d..2d3f13c3 100644 --- a/packages/squiggle-lang/.npmignore +++ b/packages/squiggle-lang/.npmignore @@ -2,7 +2,6 @@ node_modules shell.nix .cache .direnv -src __tests__ lib examples diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 75583bfc..a2a79a4f 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -1,10 +1,10 @@ { "name": "@quri/squiggle-lang", - "version": "0.2.5", + "version": "0.2.6", "homepage": "https://squiggle-language.com", "licence": "MIT", "scripts": { - "build": "rescript build -with-deps", + "build": "rescript build -with-deps && tsc", "bundle": "webpack", "start": "rescript build -w -with-deps", "clean": "rescript clean", @@ -31,11 +31,15 @@ ], "author": "Quantified Uncertainty Research Institute", "license": "MIT", + "dependencies": { + "rescript": "^9.1.4", + "jstat": "^1.9.5", + "pdfast": "^0.2.0", + "mathjs": "10.5.0" + }, "devDependencies": { "bisect_ppx": "^2.7.1", - "jstat": "^1.9.5", "lodash": "4.17.21", - "rescript": "^9.1.4", "rescript-fast-check": "^1.1.1", "@glennsl/rescript-jest": "^0.9.0", "@istanbuljs/nyc-config-typescript": "^1.0.2", @@ -46,10 +50,8 @@ "fast-check": "2.25.0", "gentype": "^4.3.0", "jest": "^27.5.1", - "mathjs": "10.5.0", "moduleserve": "0.9.1", "nyc": "^15.1.0", - "pdfast": "^0.2.0", "reanalyze": "^2.19.0", "ts-jest": "^27.1.4", "ts-loader": "^9.2.8", @@ -59,6 +61,6 @@ "webpack-cli": "^4.9.2" }, "source": "./src/js/index.ts", - "main": "./dist/bundle.js", + "main": "./dist/src/js/index.js", "types": "./dist/js/index.d.ts" } From e499c1a887299a0e7ba94fefb9af1820642b3cc2 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Thu, 28 Apr 2022 20:16:31 +0000 Subject: [PATCH 037/146] Add tests for deeply nested and records --- .../squiggle-lang/__tests__/TS/JS_test.ts | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/packages/squiggle-lang/__tests__/TS/JS_test.ts b/packages/squiggle-lang/__tests__/TS/JS_test.ts index 1974dee6..43f981eb 100644 --- a/packages/squiggle-lang/__tests__/TS/JS_test.ts +++ b/packages/squiggle-lang/__tests__/TS/JS_test.ts @@ -42,6 +42,39 @@ describe("Log function", () => { }); }); +describe("Array", () => { + test("nested Array", () => { + expect(testRun("[[1]]")).toEqual({ + tag: "array", + value: [ + { + tag: "array", + value: [ + { + tag: "number", + value: 1, + }, + ], + }, + ], + }); + }); +}); + +describe("Record", () => { + test("Return record", () => { + expect(testRun("{a: 1}")).toEqual({ + tag: "record", + value: { + a: { + tag: "number", + value: 1, + }, + }, + }); + }); +}); + describe("Distribution", () => { //It's important that sampleCount is less than 9. If it's more, than that will create randomness //Also, note, the value should be created using makeSampleSetDist() later on. From de8eb76f4e84c5a84443fd984f884f43f9cfe839 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Thu, 28 Apr 2022 16:19:40 -0400 Subject: [PATCH 038/146] v0.2.13: packaging works Value: [2e-1 to 8e-1] --- packages/components/package.json | 23 +- packages/squiggle-lang/package.json | 2 +- yarn.lock | 909 ++++++++++++++++------------ 3 files changed, 551 insertions(+), 383 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index d895d545..5d21b9cc 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,12 +1,19 @@ { "name": "@quri/squiggle-components", - "version": "0.2.9", - "licence": "MIT", + "version": "0.2.13", + "license": "MIT", "dependencies": { "antd": "^4.20.1", "react-ace": "10.1.0", + "@quri/squiggle-lang": "0.2.6", "react-dom": "^18.1.0", + "vega": "^5.22.1", + "vega-embed": "^6.20.6", + "vega-lite": "^5.2.0", + "react-vega": "^7.5.0", + "react": "^18.1.0", "@react-hook/size": "^2.1.2", + "lodash": "^4.17.21", "styled-components": "^5.3.5" }, "devDependencies": { @@ -26,31 +33,25 @@ "webpack": "^5.72.0", "webpack-cli": "^4.9.2", "webpack-dev-server": "^4.8.1", - "@quri/squiggle-lang": "0.2.5", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.1.1", "@testing-library/user-event": "^14.1.1", "@types/jest": "^27.4.0", + "web-vitals": "^2.1.4", "@types/lodash": "^4.14.182", "@types/node": "^17.0.29", "@types/react": "^18.0.3", "@types/react-dom": "^18.0.2", "cross-env": "^7.0.3", - "lodash": "^4.17.21", - "react": "^18.1.0", "react-scripts": "5.0.1", - "react-vega": "^7.5.0", "tsconfig-paths-webpack-plugin": "^3.5.2", "typescript": "^4.6.3", - "vega": "^5.22.1", - "vega-embed": "^6.20.6", - "vega-lite": "^5.2.0", - "web-vitals": "^2.1.4", "webpack-cli": "^4.9.2" }, "scripts": { "start": "cross-env REACT_APP_FAST_REFRESH=false && start-storybook -p 6006 -s public", "build": "tsc -b && build-storybook -s public", + "build:package": "tsc -b", "bundle": "webpack", "all": "yarn bundle && yarn build", "lint": "prettier --check .", @@ -88,6 +89,6 @@ "@types/react": "17.0.43" }, "source": "./src/index.ts", - "main": "dist/bundle.js", + "main": "dist/src/index.js", "types": "dist/src/index.d.ts" } diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index a2a79a4f..f5002481 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -7,7 +7,7 @@ "build": "rescript build -with-deps && tsc", "bundle": "webpack", "start": "rescript build -w -with-deps", - "clean": "rescript clean", + "clean": "rescript clean && rm -r dist", "test:reducer": "jest __tests__/Reducer*/", "benchmark": "ts-node benchmark/conversion_tests.ts", "test": "jest", diff --git a/yarn.lock b/yarn.lock index 283b1121..4ce8009f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -131,11 +131,12 @@ "@algolia/requester-common" "4.13.0" "@ampproject/remapping@^2.1.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" - integrity sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg== + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== dependencies: - "@jridgewell/trace-mapping" "^0.3.0" + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" "@ant-design/colors@^6.0.0": version "6.0.0" @@ -1351,7 +1352,7 @@ resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-12.0.0.tgz#a9583a75c3f150667771f30b60d9f059473e62c4" integrity sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg== -"@csstools/postcss-color-function@^1.0.3": +"@csstools/postcss-color-function@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-1.1.0.tgz#229966327747f58fbe586de35daa139db3ce1e5d" integrity sha512-5D5ND/mZWcQoSfYnSPsXtuiFxhzmhxt6pcjrFLJyldj+p0ZN2vvRpYNX+lahFTtMhAYOa2WmkdGINr0yP0CvGA== @@ -1381,7 +1382,7 @@ "@csstools/postcss-progressive-custom-properties" "^1.1.0" postcss-value-parser "^4.2.0" -"@csstools/postcss-is-pseudo-class@^2.0.1": +"@csstools/postcss-is-pseudo-class@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.2.tgz#a834ca11a43d6ed9bc9e3ff53c80d490a4b1aaad" integrity sha512-L9h1yxXMj7KpgNzlMrw3isvHJYkikZgZE4ASwssTnGEH8tm50L6QsM9QQT5wR4/eO5mU0rN5axH7UzNxEYg5CA== @@ -1395,7 +1396,7 @@ dependencies: postcss-value-parser "^4.2.0" -"@csstools/postcss-oklab-function@^1.0.2": +"@csstools/postcss-oklab-function@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.0.tgz#e9a269487a292e0930760948e923e1d46b638ee6" integrity sha512-e/Q5HopQzmnQgqimG9v3w2IG4VRABsBq3itOcn4bnm+j4enTgQZ0nWsaH/m9GV2otWGQ0nwccYL5vmLKyvP1ww== @@ -1920,10 +1921,10 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== -"@eslint/eslintrc@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6" - integrity sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ== +"@eslint/eslintrc@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.2.tgz#4989b9e8c0216747ee7cca314ae73791bb281aae" + integrity sha512-lTVWHs7O2hjBFZunXTZYnYqtB9GakA1lnxIf+gKq2nY5gxkkNi/lQvveW6t8gFdOHTg6nG50Xs95PrLqVpcaLg== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -1992,7 +1993,7 @@ dependencies: "@istanbuljs/schema" "^0.1.2" -"@istanbuljs/schema@^0.1.2": +"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": version "0.1.3" resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== @@ -2009,6 +2010,18 @@ jest-util "^27.5.1" slash "^3.0.0" +"@jest/console@^28.0.2": + version "28.0.2" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.0.2.tgz#d11e8b43ae431ae9b3112656848417ae4008fcad" + integrity sha512-tiRpnMeeyQuuzgL5UNSeiqMwF8UOWPbAE5rzcu/1zyq4oPG2Ox6xm4YCOruwbp10F8odWc+XwVxTyGzMSLMqxA== + dependencies: + "@jest/types" "^28.0.2" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^28.0.2" + jest-util "^28.0.2" + slash "^3.0.0" + "@jest/core@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" @@ -2105,6 +2118,13 @@ terminal-link "^2.0.0" v8-to-istanbul "^8.1.0" +"@jest/schemas@^28.0.2": + version "28.0.2" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.0.2.tgz#08c30df6a8d07eafea0aef9fb222c5e26d72e613" + integrity sha512-YVDJZjd4izeTDkij00vHHAymNXQ6WWsdChFRK86qck6Jpr3DCL5W3Is3vslviRlP+bLuMYRLbdp98amMvqudhA== + dependencies: + "@sinclair/typebox" "^0.23.3" + "@jest/source-map@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" @@ -2124,6 +2144,16 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" +"@jest/test-result@^28.0.2": + version "28.0.2" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.0.2.tgz#bc8e15a95347e3c2149572ae06a5a6fed939c522" + integrity sha512-4EUqgjq9VzyUiVTvZfI9IRJD6t3NYBNP4f+Eq8Zr93+hkJ0RrGU4OBTw8tfNzidKX+bmuYzn8FxqpxOPIGGCMA== + dependencies: + "@jest/console" "^28.0.2" + "@jest/types" "^28.0.2" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + "@jest/test-sequencer@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" @@ -2198,20 +2228,45 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" +"@jest/types@^28.0.2": + version "28.0.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.0.2.tgz#70b9538c1863fb060b2f438ca008b5563d00c5b4" + integrity sha512-hi3jUdm9iht7I2yrV5C4s3ucCJHUP8Eh3W6rQ1s4n/Qw9rQgsda4eqCt+r3BKRi7klVmZfQlMx1nGlzNMP2d8A== + dependencies: + "@jest/schemas" "^28.0.2" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/resolve-uri@^3.0.3": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" - integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew== + version "3.0.6" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.6.tgz#4ac237f4dabc8dd93330386907b97591801f7352" + integrity sha512-R7xHtBSNm+9SyvpJkdQl+qrM3Hm2fea3Ef197M3mUug+v+yR+Rhfbs7PBtcBUVnIWJ4JcAdjvij+c8hXS9p5aw== + +"@jridgewell/set-array@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.0.tgz#1179863356ac8fbea64a5a4bcde93a4871012c01" + integrity sha512-SfJxIxNVYLTsKwzB3MoOQ1yxf4w/E6MdkvTgrgAt1bfxjSrLUoHMKrDOykwN14q65waezZIdqDneUIPh4/sKxg== "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.11" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== -"@jridgewell/trace-mapping@^0.3.0": - version "0.3.4" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" - integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== +"@jridgewell/trace-mapping@^0.3.7", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== dependencies: "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" @@ -2345,6 +2400,19 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64" integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw== +"@quri/squiggle-lang@0.2.5": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@quri/squiggle-lang/-/squiggle-lang-0.2.5.tgz#368f0644290a0265696db7547ea31b0a0b55a69e" + integrity sha512-yBCqjieirDE4oDZVICGQh2r1A6vS6GM5y8Pc0IhHGnNBbs230iA/b+eytQTGbEE7yVEvHbDNBUoiB+B7sCPzaQ== + dependencies: + bisect_ppx "^2.7.1" + jstat "^1.9.5" + lodash "4.17.21" + mathjs "10.5.0" + pdfast "^0.2.0" + rationale "0.2.0" + rescript "^9.1.4" + "@react-hook/latest@^1.0.2": version "1.0.3" resolved "https://registry.yarnpkg.com/@react-hook/latest/-/latest-1.0.3.tgz#c2d1d0b0af8b69ec6e2b3a2412ba0768ac82db80" @@ -2412,9 +2480,9 @@ picomatch "^2.2.2" "@rushstack/eslint-patch@^1.1.0": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.2.tgz#7a26e63b1bdaf654bcce2176a38b83f7f576327e" - integrity sha512-oe5WJEDaVsW8fBlGT7udrSCgOwWfoYHQOmSpnh8X+0GXpqqcRCP8k4y+Dxb0taWJDPpB+rdDUtumIiBwkY9qGA== + version "1.1.3" + resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.3.tgz#6801033be7ff87a6b7cadaf5b337c9f366a3c4b0" + integrity sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw== "@ryyppy/rescript-promise@^2.1.0": version "2.1.0" @@ -2438,6 +2506,11 @@ resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== +"@sinclair/typebox@^0.23.3": + version "0.23.4" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.23.4.tgz#6ff93fd2585ce44f7481c9ff6af610fbb5de98a4" + integrity sha512-0/WqSvpVbCBAV1yPeko7eAczKbs78dNVAaX14quVlwOb2wxfKuXCx91h4NrEfkYK9zEnyVSW4JVI/trP3iS+Qg== + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -3758,9 +3831,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.17.0.tgz#7a9b80f712fe2052bc20da153ff1e552404d8e4b" - integrity sha512-r8aveDbd+rzGP+ykSdF3oPuTVRWRfbBiHl0rVDM2yNEmSMXfkObQLV46b4RnCv3Lra51OlfnZhkkFaDl2MIRaA== + version "7.17.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.17.1.tgz#1a0e73e8c28c7e832656db372b779bfd2ef37314" + integrity sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA== dependencies: "@babel/types" "^7.3.0" @@ -4004,9 +4077,9 @@ integrity sha512-tx5jMmMFwx7wBwq/V7OohKDVb/JwJU5qCVkeLMh1//xycAJ/ESuw9aJ9SEtlCZDYi2pBfe4JkisSoAtbOsBNAA== "@types/node@^14.0.10": - version "14.18.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.13.tgz#6ad4d9db59e6b3faf98dcfe4ca9d2aec84443277" - integrity sha512-Z6/KzgyWOga3pJNS42A+zayjhPbf2zM3hegRQaOPnLOzEi86VV++6FLDWgR1LGrVCRufP/ph2daa3tEa5br1zA== + version "14.18.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.16.tgz#878f670ba3f00482bf859b6550b6010610fc54b5" + integrity sha512-X3bUMdK/VmvrWdoTkz+VCn6nwKwrKCFTHtqwBIaQJNx4RUIBBUFXM00bqPz/DsDd+Icjmzm6/tyYZzeGVqb6/Q== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -4131,10 +4204,10 @@ dependencies: "@types/node" "*" -"@types/retry@^0.12.0": - version "0.12.1" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" - integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== "@types/sax@^1.2.1": version "1.2.4" @@ -4219,9 +4292,9 @@ integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== "@types/webpack-env@^1.16.0": - version "1.16.3" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.3.tgz#b776327a73e561b71e7881d0cd6d34a1424db86a" - integrity sha512-9gtOPPkfyNoEqCQgx4qJKkuNm/x0R2hKR7fdl7zvTJyHnIisuE/LfvXOsYWL0o3qq6uiBnKZNNNzi3l0y/X+xw== + version "1.16.4" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.4.tgz#1f4969042bf76d7ef7b5914f59b3b60073f4e1f4" + integrity sha512-llS8qveOUX3wxHnSykP5hlYFFuMfJ9p5JvIyCiBgp7WTfl6K5ZcyHj8r8JsN/J6QODkAsRRCLIcTuOCu8etkUw== "@types/webpack-sources@*": version "3.2.0" @@ -4279,14 +4352,21 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^5.5.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.19.0.tgz#9608a4b6d0427104bccf132f058cba629a6553c0" - integrity sha512-w59GpFqDYGnWFim9p6TGJz7a3qWeENJuAKCqjGSx+Hq/bwq3RZwXYqy98KIfN85yDqz9mq6QXiY5h0FjGQLyEg== +"@types/yargs@^17.0.8": + version "17.0.10" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.10.tgz#591522fce85d8739bca7b8bb90d048e4478d186a" + integrity sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA== dependencies: - "@typescript-eslint/scope-manager" "5.19.0" - "@typescript-eslint/type-utils" "5.19.0" - "@typescript-eslint/utils" "5.19.0" + "@types/yargs-parser" "*" + +"@typescript-eslint/eslint-plugin@^5.5.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.21.0.tgz#bfc22e0191e6404ab1192973b3b4ea0461c1e878" + integrity sha512-fTU85q8v5ZLpoZEyn/u1S2qrFOhi33Edo2CZ0+q1gDaWWm0JuPh3bgOyU8lM0edIEYgKLDkPFiZX2MOupgjlyg== + dependencies: + "@typescript-eslint/scope-manager" "5.21.0" + "@typescript-eslint/type-utils" "5.21.0" + "@typescript-eslint/utils" "5.21.0" debug "^4.3.2" functional-red-black-tree "^1.0.1" ignore "^5.1.8" @@ -4295,75 +4375,75 @@ tsutils "^3.21.0" "@typescript-eslint/experimental-utils@^5.0.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.19.0.tgz#b7c8f1e22624d4f3d1b3683438530f5636086cb7" - integrity sha512-F+X/TTzmb2UXbghY1LrNLNDjMcGZMhKzXuzvu0xD+YEB77EamLM7zMOLuz2kP5807IJRDLBoAFFPYa7HT62sYg== + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.21.0.tgz#489275ca792f5de7e0d1f4be1f15576ea56b6ca2" + integrity sha512-mzF6ert/6iQoESV0z9v5/mEaJRKL4fv68rHoZ6exM38xjxkw4MNx54B7ferrnMTM/GIRKLDaJ3JPRi+Dxa5Hlg== dependencies: - "@typescript-eslint/utils" "5.19.0" + "@typescript-eslint/utils" "5.21.0" "@typescript-eslint/parser@^5.5.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.19.0.tgz#05e587c1492868929b931afa0cb5579b0f728e75" - integrity sha512-yhktJjMCJX8BSBczh1F/uY8wGRYrBeyn84kH6oyqdIJwTGKmzX5Qiq49LRQ0Jh0LXnWijEziSo6BRqny8nqLVQ== + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.21.0.tgz#6cb72673dbf3e1905b9c432175a3c86cdaf2071f" + integrity sha512-8RUwTO77hstXUr3pZoWZbRQUxXcSXafZ8/5gpnQCfXvgmP9gpNlRGlWzvfbEQ14TLjmtU8eGnONkff8U2ui2Eg== dependencies: - "@typescript-eslint/scope-manager" "5.19.0" - "@typescript-eslint/types" "5.19.0" - "@typescript-eslint/typescript-estree" "5.19.0" + "@typescript-eslint/scope-manager" "5.21.0" + "@typescript-eslint/types" "5.21.0" + "@typescript-eslint/typescript-estree" "5.21.0" debug "^4.3.2" -"@typescript-eslint/scope-manager@5.19.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.19.0.tgz#97e59b0bcbcb54dbcdfba96fc103b9020bbe9cb4" - integrity sha512-Fz+VrjLmwq5fbQn5W7cIJZ066HxLMKvDEmf4eu1tZ8O956aoX45jAuBB76miAECMTODyUxH61AQM7q4/GOMQ5g== +"@typescript-eslint/scope-manager@5.21.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.21.0.tgz#a4b7ed1618f09f95e3d17d1c0ff7a341dac7862e" + integrity sha512-XTX0g0IhvzcH/e3393SvjRCfYQxgxtYzL3UREteUneo72EFlt7UNoiYnikUtmGVobTbhUDByhJ4xRBNe+34kOQ== dependencies: - "@typescript-eslint/types" "5.19.0" - "@typescript-eslint/visitor-keys" "5.19.0" + "@typescript-eslint/types" "5.21.0" + "@typescript-eslint/visitor-keys" "5.21.0" -"@typescript-eslint/type-utils@5.19.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.19.0.tgz#80f2125b0dfe82494bbae1ea99f1c0186d420282" - integrity sha512-O6XQ4RI4rQcBGshTQAYBUIGsKqrKeuIOz9v8bckXZnSeXjn/1+BDZndHLe10UplQeJLXDNbaZYrAytKNQO2T4Q== +"@typescript-eslint/type-utils@5.21.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.21.0.tgz#ff89668786ad596d904c21b215e5285da1b6262e" + integrity sha512-MxmLZj0tkGlkcZCSE17ORaHl8Th3JQwBzyXL/uvC6sNmu128LsgjTX0NIzy+wdH2J7Pd02GN8FaoudJntFvSOw== dependencies: - "@typescript-eslint/utils" "5.19.0" + "@typescript-eslint/utils" "5.21.0" debug "^4.3.2" tsutils "^3.21.0" -"@typescript-eslint/types@5.19.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.19.0.tgz#12d3d600d754259da771806ee8b2c842d3be8d12" - integrity sha512-zR1ithF4Iyq1wLwkDcT+qFnhs8L5VUtjgac212ftiOP/ZZUOCuuF2DeGiZZGQXGoHA50OreZqLH5NjDcDqn34w== +"@typescript-eslint/types@5.21.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.21.0.tgz#8cdb9253c0dfce3f2ab655b9d36c03f72e684017" + integrity sha512-XnOOo5Wc2cBlq8Lh5WNvAgHzpjnEzxn4CJBwGkcau7b/tZ556qrWXQz4DJyChYg8JZAD06kczrdgFPpEQZfDsA== -"@typescript-eslint/typescript-estree@5.19.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.19.0.tgz#fc987b8f62883f9ea6a5b488bdbcd20d33c0025f" - integrity sha512-dRPuD4ocXdaE1BM/dNR21elSEUPKaWgowCA0bqJ6YbYkvtrPVEvZ+zqcX5a8ECYn3q5iBSSUcBBD42ubaOp0Hw== +"@typescript-eslint/typescript-estree@5.21.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.21.0.tgz#9f0c233e28be2540eaed3df050f0d54fb5aa52de" + integrity sha512-Y8Y2T2FNvm08qlcoSMoNchh9y2Uj3QmjtwNMdRQkcFG7Muz//wfJBGBxh8R7HAGQFpgYpdHqUpEoPQk+q9Kjfg== dependencies: - "@typescript-eslint/types" "5.19.0" - "@typescript-eslint/visitor-keys" "5.19.0" + "@typescript-eslint/types" "5.21.0" + "@typescript-eslint/visitor-keys" "5.21.0" debug "^4.3.2" globby "^11.0.4" is-glob "^4.0.3" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/utils@5.19.0", "@typescript-eslint/utils@^5.13.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.19.0.tgz#fe87f1e3003d9973ec361ed10d36b4342f1ded1e" - integrity sha512-ZuEckdupXpXamKvFz/Ql8YnePh2ZWcwz7APICzJL985Rp5C2AYcHO62oJzIqNhAMtMK6XvrlBTZeNG8n7gS3lQ== +"@typescript-eslint/utils@5.21.0", "@typescript-eslint/utils@^5.13.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.21.0.tgz#51d7886a6f0575e23706e5548c7e87bce42d7c18" + integrity sha512-q/emogbND9wry7zxy7VYri+7ydawo2HDZhRZ5k6yggIvXa7PvBbAAZ4PFH/oZLem72ezC4Pr63rJvDK/sTlL8Q== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.19.0" - "@typescript-eslint/types" "5.19.0" - "@typescript-eslint/typescript-estree" "5.19.0" + "@typescript-eslint/scope-manager" "5.21.0" + "@typescript-eslint/types" "5.21.0" + "@typescript-eslint/typescript-estree" "5.21.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/visitor-keys@5.19.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.19.0.tgz#c84ebc7f6c744707a361ca5ec7f7f64cd85b8af6" - integrity sha512-Ym7zZoMDZcAKWsULi2s7UMLREdVQdScPQ/fKWMYefarCztWlHPFVJo8racf8R0Gc8FAEJ2eD4of8As1oFtnQlQ== +"@typescript-eslint/visitor-keys@5.21.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.21.0.tgz#453fb3662409abaf2f8b1f65d515699c888dd8ae" + integrity sha512-SX8jNN+iHqAF0riZQMkm7e8+POXa/fXw5cxL+gjpyP+FI+JVNhii53EmQgDAfDcBpFekYSlO0fGytMQwRiMQCA== dependencies: - "@typescript-eslint/types" "5.19.0" + "@typescript-eslint/types" "5.21.0" eslint-visitor-keys "^3.0.0" "@webassemblyjs/ast@1.11.1": @@ -4660,9 +4740,9 @@ integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== abab@^2.0.3, abab@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: version "1.3.8" @@ -4725,9 +4805,9 @@ acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.1: integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== acorn@^8.0.4, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" - integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== + version "8.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" + integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== address@^1.0.1, address@^1.1.2: version "1.1.2" @@ -5221,10 +5301,10 @@ async-each@^1.0.1: resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== -async-validator@^4.0.2: - version "4.0.7" - resolved "https://registry.yarnpkg.com/async-validator/-/async-validator-4.0.7.tgz#034a0fd2103a6b2ebf010da75183bec299247afe" - integrity sha512-Pj2IR7u8hmUEDOwB++su6baaRi+QvsgajuFB9j95foM1N2gy5HM4z60hfusIO0fBPG5uLAEl6yCJr1jNSVugEQ== +async-validator@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/async-validator/-/async-validator-4.1.1.tgz#3cd1437faa2de64743f7d56649dd904c946a18fe" + integrity sha512-p4DO/JXwjs8klJyJL8Q2oM4ks5fUTze/h5k10oPPKMiLe1fj3G1QMzPHNmN1Py4ycOk7WlO2DcGXv1qiESJCZA== async@^2.6.2: version "2.6.4" @@ -5253,13 +5333,13 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autoprefixer@^10.3.7, autoprefixer@^10.4.4: - version "10.4.4" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.4.tgz#3e85a245b32da876a893d3ac2ea19f01e7ea5a1e" - integrity sha512-Tm8JxsB286VweiZ5F0anmbyGiNI3v3wGv3mz9W+cxEDYB/6jbnj6GM9H9mK3wIL8ftgl+C07Lcwb8PG5PCCPzA== +autoprefixer@^10.3.7, autoprefixer@^10.4.4, autoprefixer@^10.4.5: + version "10.4.5" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.5.tgz#662193c744094b53d3637f39be477e07bd904998" + integrity sha512-Fvd8yCoA7lNX/OUllvS+aS1I7WRBclGXsepbvT8ZaPgrH24rgXpZzF0/6Hh3ZEkwg+0AES/Osd196VZmYoEFtw== dependencies: browserslist "^4.20.2" - caniuse-lite "^1.0.30001317" + caniuse-lite "^1.0.30001332" fraction.js "^4.2.0" normalize-range "^0.1.2" picocolors "^1.0.0" @@ -5319,9 +5399,9 @@ babel-jest@^27.4.2, babel-jest@^27.5.1: slash "^3.0.0" babel-loader@^8.0.0, babel-loader@^8.2.3, babel-loader@^8.2.4: - version "8.2.4" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.4.tgz#95f5023c791b2e9e2ca6f67b0984f39c82ff384b" - integrity sha512-8dytA3gcvPPPv4Grjhnt8b5IIiTcq/zeXOPk4iTYI0SVXcsmuGg7JtBRDp8S9X+gJfhQ8ektjXZlDu1Bb33U8A== + version "8.2.5" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e" + integrity sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ== dependencies: find-cache-dir "^3.3.1" loader-utils "^2.0.0" @@ -5708,26 +5788,28 @@ bn.js@^5.0.0, bn.js@^5.1.1: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== -body-parser@1.19.2: - version "1.19.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e" - integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw== +body-parser@1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== dependencies: bytes "3.1.2" content-type "~1.0.4" debug "2.6.9" - depd "~1.1.2" - http-errors "1.8.1" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.9.7" - raw-body "2.4.3" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" type-is "~1.6.18" + unpipe "1.0.0" bonjour-service@^1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.11.tgz#5418e5c1ac91c89a406f853a942e7892829c0d89" - integrity sha512-drMprzr2rDTCtgEE3VgdA9uUFaUHF+jXduwYSThHJnKMYM+FhI9Z3ph+TX3xy0LtgYHae6CHYPJ/2UnK8nQHcA== + version "1.0.12" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.12.tgz#28fbd4683f5f2e36feedb833e24ba661cac960c3" + integrity sha512-pMmguXYCu63Ug37DluMKEHdxc+aaIf/ay4YbF8Gxtba+9d3u+rmEWy61VK3Z3hp8Rskok3BunHYnG0dUHAsblw== dependencies: array-flatten "^2.1.2" dns-equal "^1.0.0" @@ -5876,15 +5958,15 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.17.5, browserslist@^4.18.1, browserslist@^4.19.1, browserslist@^4.20.2: - version "4.20.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" - integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.17.5, browserslist@^4.18.1, browserslist@^4.20.2, browserslist@^4.20.3: + version "4.20.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.3.tgz#eb7572f49ec430e054f56d52ff0ebe9be915f8bf" + integrity sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg== dependencies: - caniuse-lite "^1.0.30001317" - electron-to-chromium "^1.4.84" + caniuse-lite "^1.0.30001332" + electron-to-chromium "^1.4.118" escalade "^3.1.1" - node-releases "^2.0.2" + node-releases "^2.0.3" picocolors "^1.0.0" bs-logger@0.x: @@ -5941,22 +6023,22 @@ bytes@3.1.2: integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== c8@^7.6.0: - version "7.11.0" - resolved "https://registry.yarnpkg.com/c8/-/c8-7.11.0.tgz#b3ab4e9e03295a102c47ce11d4ef6d735d9a9ac9" - integrity sha512-XqPyj1uvlHMr+Y1IeRndC2X5P7iJzJlEJwBpCdBbq2JocXOgJfr+JVfJkyNMGROke5LfKrhSFXGFXnwnRJAUJw== + version "7.11.2" + resolved "https://registry.yarnpkg.com/c8/-/c8-7.11.2.tgz#2f2103e39079899041e612999a16b31d7ea6d463" + integrity sha512-6ahJSrhS6TqSghHm+HnWt/8Y2+z0hM/FQyB1ybKhAR30+NYL9CTQ1uwHxuWw6U7BHlHv6wvhgOrH81I+lfCkxg== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@istanbuljs/schema" "^0.1.2" + "@istanbuljs/schema" "^0.1.3" find-up "^5.0.0" foreground-child "^2.0.0" - istanbul-lib-coverage "^3.0.1" + istanbul-lib-coverage "^3.2.0" istanbul-lib-report "^3.0.0" - istanbul-reports "^3.0.2" - rimraf "^3.0.0" + istanbul-reports "^3.1.4" + rimraf "^3.0.2" test-exclude "^6.0.0" - v8-to-istanbul "^8.0.0" + v8-to-istanbul "^9.0.0" yargs "^16.2.0" - yargs-parser "^20.2.7" + yargs-parser "^20.2.9" cacache@^12.0.2: version "12.0.4" @@ -6097,10 +6179,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001317: - version "1.0.30001332" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz#39476d3aa8d83ea76359c70302eafdd4a1d727dd" - integrity sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001332: + version "1.0.30001334" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001334.tgz#892e9965b35285033fc2b8a8eff499fe02f13d8b" + integrity sha512-kbaCEBRRVSoeNs74sCuq92MJyGrMtjWVfhltoHUCW4t4pXFvGjUBrfo47weBRViHkiV3eBYyIsfl956NtHGazw== capture-exit@^2.0.0: version "2.0.0" @@ -6680,10 +6762,10 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= -cookie@0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" - integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== copy-concurrently@^1.0.0: version "1.0.5" @@ -6727,17 +6809,17 @@ copy-webpack-plugin@^10.2.4: serialize-javascript "^6.0.0" core-js-compat@^3.20.2, core-js-compat@^3.21.0, core-js-compat@^3.8.1: - version "3.21.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.21.1.tgz#cac369f67c8d134ff8f9bd1623e3bc2c42068c82" - integrity sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g== + version "3.22.3" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.3.tgz#9b10d786052d042bc97ee8df9c0d1fb6a49c2005" + integrity sha512-wliMbvPI2idgFWpFe7UEyHMvu6HWgW8WA+HnDRtgzoSDYvXFMpoGX1H3tPDDXrcfUSyXafCLDd7hOeMQHEZxGw== dependencies: - browserslist "^4.19.1" + browserslist "^4.20.3" semver "7.0.0" core-js-pure@^3.20.2, core-js-pure@^3.8.1, core-js-pure@^3.8.2: - version "3.21.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.21.1.tgz#8c4d1e78839f5f46208de7230cebfb72bc3bdb51" - integrity sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ== + version "3.22.3" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.22.3.tgz#181d1b6321fb29fe99c16a1f28beb840ab84ad36" + integrity sha512-oN88zz7nmKROMy8GOjs+LN+0LedIvbMdnB5XsTlhcOg1WGARt9l0LFg0zohdoFmCsEZ1h2ZbSQ6azj3M+vhzwQ== core-js@^2.4.0: version "2.6.12" @@ -6745,9 +6827,9 @@ core-js@^2.4.0: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.0.4, core-js@^3.19.2, core-js@^3.21.1, core-js@^3.6.5, core-js@^3.8.2: - version "3.21.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.21.1.tgz#f2e0ddc1fc43da6f904706e8e955bc19d06a0d94" - integrity sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig== + version "3.22.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.22.3.tgz#498c41d997654cb00e81c7a54b44f0ab21ab01d5" + integrity sha512-1t+2a/d2lppW1gkLXx3pKPVGbBdxXAkqztvWb1EJ8oF8O2gIGiytzflNiFEehYwVK/t2ryUsGBoOFFvNx95mbg== core-util-is@~1.0.0: version "1.0.3" @@ -7332,9 +7414,9 @@ date-fns@2.x: integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw== dayjs@1.x: - version "1.11.0" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.0.tgz#009bf7ef2e2ea2d5db2e6583d2d39a4b5061e805" - integrity sha512-JLC809s6Y948/FuCZPm5IX8rRhQwOiyMb2TfVVQEixG7P8Lm/gt5S7yoQZmC8x1UehI9Pb7sksEt4xx14m+7Ug== + version "1.11.1" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.1.tgz#90b33a3dda3417258d48ad2771b415def6545eb0" + integrity sha512-ER7EjqVAMkRRsxNCC5YqJ9d9VQYuWdGt7aiH2qA5R5wt8ZmWaP2dLUSIK6y/kVzLMlmh1Tvu5xUf4M/wdGJ5KA== debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9: version "2.6.9" @@ -7429,11 +7511,12 @@ define-lazy-prop@^2.0.0: integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== dependencies: - object-keys "^1.0.12" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" define-property@^0.2.5: version "0.2.5" @@ -7638,14 +7721,14 @@ doctrine@^3.0.0: esutils "^2.0.2" dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9: - version "0.5.13" - resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.13.tgz#102ee5f25eacce09bdf1cfa5a298f86da473be4b" - integrity sha512-R305kwb5CcMDIpSHUnLyIAp7SrSPBx6F0VfQFB3M75xVMHhXJJIdePYgbPPh1o57vCHNu5QztokWUPsLjWzFqw== + version "0.5.14" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz#56082f71b1dc7aac69d83c4285eef39c15d93f56" + integrity sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg== dom-align@^1.7.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/dom-align/-/dom-align-1.12.2.tgz#0f8164ebd0c9c21b0c790310493cd855892acd4b" - integrity sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg== + version "1.12.3" + resolved "https://registry.yarnpkg.com/dom-align/-/dom-align-1.12.3.tgz#a36d02531dae0eefa2abb0c4db6595250526f103" + integrity sha512-Gj9hZN3a07cbR6zviMUBOMPdWxYhbMI+x+WS0NAIu2zFZmbK8ys9R79g+iG9qLnlCwpFoaB+fKy8Pdv470GsPA== dom-converter@^0.2.0: version "0.2.0" @@ -7823,10 +7906,10 @@ ejs@^3.1.6: dependencies: jake "^10.8.5" -electron-to-chromium@^1.4.84: - version "1.4.107" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.107.tgz#564257014ab14033b4403a309c813123c58a3fb9" - integrity sha512-Huen6taaVrUrSy8o7mGStByba8PfOWWluHNxSHGBrCgEdFVLtvdQDBr9LBCF9Uci8SYxh28QNNMO0oC17wbGAg== +electron-to-chromium@^1.4.118: + version "1.4.124" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.124.tgz#e9015e234d8632920dcdf5480351da9e845ed220" + integrity sha512-VhaE9VUYU6d2eIb+4xf83CATD+T+3bTzvxvlADkQE+c2hisiw3sZmvEDtsW704+Zky9WZGhBuQXijDVqSriQLA== element-resize-detector@^1.2.2: version "1.2.4" @@ -7848,6 +7931,11 @@ elliptic@^6.5.3: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" +emittery@^0.10.2: + version "0.10.2" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" + integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== + emittery@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" @@ -8028,9 +8116,9 @@ es-to-primitive@^1.2.1: is-symbol "^1.0.2" es5-shim@^4.5.13: - version "4.6.5" - resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.6.5.tgz#2124bb073b7cede2ed23b122a1fd87bb7b0bb724" - integrity sha512-vfQ4UAai8szn0sAubCy97xnZ4sJVDD1gt/Grn736hg8D7540wemIb1YPrYZSTqlM2H69EQX1or4HU/tSwRTI3w== + version "4.6.6" + resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.6.6.tgz#1e0e95bedfdcd933a2d4931a3ac6c79164f18de6" + integrity sha512-Ay5QQE78I2WKUoZVZjL0AIuiIjsmXwZGkyCTH9+n6J1anPbb0ymDA27ASa2Lt0rhOpAlEKy2W0d17gJ1XOQ5eQ== es6-error@^4.0.1: version "4.1.1" @@ -8178,9 +8266,9 @@ eslint-plugin-jsx-a11y@^6.5.1: minimatch "^3.0.4" eslint-plugin-react-hooks@^4.3.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.4.0.tgz#71c39e528764c848d8253e1aa2c7024ed505f6c4" - integrity sha512-U3RVIfdzJaeKDQKEJbz5p3NW8/L80PCATJAfuojwbaEL+gBjfGdhUcGde+WGUW46Q5sr/NgxevsIiDtNXrvZaQ== + version "4.5.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz#5f762dfedf8b2cf431c689f533c9d3fa5dcf25ad" + integrity sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw== eslint-plugin-react@^7.27.1: version "7.29.4" @@ -8262,11 +8350,11 @@ eslint-webpack-plugin@^3.1.1: schema-utils "^3.1.1" eslint@^8.3.0: - version "8.13.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.13.0.tgz#6fcea43b6811e655410f5626cfcf328016badcd7" - integrity sha512-D+Xei61eInqauAyTJ6C0q6x9mx7kTUC1KZ0m0LSEexR0V+e94K12LmWX076ZIsldwfQ2RONdaJe0re0TRGQbRQ== + version "8.14.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.14.0.tgz#62741f159d9eb4a79695b28ec4989fcdec623239" + integrity sha512-3/CE4aJX7LNEiE3i6FeodHmI/38GZtWCsAtsymScmzYapx8q1nVVb+eLcLSzATmCPXw5pT4TqVs1E0OmxAd9tw== dependencies: - "@eslint/eslintrc" "^1.2.1" + "@eslint/eslintrc" "^1.2.2" "@humanwhocodes/config-array" "^0.9.2" ajv "^6.10.0" chalk "^4.0.0" @@ -8457,37 +8545,38 @@ expect@^27.5.1: jest-message-util "^27.5.1" express@^4.17.1, express@^4.17.3: - version "4.17.3" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1" - integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg== + version "4.18.0" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.0.tgz#7a426773325d0dd5406395220614c0db10b6e8e2" + integrity sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.19.2" + body-parser "1.20.0" content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.4.2" + cookie "0.5.0" cookie-signature "1.0.6" debug "2.6.9" - depd "~1.1.2" + depd "2.0.0" encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "~1.1.2" + finalhandler "1.2.0" fresh "0.5.2" + http-errors "2.0.0" merge-descriptors "1.0.1" methods "~1.1.2" - on-finished "~2.3.0" + on-finished "2.4.1" parseurl "~1.3.3" path-to-regexp "0.1.7" proxy-addr "~2.0.7" - qs "6.9.7" + qs "6.10.3" range-parser "~1.2.1" safe-buffer "5.2.1" - send "0.17.2" - serve-static "1.14.2" + send "0.18.0" + serve-static "1.15.0" setprototypeof "1.2.0" - statuses "~1.5.0" + statuses "2.0.1" type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" @@ -8716,17 +8805,17 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== dependencies: debug "2.6.9" encodeurl "~1.0.2" escape-html "~1.0.3" - on-finished "~2.3.0" + on-finished "2.4.1" parseurl "~1.3.3" - statuses "~1.5.0" + statuses "2.0.1" unpipe "~1.0.0" find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: @@ -8843,9 +8932,9 @@ fork-ts-checker-webpack-plugin@^4.1.6: worker-rpc "^0.1.0" fork-ts-checker-webpack-plugin@^6.0.4, fork-ts-checker-webpack-plugin@^6.5.0: - version "6.5.1" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.1.tgz#fd689e2d9de6ac76abb620909eea56438cd0f232" - integrity sha512-x1wumpHOEf4gDROmKTaB6i4/Q6H3LwmjVO7fIX47vBwlZbtPjU33hgoMuD/Q/y6SU8bnuYSoN6ZQOLshGp0T/g== + version "6.5.2" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz#4f67183f2f9eb8ba7df7177ce3cf3e75cdafb340" + integrity sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA== dependencies: "@babel/code-frame" "^7.8.3" "@types/json-schema" "^7.0.5" @@ -8922,9 +9011,9 @@ fs-extra@^0.30.0: rimraf "^2.2.8" fs-extra@^10.0.0, fs-extra@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.1.tgz#27de43b4320e833f6867cc044bfce29fdf0ef3b8" - integrity sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag== + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -9001,9 +9090,9 @@ functional-red-black-tree@^1.0.1: integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= functions-have-names@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.2.tgz#98d93991c39da9361f8e50b337c4f6e41f120e21" - integrity sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA== + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== fuse.js@^3.6.1: version "3.6.1" @@ -9308,10 +9397,10 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== has-flag@^3.0.0: version "3.0.0" @@ -9330,6 +9419,13 @@ has-glob@^1.0.0: dependencies: is-glob "^3.0.0" +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" @@ -9756,9 +9852,9 @@ http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1: debug "4" http-proxy-middleware@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz#03af0f4676d172ae775cb5c33f592f40e1a4e07a" - integrity sha512-m/4FxX17SUvz4lJ5WPXOHDUuCwIqXLfLHs1s0uZ3oYjhoXlx9csYxaOa0ElDEJ+h8Q4iJ1s+lTMbiCa4EXIJqg== + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" @@ -10092,9 +10188,9 @@ is-ci@^2.0.0: ci-info "^2.0.0" is-core-module@^2.2.0, is-core-module@^2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" - integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + version "2.9.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== dependencies: has "^1.0.3" @@ -10445,7 +10541,7 @@ isobject@^4.0.0: resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.0.0-alpha.1, istanbul-lib-coverage@^3.0.1, istanbul-lib-coverage@^3.2.0: +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.0.0-alpha.1, istanbul-lib-coverage@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== @@ -10468,9 +10564,9 @@ istanbul-lib-instrument@^4.0.0: semver "^6.3.0" istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" - integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== + version "5.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" + integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== dependencies: "@babel/core" "^7.12.3" "@babel/parser" "^7.14.7" @@ -10509,7 +10605,7 @@ istanbul-lib-source-maps@^4.0.0: istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^3.0.2, istanbul-reports@^3.1.3: +istanbul-reports@^3.0.2, istanbul-reports@^3.1.3, istanbul-reports@^3.1.4: version "3.1.4" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== @@ -10782,6 +10878,21 @@ jest-message-util@^27.5.1: slash "^3.0.0" stack-utils "^2.0.3" +jest-message-util@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.0.2.tgz#f3cf36be72be4c4c4058cb34bd6673996d26dee3" + integrity sha512-knK7XyojvwYh1XiF2wmVdskgM/uN11KsjcEWWHfnMZNEdwXCrqB4sCBO94F4cfiAwCS8WFV6CDixDwPlMh/wdA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^28.0.2" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^28.0.2" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" @@ -10800,11 +10911,16 @@ jest-regex-util@^26.0.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== -jest-regex-util@^27.0.0, jest-regex-util@^27.5.1: +jest-regex-util@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== +jest-regex-util@^28.0.0: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" + integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== + jest-resolve-dependencies@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" @@ -10953,6 +11069,18 @@ jest-util@^27.0.0, jest-util@^27.5.1: graceful-fs "^4.2.9" picomatch "^2.2.3" +jest-util@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.0.2.tgz#8e22cdd6e0549e0a393055f0e2da7eacc334b143" + integrity sha512-EVdpIRCC8lzqhp9A0u0aAKlsFIzufK6xKxNK7awsnebTdOP4hpyQW5o6Ox2qPl8gbeUKYF+POLyItaND53kpGA== + dependencies: + "@jest/types" "^28.0.2" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + jest-validate@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" @@ -10966,19 +11094,19 @@ jest-validate@^27.5.1: pretty-format "^27.5.1" jest-watch-typeahead@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-1.0.0.tgz#4de2ca1eb596acb1889752afbab84b74fcd99173" - integrity sha512-jxoszalAb394WElmiJTFBMzie/RDCF+W7Q29n5LzOPtcoQoHWfdUtHFkbhgf5NwWe8uMOxvKb/g7ea7CshfkTw== + version "1.1.0" + resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz#b4a6826dfb9c9420da2f7bc900de59dad11266a9" + integrity sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw== dependencies: ansi-escapes "^4.3.1" chalk "^4.0.0" - jest-regex-util "^27.0.0" - jest-watcher "^27.0.0" + jest-regex-util "^28.0.0" + jest-watcher "^28.0.0" slash "^4.0.0" string-length "^5.0.1" strip-ansi "^7.0.1" -jest-watcher@^27.0.0, jest-watcher@^27.5.1: +jest-watcher@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== @@ -10991,6 +11119,20 @@ jest-watcher@^27.0.0, jest-watcher@^27.5.1: jest-util "^27.5.1" string-length "^4.0.1" +jest-watcher@^28.0.0: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.0.2.tgz#649fa24df531d4071be5784b6274d494d788c88b" + integrity sha512-uIVJLpQ/5VTGQWBiBatHsi7jrCqHjHl0e0dFHMWzwuIfUbdW/muk0DtSr0fteY2T7QTFylv+7a5Rm8sBKrE12Q== + dependencies: + "@jest/test-result" "^28.0.2" + "@jest/types" "^28.0.2" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.10.2" + jest-util "^28.0.2" + string-length "^4.0.1" + jest-worker@^26.2.1, jest-worker@^26.5.0, jest-worker@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" @@ -12050,9 +12192,9 @@ nan@^2.12.1: integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== nanoid@^3.1.23, nanoid@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.2.tgz#c89622fafb4381cd221421c69ec58547a1eec557" - integrity sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA== + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== nanomatch@^1.2.9: version "1.2.13" @@ -12171,10 +12313,10 @@ node-preload@^0.2.1: dependencies: process-on-spawn "^1.0.0" -node-releases@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" - integrity sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw== +node-releases@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.4.tgz#f38252370c43854dc48aa431c766c6c398f40476" + integrity sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ== normalize-package-data@^2.5.0: version "2.5.0" @@ -12323,7 +12465,7 @@ object-inspect@^1.12.0, object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== -object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -12600,11 +12742,11 @@ p-map@^4.0.0: aggregate-error "^3.0.0" p-retry@^4.5.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" - integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== + version "4.6.2" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== dependencies: - "@types/retry" "^0.12.0" + "@types/retry" "0.12.0" retry "^0.13.1" p-timeout@^3.1.0: @@ -13009,7 +13151,7 @@ postcss-custom-media@^8.0.0: resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-8.0.0.tgz#1be6aff8be7dc9bf1fe014bde3b71b92bb4552f1" integrity sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g== -postcss-custom-properties@^12.1.5: +postcss-custom-properties@^12.1.7: version "12.1.7" resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.7.tgz#ca470fd4bbac5a87fd868636dafc084bc2a78b41" integrity sha512-N/hYP5gSoFhaqxi2DPCmvto/ZcRDVjE3T1LiAMzc/bg53hvhcHOLpXOHb526LzBBp5ZlAUhkuot/bfpmpgStJg== @@ -13127,7 +13269,7 @@ postcss-js@^4.0.0: dependencies: camelcase-css "^2.0.1" -postcss-lab-function@^4.1.2: +postcss-lab-function@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-4.2.0.tgz#e054e662c6480202f5760887ec1ae0d153357123" integrity sha512-Zb1EO9DGYfa3CP8LhINHCcTTCTLI+R3t7AX2mKsDzdgVQ/GkCpHOTgOr6HBHslP7XDdVbqgHW5vvRPMdVANQ8w== @@ -13299,7 +13441,7 @@ postcss-nested@5.0.6: dependencies: postcss-selector-parser "^6.0.6" -postcss-nesting@^10.1.3: +postcss-nesting@^10.1.4: version "10.1.4" resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.1.4.tgz#80de9d1c2717bc44df918dd7f118929300192a7a" integrity sha512-2ixdQ59ik/Gt1+oPHiI1kHdwEI8lLKEmui9B1nl6163ANLC+GewQn7fXMxJF2JSb4i2MKL96GU8fIiQztK4TTA== @@ -13409,20 +13551,20 @@ postcss-place@^7.0.4: postcss-value-parser "^4.2.0" postcss-preset-env@^7.0.1: - version "7.4.3" - resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.4.3.tgz#fb1c8b4cb405da042da0ddb8c5eda7842c08a449" - integrity sha512-dlPA65g9KuGv7YsmGyCKtFkZKCPLkoVMUE3omOl6yM+qrynVHxFvf0tMuippIrXB/sB/MyhL1FgTIbrO+qMERg== + version "7.4.4" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.4.4.tgz#069e34e31e2a7345154da7936b9fc1fcbdbd6d43" + integrity sha512-MqzSEx/QsvOk562iV9mLTgIvLFEOq1os9QBQfkgnq8TW6yKhVFPGh0gdXSK5ZlmjuNQEga6/x833e86XZF/lug== dependencies: - "@csstools/postcss-color-function" "^1.0.3" + "@csstools/postcss-color-function" "^1.1.0" "@csstools/postcss-font-format-keywords" "^1.0.0" "@csstools/postcss-hwb-function" "^1.0.0" "@csstools/postcss-ic-unit" "^1.0.0" - "@csstools/postcss-is-pseudo-class" "^2.0.1" + "@csstools/postcss-is-pseudo-class" "^2.0.2" "@csstools/postcss-normalize-display-values" "^1.0.0" - "@csstools/postcss-oklab-function" "^1.0.2" + "@csstools/postcss-oklab-function" "^1.1.0" "@csstools/postcss-progressive-custom-properties" "^1.3.0" - autoprefixer "^10.4.4" - browserslist "^4.20.2" + autoprefixer "^10.4.5" + browserslist "^4.20.3" css-blank-pseudo "^3.0.3" css-has-pseudo "^3.0.4" css-prefers-color-scheme "^6.0.3" @@ -13433,7 +13575,7 @@ postcss-preset-env@^7.0.1: postcss-color-hex-alpha "^8.0.3" postcss-color-rebeccapurple "^7.0.2" postcss-custom-media "^8.0.0" - postcss-custom-properties "^12.1.5" + postcss-custom-properties "^12.1.7" postcss-custom-selectors "^6.0.0" postcss-dir-pseudo-class "^6.0.4" postcss-double-position-gradients "^3.1.1" @@ -13444,20 +13586,20 @@ postcss-preset-env@^7.0.1: postcss-gap-properties "^3.0.3" postcss-image-set-function "^4.0.6" postcss-initial "^4.0.1" - postcss-lab-function "^4.1.2" + postcss-lab-function "^4.2.0" postcss-logical "^5.0.4" postcss-media-minmax "^5.0.0" - postcss-nesting "^10.1.3" + postcss-nesting "^10.1.4" postcss-opacity-percentage "^1.1.2" postcss-overflow-shorthand "^3.0.3" postcss-page-break "^3.0.4" postcss-place "^7.0.4" - postcss-pseudo-class-any-link "^7.1.1" + postcss-pseudo-class-any-link "^7.1.2" postcss-replace-overflow-wrap "^4.0.0" postcss-selector-not "^5.0.0" postcss-value-parser "^4.2.0" -postcss-pseudo-class-any-link@^7.1.1: +postcss-pseudo-class-any-link@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.2.tgz#81ec491aa43f97f9015e998b7a14263b4630bdf0" integrity sha512-76XzEQv3g+Vgnz3tmqh3pqQyRojkcJ+pjaePsyhcyf164p9aZsu3t+NWxkZYbcHLK1ju5Qmalti2jPI5IWCe5w== @@ -13610,6 +13752,16 @@ pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: ansi-styles "^5.0.0" react-is "^17.0.1" +pretty-format@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.0.2.tgz#6a24d71cbb61a5e5794ba7513fe22101675481bc" + integrity sha512-UmGZ1IERwS3yY35LDMTaBUYI1w4udZDdJGGT/DqQeKG9ZLDn7/K2Jf/JtYSRiHCCKMHvUA+zsEGSmHdpaVp1yw== + dependencies: + "@jest/schemas" "^28.0.2" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^18.0.0" + pretty-hrtime@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" @@ -13625,7 +13777,12 @@ prism-react-renderer@^1.2.1, prism-react-renderer@^1.3.1: resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.3.1.tgz#88fc9d0df6bed06ca2b9097421349f8c2f24e30d" integrity sha512-xUeDMEz074d0zc5y6rxiMp/dlC7C+5IDDlaEUlcBOFE2wddz7hz5PNupb087mPwTt7T9BrFmewObfCBuf/LKwQ== -prismjs@^1.21.0, prismjs@^1.27.0, prismjs@~1.27.0: +prismjs@^1.21.0, prismjs@^1.27.0: + version "1.28.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.28.0.tgz#0d8f561fa0f7cf6ebca901747828b149147044b6" + integrity sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw== + +prismjs@~1.27.0: version "1.27.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== @@ -13695,7 +13852,7 @@ prompts@^2.0.1, prompts@^2.4.0, prompts@^2.4.2: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: +prop-types@^15.0.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -13803,12 +13960,7 @@ q@^1.1.2: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= -qs@6.9.7: - version "6.9.7" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" - integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== - -qs@^6.10.0: +qs@6.10.3, qs@^6.10.0: version "6.10.3" resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== @@ -13889,13 +14041,18 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c" - integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g== +rationale@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/rationale/-/rationale-0.2.0.tgz#555ed4f3cc7cd0245faeac041d3769f1857e4f3d" + integrity sha512-Pd8w5Inv1JhTfRyx03zs486CEAn6UKXvvOtxVRLsewngsBSffo3MQwUKYS75L/8vPt98wmf7iaZROx362/f7Bw== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== dependencies: bytes "3.1.2" - http-errors "1.8.1" + http-errors "2.0.0" iconv-lite "0.4.24" unpipe "1.0.0" @@ -13908,9 +14065,9 @@ raw-loader@^4.0.2: schema-utils "^3.0.0" rc-align@^4.0.0: - version "4.0.11" - resolved "https://registry.yarnpkg.com/rc-align/-/rc-align-4.0.11.tgz#8198c62db266bc1b8ef05e56c13275bf72628a5e" - integrity sha512-n9mQfIYQbbNTbefyQnRHZPWuTEwG1rY4a9yKlIWHSTbgwI+XUMGRYd0uJ5pE2UbrNX0WvnMBA1zJ3Lrecpra/A== + version "4.0.12" + resolved "https://registry.yarnpkg.com/rc-align/-/rc-align-4.0.12.tgz#065b5c68a1cc92a00800c9239320d9fdf5f16207" + integrity sha512-3DuwSJp8iC/dgHzwreOQl52soj40LchlfUHtgACOUtwGuoFIOVh6n/sCpfqCU8kO5+iz6qR0YKvjgB8iPdE3aQ== dependencies: "@babel/runtime" "^7.10.1" classnames "2.x" @@ -13970,9 +14127,9 @@ rc-drawer@~4.4.2: rc-util "^5.7.0" rc-dropdown@~3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/rc-dropdown/-/rc-dropdown-3.5.0.tgz#6ff2e6aaacd3641aa4040cfa941ab9634ad5f1ed" - integrity sha512-HHMpzO6AJt3I2jBG8fFK9LqFMQhHn/V09AzQnqCCV8Fp22tNCS98Obelcc4C8T6ZlZR+/w01im0BQVP3o1Y+Cw== + version "3.5.2" + resolved "https://registry.yarnpkg.com/rc-dropdown/-/rc-dropdown-3.5.2.tgz#2f1f4eeb36c07fb67cd599c0cb8e861da3de5527" + integrity sha512-Ty4LsXjkspZuFJSRx3blCLLCDicXM5qds6F1odgEa+jcjC+OJKHQGnvE4FqtoljPaqWm4wG78pbgXH6Ddh2DkA== dependencies: "@babel/runtime" "^7.10.1" classnames "^2.2.6" @@ -13980,18 +14137,18 @@ rc-dropdown@~3.5.0: rc-util "^5.17.0" rc-field-form@~1.26.1: - version "1.26.2" - resolved "https://registry.yarnpkg.com/rc-field-form/-/rc-field-form-1.26.2.tgz#69d92811eed09f9e1f74704695b13253bb2ae534" - integrity sha512-Q1QdpLAt/kxd119kJwGfFvn/ZIzjzTBJsCscy5k0z3g+eRMHkI0Exij6SE2D42N7FAzVkvuXTvzqWSiFGeer7g== + version "1.26.3" + resolved "https://registry.yarnpkg.com/rc-field-form/-/rc-field-form-1.26.3.tgz#4050000eae0d879fde85672a965c9558ed6ff04b" + integrity sha512-wzQToAwdr8fiq/Nb1KFq+9WYFeALJXKwNGk5/MaCu1AUS7PpVQaN2anzVfWdVBFiiM2N+3DOh64JSOH8s1w3FQ== dependencies: "@babel/runtime" "^7.8.4" - async-validator "^4.0.2" + async-validator "^4.1.0" rc-util "^5.8.0" rc-image@~5.6.0: - version "5.6.1" - resolved "https://registry.yarnpkg.com/rc-image/-/rc-image-5.6.1.tgz#60662a8fc0fe91d7ebd7fd5ee972d5b6226850e2" - integrity sha512-nmcobNCfmeevsep6eL7KNHVwFdLz4As4Vx0o90nnUFNzZ9Pqost1s10gOf4Wl6XW2iMR9LU6ztm5EazM7yA4Gg== + version "5.6.2" + resolved "https://registry.yarnpkg.com/rc-image/-/rc-image-5.6.2.tgz#31892b0b22aa5122fd9b1a067e9a4ba627004214" + integrity sha512-qhKOVvivCZkd6CrzS/4ST2+Auu16mtPSFVqVzwE7sELWfuvzcLGTzGv8UsVvm6qRNIz6SeaueUetqi4Ii16XQA== dependencies: "@babel/runtime" "^7.11.2" classnames "^2.2.6" @@ -14061,9 +14218,9 @@ rc-notification@~4.6.0: rc-util "^5.20.1" rc-overflow@^1.0.0, rc-overflow@^1.2.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/rc-overflow/-/rc-overflow-1.2.4.tgz#e25cd3c4a98b4f8233a8dab7172ab2dbcc83b45e" - integrity sha512-nIeelyYfdS+mQBK1++FisLZEvZ8xVAzC+duG+TC4TmqNN+kTHraiGntV9/zxDGA1ruyQ91YRJ549JjFodCBnsw== + version "1.2.5" + resolved "https://registry.yarnpkg.com/rc-overflow/-/rc-overflow-1.2.5.tgz#d0fe3f9fa99edec70f4fe20e38119e8c1c5ae3ca" + integrity sha512-5HJKZ4nPe9e7AFdCkflgpRydvH6lJ4i2iFF06q/T1G9lL/XBeuoPLRrTBU8ao/Vo/yARW6WfEHnC2951lVgX5Q== dependencies: "@babel/runtime" "^7.11.1" classnames "^2.2.1" @@ -14071,17 +14228,17 @@ rc-overflow@^1.0.0, rc-overflow@^1.2.0: rc-util "^5.19.2" rc-pagination@~3.1.9: - version "3.1.15" - resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-3.1.15.tgz#e05eddf4c15717a5858290bed0857e27e2f957ff" - integrity sha512-4L3fot8g4E+PjWEgoVGX0noFCg+8ZFZmeLH4vsnZpB3O2T2zThtakjNxG+YvSaYtyMVT4B+GLayjKrKbXQpdAg== + version "3.1.16" + resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-3.1.16.tgz#b0082108cf027eded18ed61d818d31897c343e81" + integrity sha512-GFcHXJ7XxeJDf9B+ndP4PRDt46maSSgYhiwofBMiIGKIlBhJ0wfu8DMCEvaWJJLpI2u4Gb6zF1dHpiqPFrosPg== dependencies: "@babel/runtime" "^7.10.1" classnames "^2.2.1" rc-picker@~2.6.4: - version "2.6.7" - resolved "https://registry.yarnpkg.com/rc-picker/-/rc-picker-2.6.7.tgz#bdde4156e219ef36b0006b7d4d72020373f21229" - integrity sha512-+P2Grt0r2kmCkw2XTp9ew3zTCwBCFEOQLd5BYs+hFaGDSSZwEWJtlbGXAGqWnAUMFx6JrCsKYkDKXDxAWlRz3A== + version "2.6.8" + resolved "https://registry.yarnpkg.com/rc-picker/-/rc-picker-2.6.8.tgz#eff71e13d836953a4c7439c958228b5108f92c22" + integrity sha512-j14N2nxcx4PAw7LviwLKIJG4cEAlCFhcHI/7pz+Ps43Df7UrSIWt/QGJgPAWz38Z6jrjsgMcyVHVccpL09gDDA== dependencies: "@babel/runtime" "^7.10.1" classnames "^2.2.1" @@ -14237,9 +14394,9 @@ rc-tree@~5.5.0: rc-virtual-list "^3.4.2" rc-trigger@^5.0.0, rc-trigger@^5.0.4, rc-trigger@^5.1.2, rc-trigger@^5.2.10: - version "5.2.15" - resolved "https://registry.yarnpkg.com/rc-trigger/-/rc-trigger-5.2.15.tgz#f6bfed418e602513cc3e07853ddaf37e5c5339f4" - integrity sha512-VxZWqCObtUOzs9V9Be0dDA2JGchriDpvQaJpsCI2EQ4+KWHIvjFz6Ziina4uxK5drRsn0RnBi7nngmTl9j/F7Q== + version "5.2.18" + resolved "https://registry.yarnpkg.com/rc-trigger/-/rc-trigger-5.2.18.tgz#adab51918e4569b174d4fc5044186200d97a542c" + integrity sha512-hi2yZ7umtbAGLxgSph1az9BR9i4Pb4fiQa4pdvFQuKN7U//3nwwygHQKHfexnM+0APBnzZwVlEHA5I8BpWrygw== dependencies: "@babel/runtime" "^7.11.2" classnames "^2.2.6" @@ -14266,9 +14423,9 @@ rc-util@^5.0.1, rc-util@^5.0.6, rc-util@^5.12.0, rc-util@^5.14.0, rc-util@^5.15. shallowequal "^1.1.0" rc-virtual-list@^3.2.0, rc-virtual-list@^3.4.2: - version "3.4.6" - resolved "https://registry.yarnpkg.com/rc-virtual-list/-/rc-virtual-list-3.4.6.tgz#af34235915221173dd42d9f25b32e95d4c0f5698" - integrity sha512-wMJ7Bl+AxgIDojp0VxuQxjpNulKodwxGXSsTyxA9Mwzwemj5vKAgTbkPT64ZW5ORf8FOQAaPRlMiTADrPEo3sQ== + version "3.4.7" + resolved "https://registry.yarnpkg.com/rc-virtual-list/-/rc-virtual-list-3.4.7.tgz#ca0ba5ecddff686cd3833562d07c2678d1c9cb2e" + integrity sha512-PhV8a8g/L9sCmWcmXizzwW7QdqsxK4ebHU6fA9OsUIR7isFdx2bTGU2iAUdRV4teiIF1ZHF3gSQh8NtAxrXh6A== dependencies: classnames "^2.2.6" rc-resize-observer "^1.0.0" @@ -14382,12 +14539,12 @@ react-dom@^18.1.0: scheduler "^0.22.0" react-draggable@^4.4.3: - version "4.4.4" - resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.4.tgz#5b26d9996be63d32d285a426f41055de87e59b2f" - integrity sha512-6e0WdcNLwpBx/YIDpoyd2Xb04PB0elrDrulKUgdrIlwuYvxh5Ok9M+F8cljm8kPXXs43PmMzek9RrB1b7mLMqA== + version "4.4.5" + resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.5.tgz#9e37fe7ce1a4cf843030f521a0a4cc41886d7e7c" + integrity sha512-OMHzJdyJbYTZo4uQE393fHcqqPYsEtkjfMgvCHr6rejT+Ezn4OZbNyGH50vv+SunC1RMvwOTSWkEODQLzw1M9g== dependencies: clsx "^1.1.1" - prop-types "^15.6.0" + prop-types "^15.8.1" react-element-to-jsx-string@^14.3.4: version "14.3.4" @@ -14438,6 +14595,11 @@ react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@^18.0.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" + integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== + react-json-view@^1.21.3: version "1.21.3" resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.21.3.tgz#f184209ee8f1bf374fb0c41b0813cff54549c475" @@ -14470,9 +14632,9 @@ react-popper-tooltip@^3.1.1: react-popper "^2.2.4" react-popper@^2.2.4: - version "2.2.5" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.2.5.tgz#1214ef3cec86330a171671a4fbcbeeb65ee58e96" - integrity sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw== + version "2.3.0" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.3.0.tgz#17891c620e1320dce318bad9fede46a5f71c70ba" + integrity sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q== dependencies: react-fast-compare "^3.0.1" warning "^4.0.2" @@ -14490,15 +14652,15 @@ react-router-config@^5.1.1: "@babel/runtime" "^7.1.2" react-router-dom@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.0.tgz#da1bfb535a0e89a712a93b97dd76f47ad1f32363" - integrity sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ== + version "5.3.1" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.1.tgz#0151baf2365c5fcd8493f6ec9b9b31f34d0f8ae1" + integrity sha512-f0pj/gMAbv9e8gahTmCEY20oFhxhrmHwYeIwH5EO5xu0qme+wXtsdB8YfUOAZzUz4VaXmb58m3ceiLtjMhqYmQ== dependencies: "@babel/runtime" "^7.12.13" history "^4.9.0" loose-envify "^1.3.1" prop-types "^15.6.2" - react-router "5.2.1" + react-router "5.3.1" tiny-invariant "^1.0.2" tiny-warning "^1.0.0" @@ -14510,10 +14672,10 @@ react-router-dom@^6.0.0: history "^5.2.0" react-router "6.3.0" -react-router@5.2.1, react-router@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.1.tgz#4d2e4e9d5ae9425091845b8dbc6d9d276239774d" - integrity sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ== +react-router@5.3.1, react-router@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.3.1.tgz#b13e84a016c79b9e80dde123ca4112c4f117e3cf" + integrity sha512-v+zwjqb7bakqgF+wMVKlAPTca/cEmPOvQ9zt7gpSNyPXau1+0qvuYZ5BWzzNDP1y6s15zDwgb9rPN63+SIniRQ== dependencies: "@babel/runtime" "^7.12.13" history "^4.9.0" @@ -14782,12 +14944,13 @@ regex-parser@^2.2.11: integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== regexp.prototype.flags@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.2.tgz#bf635117a2f4b755595ebb0c0ee2d2a49b2084db" - integrity sha512-Ynz8fTQW5/1elh+jWU2EDDzeoNbD0OQ0R+D1VJU5ATOkUaro4A9YEkdN2ODQl/8UQFPPpZNw91fOcLFamM7Pww== + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" + functions-have-names "^1.2.2" regexpp@^3.2.0: version "3.2.0" @@ -15163,9 +15326,9 @@ rollup-plugin-terser@^7.0.0: terser "^5.0.0" rollup@^2.43.1: - version "2.70.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.70.1.tgz#824b1f1f879ea396db30b0fc3ae8d2fead93523e" - integrity sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA== + version "2.70.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.70.2.tgz#808d206a8851628a065097b7ba2053bd83ba0c0d" + integrity sha512-EitogNZnfku65I1DD5Mxe8JYRUCy0hkK5X84IlDtUs+O6JRMpRciXTzyCUuX11b5L5pvjH+OmFXiQ3XjabcXgg== optionalDependencies: fsevents "~2.3.2" @@ -15396,25 +15559,6 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -send@0.17.2, send@^0.17.1: - version "0.17.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" - integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "1.8.1" - mime "1.6.0" - ms "2.1.3" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - send@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" @@ -15434,6 +15578,25 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" +send@^0.17.1: + version "0.17.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" + integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "1.8.1" + mime "1.6.0" + ms "2.1.3" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + serialize-javascript@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" @@ -15493,17 +15656,7 @@ serve-index@^1.9.1: mime-types "~2.1.17" parseurl "~1.3.2" -serve-static@1.14.2: - version "1.14.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" - integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.2" - -serve-static@^1.14.1: +serve-static@1.15.0, serve-static@^1.14.1: version "1.15.0" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== @@ -15759,12 +15912,12 @@ source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.7.3, source-map@~0.7.2: +source-map@^0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== -source-map@^0.8.0-beta.0: +source-map@^0.8.0-beta.0, source-map@~0.8.0-beta.0: version "0.8.0-beta.0" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== @@ -15909,9 +16062,9 @@ statuses@2.0.1: integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= std-env@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.0.1.tgz#bc4cbc0e438610197e34c2d79c3df30b491f5182" - integrity sha512-mC1Ps9l77/97qeOZc+HrOL7TIaOboHqMZ24dGVQrlxFcpPpfCHpH+qfUT7Dz+6mlG8+JPA1KfBQo19iC/+Ngcw== + version "3.1.1" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.1.1.tgz#1f19c4d3f6278c52efd08a94574a2a8d32b7d092" + integrity sha512-/c645XdExBypL01TpFKiG/3RAa/Qmu+zRi0MwAmrdEkwHNuN0ebo8ccAXBBDa5Z0QOJgBskUIbuCK91x0sCVEw== store2@^2.12.0: version "2.13.2" @@ -16441,13 +16594,13 @@ terser@^4.1.2, terser@^4.6.3: source-map-support "~0.5.12" terser@^5.0.0, terser@^5.10.0, terser@^5.3.4, terser@^5.7.2: - version "5.12.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.12.1.tgz#4cf2ebed1f5bceef5c83b9f60104ac4a78b49e9c" - integrity sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ== + version "5.13.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.13.0.tgz#d43fd71861df1b4df743980caa257c6fa03acc44" + integrity sha512-sgQ99P+fRBM1jAYzN9RTnD/xEWx/7LZgYTCRgmYriSq1wxxqiQPJgXkkLBBuwySDWJ2PP0PnVQyuf4xLUuH4Ng== dependencies: acorn "^8.5.0" commander "^2.20.0" - source-map "~0.7.2" + source-map "~0.8.0-beta.0" source-map-support "~0.5.20" test-exclude@^6.0.0: @@ -16713,7 +16866,12 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.2.0, tslib@^2.3.0, tslib@^2.3.1, tslib@~2.3.1: +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.2.0, tslib@^2.3.0, tslib@^2.3.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + +tslib@~2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== @@ -16820,13 +16978,13 @@ uglify-js@^3.1.4: integrity sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA== unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" unfetch@^4.2.0: @@ -17093,21 +17251,21 @@ urlgrey@1.0.0: fast-url-parser "^1.1.3" use-composed-ref@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.2.1.tgz#9bdcb5ccd894289105da2325e1210079f56bf849" - integrity sha512-6+X1FLlIcjvFMAeAD/hcxDT8tmyrWnbSPMU0EnxQuDLIxokuFzWliXBiYZuGIx+mrAMLBw0WFfCkaPw8ebzAhw== + version "1.3.0" + resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.3.0.tgz#3d8104db34b7b264030a9d916c5e94fbe280dbda" + integrity sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ== -use-isomorphic-layout-effect@^1.0.0: +use-isomorphic-layout-effect@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb" integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA== use-latest@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.2.0.tgz#a44f6572b8288e0972ec411bdd0840ada366f232" - integrity sha512-d2TEuG6nSLKQLAfW3By8mKr8HurOlTkul0sOpxbClIv4SQ4iOd7BYr7VIzdbktUCnv7dua/60xzd8igMU6jmyw== + version "1.2.1" + resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.2.1.tgz#d13dfb4b08c28e3e33991546a2cee53e14038cf2" + integrity sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw== dependencies: - use-isomorphic-layout-effect "^1.0.0" + use-isomorphic-layout-effect "^1.1.1" use@^3.1.0: version "3.1.1" @@ -17191,7 +17349,7 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== -v8-to-istanbul@^8.0.0, v8-to-istanbul@^8.1.0: +v8-to-istanbul@^8.1.0: version "8.1.1" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== @@ -17200,6 +17358,15 @@ v8-to-istanbul@^8.0.0, v8-to-istanbul@^8.1.0: convert-source-map "^1.6.0" source-map "^0.7.3" +v8-to-istanbul@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz#be0dae58719fc53cb97e5c7ac1d7e6d4f5b19511" + integrity sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw== + dependencies: + "@jridgewell/trace-mapping" "^0.3.7" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -18368,7 +18535,7 @@ yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs-parser@20.x, yargs-parser@^20.2.2, yargs-parser@^20.2.7: +yargs-parser@20.x, yargs-parser@^20.2.2, yargs-parser@^20.2.9: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== From b9c1f8d7272213a9243e39767dfe6c86ed455ded Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Thu, 28 Apr 2022 20:26:40 +0000 Subject: [PATCH 039/146] Move around declarations to be a bit more readable --- packages/squiggle-lang/src/js/index.ts | 233 +++++++++--------- .../src/rescript/TypescriptInterface.res | 6 + 2 files changed, 125 insertions(+), 114 deletions(-) diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 57c09e1a..bc66ab99 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -10,6 +10,9 @@ import { continuousShape, discreteShape, distributionErrorToString, + mixedShape, + sampleSetDist, + symbolicDist, } from "../rescript/TypescriptInterface.gen"; export { makeSampleSetDist, @@ -50,67 +53,6 @@ export let defaultSamplingInputs: samplingParams = { xyPointLength: 10000, }; -import type { t as SampleSetDist_t } from "../rescript/Distributions/SampleSetDist/SampleSetDist.gen"; -import type { mixedShape } from "../rescript/Distributions/PointSetDist/PointSetTypes.gen"; - -import type { symbolicDist as SymbolicDistTypes_symbolicDist } from "../rescript/Distributions/SymbolicDist/SymbolicDistTypes.gen"; - -type rescriptPointSetDist = - | { - TAG: 0; // Mixed - _0: mixedShape; - } - | { - TAG: 1; // Discrete - _0: discreteShape; - } - | { - TAG: 2; // ContinuousShape - _0: continuousShape; - }; - -type rescriptDist = - | { TAG: 0; _0: rescriptPointSetDist } - | { TAG: 1; _0: SampleSetDist_t } - | { TAG: 2; _0: SymbolicDistTypes_symbolicDist }; - -// This is a raw rescript export. genType for some reason only converts half -// the data structure into the format it claims it is. This here is so that -// we can be guided in converting the other half -type rescriptExport = - | { - TAG: 0; // EvArray - _0: rescriptExport[]; - } - | { - TAG: 1; // EvBool - _0: boolean; - } - | { - TAG: 2; // EvCall - _0: string; - } - | { - TAG: 3; // EvDistribution - _0: rescriptDist; - } - | { - TAG: 4; // EvNumber - _0: number; - } - | { - TAG: 5; // EvRecord - _0: { [key: string]: rescriptExport }; - } - | { - TAG: 6; // EvString - _0: string; - } - | { - TAG: 7; // EvSymbol - _0: string; - }; - export type result = | { tag: "Ok"; @@ -163,7 +105,69 @@ export function run( return resultMap(result, (x) => createTsExport(x, si)); } -// Recript half converts recursive data structures +function createTsExport( + x: expressionValue, + sampEnv: samplingParams +): squiggleExpression { + switch (x.tag) { + case "EvArray": + // genType doesn't convert anything more than 2 layers down into {tag: x, value: x} + // format, leaving it as the raw values. This converts the raw values + // directly into typescript values. + // + // The casting here is because genType is about the types of the returned + // values, claiming they are fully recursive when that's not actually the + // case + return tag( + "array", + x.value.map((arrayItem): squiggleExpression => { + switch (arrayItem.tag) { + case "EvRecord": + return tag( + "record", + _.mapValues(arrayItem.value, (recordValue: unknown) => + convertRawToTypescript(recordValue as rescriptExport, sampEnv) + ) + ); + case "EvArray": + let y = arrayItem.value as unknown as rescriptExport[]; + return tag( + "array", + y.map((childArrayItem) => + convertRawToTypescript(childArrayItem, sampEnv) + ) + ); + default: + return createTsExport(arrayItem, sampEnv); + } + }) + ); + case "EvBool": + return tag("boolean", x.value); + case "EvCall": + return tag("call", x.value); + case "EvDistribution": + return tag("distribution", new Distribution(x.value, sampEnv)); + case "EvNumber": + return tag("number", x.value); + case "EvRecord": + // genType doesn't support records, so we have to do the raw conversion ourself + let result: tagged<"record", { [key: string]: squiggleExpression }> = tag( + "record", + _.mapValues(x.value, (x: unknown) => + convertRawToTypescript(x as rescriptExport, sampEnv) + ) + ); + return result; + case "EvString": + return tag("string", x.value); + case "EvSymbol": + return tag("symbol", x.value); + } +} + +// Helper functions to convert the recsript representations that genType doesn't +// cover function convertRawToTypescript( result: rescriptExport, sampEnv: samplingParams @@ -220,58 +224,59 @@ function convertRawDistributionToGenericDist( } } -function createTsExport( - x: expressionValue, - sampEnv: samplingParams -): squiggleExpression { - switch (x.tag) { - case "EvArray": - return tag( - "array", - x.value.map((arrayItem): squiggleExpression => { - switch (arrayItem.tag) { - case "EvRecord": - return tag( - "record", - _.mapValues(arrayItem.value, (recordValue: unknown) => - convertRawToTypescript(recordValue as rescriptExport, sampEnv) - ) - ); - case "EvArray": - let y = arrayItem.value as unknown as rescriptExport[]; - return tag( - "array", - y.map((childArrayItem) => - convertRawToTypescript(childArrayItem, sampEnv) - ) - ); - default: - return createTsExport(arrayItem, sampEnv); - } - }) - ); - case "EvBool": - return tag("boolean", x.value); - case "EvCall": - return tag("call", x.value); - case "EvDistribution": - return tag("distribution", new Distribution(x.value, sampEnv)); - case "EvNumber": - return tag("number", x.value); - case "EvRecord": - let result: tagged<"record", { [key: string]: squiggleExpression }> = tag( - "record", - _.mapValues(x.value, (x: unknown) => - convertRawToTypescript(x as rescriptExport, sampEnv) - ) - ); - return result; - case "EvString": - return tag("string", x.value); - case "EvSymbol": - return tag("symbol", x.value); - } -} +// Raw rescript types. +type rescriptExport = + | { + TAG: 0; // EvArray + _0: rescriptExport[]; + } + | { + TAG: 1; // EvBool + _0: boolean; + } + | { + TAG: 2; // EvCall + _0: string; + } + | { + TAG: 3; // EvDistribution + _0: rescriptDist; + } + | { + TAG: 4; // EvNumber + _0: number; + } + | { + TAG: 5; // EvRecord + _0: { [key: string]: rescriptExport }; + } + | { + TAG: 6; // EvString + _0: string; + } + | { + TAG: 7; // EvSymbol + _0: string; + }; + +type rescriptDist = + | { TAG: 0; _0: rescriptPointSetDist } + | { TAG: 1; _0: sampleSetDist } + | { TAG: 2; _0: symbolicDist }; + +type rescriptPointSetDist = + | { + TAG: 0; // Mixed + _0: mixedShape; + } + | { + TAG: 1; // Discrete + _0: discreteShape; + } + | { + TAG: 2; // ContinuousShape + _0: continuousShape; + }; export function resultExn(r: result): a | c { return r.value; diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index fc381729..c4265178 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -13,6 +13,12 @@ type samplingParams = DistributionOperation.env @genType type genericDist = DistributionTypes.genericDist +@genType +type sampleSetDist = SampleSetDist.t + +@genType +type symbolicDist = SymbolicDistTypes.symbolicDist + @genType type distributionError = DistributionTypes.error From 911fb5bcc677963ab86f91af8654abbc249a6775 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Thu, 28 Apr 2022 16:40:19 -0400 Subject: [PATCH 040/146] Should fix lint Value: [1e-6 to 1e-5] --- yarn.lock | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4ce8009f..cbd03955 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2400,18 +2400,17 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64" integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw== -"@quri/squiggle-lang@0.2.5": - version "0.2.5" - resolved "https://registry.yarnpkg.com/@quri/squiggle-lang/-/squiggle-lang-0.2.5.tgz#368f0644290a0265696db7547ea31b0a0b55a69e" - integrity sha512-yBCqjieirDE4oDZVICGQh2r1A6vS6GM5y8Pc0IhHGnNBbs230iA/b+eytQTGbEE7yVEvHbDNBUoiB+B7sCPzaQ== +"@quri/squiggle-components@0.2.9": + version "0.2.9" + resolved "https://registry.yarnpkg.com/@quri/squiggle-components/-/squiggle-components-0.2.9.tgz#9a2c7ce824ad59f980dc73e465676bd2563d409c" + integrity sha512-RpMTCzf7vBY+fatdjD+iFWkleMYOkJQN7kknZlLBriSo8Fy5KjhKghR+DotU+HE/2Yq1jUIveaIDF0XRBg+SVA== dependencies: - bisect_ppx "^2.7.1" - jstat "^1.9.5" - lodash "4.17.21" - mathjs "10.5.0" - pdfast "^0.2.0" - rationale "0.2.0" - rescript "^9.1.4" + "@react-hook/size" "^2.1.2" + antd "^4.20.0" + react "^18.0.0" + react-ace "10.0.0" + react-dom "^18.0.0" + styled-components "^5.3.5" "@react-hook/latest@^1.0.2": version "1.0.3" @@ -5006,7 +5005,7 @@ ansi-to-html@^0.6.11: dependencies: entities "^2.0.0" -antd@^4.20.1: +antd@^4.20.0, antd@^4.20.1: version "4.20.1" resolved "https://registry.yarnpkg.com/antd/-/antd-4.20.1.tgz#6cd5a406c7172d61a5d0693ea52ee908650cf674" integrity sha512-asKxOV0a6AijqonbcXkO08/q+XvqS/HmGfaRIS6ZH1ALR3FS2q+kTW52rJZO9rfoOb/ldPhEBVSWiNrbiB+uCQ== @@ -14041,11 +14040,6 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -rationale@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/rationale/-/rationale-0.2.0.tgz#555ed4f3cc7cd0245faeac041d3769f1857e4f3d" - integrity sha512-Pd8w5Inv1JhTfRyx03zs486CEAn6UKXvvOtxVRLsewngsBSffo3MQwUKYS75L/8vPt98wmf7iaZROx362/f7Bw== - raw-body@2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" @@ -14441,6 +14435,17 @@ rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-ace@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/react-ace/-/react-ace-10.0.0.tgz#1760e302604cff35ba40963db43eb027513b6572" + integrity sha512-AUoA2OsKOCv8fXLqcFM232dF/Z8w14bwPUZ9z5I2zjBfqfZOZLqxnhXN+qKL6VrQXs1DLUvalGOuM5TABAFOCA== + dependencies: + ace-builds "^1.4.14" + diff-match-patch "^1.0.5" + lodash.get "^4.4.2" + lodash.isequal "^4.5.0" + prop-types "^15.7.2" + react-ace@10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/react-ace/-/react-ace-10.1.0.tgz#d348eac2b16475231779070b6cd16768deed565f" @@ -14530,7 +14535,7 @@ react-docgen@^5.0.0: node-dir "^0.1.10" strip-indent "^3.0.0" -react-dom@^18.1.0: +react-dom@^18.0.0, react-dom@^18.1.0: version "18.1.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.1.0.tgz#7f6dd84b706408adde05e1df575b3a024d7e8a2f" integrity sha512-fU1Txz7Budmvamp7bshe4Zi32d0ll7ect+ccxNu9FlObT605GOEB8BfO4tmRJ39R5Zj831VCpvQ05QPBW5yb+w== From 94d4a38540fa0425f1412da4f02c62ee804be671 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 28 Apr 2022 16:49:51 -0400 Subject: [PATCH 041/146] Refactored errors for XYShape --- .../squiggle-lang/__tests__/XYShape_test.res | 17 +++--- .../Distributions/DistributionTypes.res | 2 + .../squiggle-lang/src/rescript/Utility/E.res | 6 ++ .../src/rescript/Utility/Errors.res | 31 ---------- .../src/rescript/Utility/XYShape.res | 59 +++++++++++++++---- 5 files changed, 66 insertions(+), 49 deletions(-) delete mode 100644 packages/squiggle-lang/src/rescript/Utility/Errors.res diff --git a/packages/squiggle-lang/__tests__/XYShape_test.res b/packages/squiggle-lang/__tests__/XYShape_test.res index c63e1ce2..38535020 100644 --- a/packages/squiggle-lang/__tests__/XYShape_test.res +++ b/packages/squiggle-lang/__tests__/XYShape_test.res @@ -18,21 +18,22 @@ let pointSetDist3: PointSetTypes.xyShape = { ys: [0.2, 0.5, 0.8], } +let makeAndGetErrorString = (~xs, ~ys) => + XYShape.T.make(~xs, ~ys)->E.R.getError->E.O2.fmap(XYShape.Error.toString) + describe("XYShapes", () => { describe("Validator", () => { - makeTest("with no errors", XYShape.T.Validator.validate(pointSetDist1), None) makeTest( - "when empty", - XYShape.T.Validator.validate({xs: [], ys: []})->E.O2.fmap(Errors.toString), - Some("XYShape validate Xs is empty"), + "with no errors", + makeAndGetErrorString(~xs=[1.0, 4.0, 8.0], ~ys=[0.2, 0.4, 0.8]), + None, ) + makeTest("when empty", makeAndGetErrorString(~xs=[], ~ys=[]), Some("Xs is empty")) makeTest( "when not sorted, different lengths, and not finite", - XYShape.T.Validator.validate({xs: [2.0, 1.0, infinity, 0.0], ys: [3.0, Js.Float._NaN]})->E.O2.fmap( - Errors.toString, - ), + makeAndGetErrorString(~xs=[2.0, 1.0, infinity, 0.0], ~ys=[3.0, Js.Float._NaN]), Some( - "Multiple Errors: [XYShape validate Xs is not sorted], [XYShape validate Xs and Ys have different lengths. Xs has length 4 and Ys has length 2], [XYShape validate Xs is not finite. Example value: Infinity], [XYShape validate Ys is not finite. Example value: NaN]", + "Multiple Errors: [Xs is not sorted], [Xs and Ys have different lengths. Xs has length 4 and Ys has length 2], [Xs is not finite. Example value: Infinity], [Ys is not finite. Example value: NaN]", ), ) }) diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res index e27a138d..93f86798 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res @@ -19,6 +19,7 @@ type error = | RequestedStrategyInvalidError(string) | LogarithmOfDistributionError(string) | OtherError(string) + | XYShapeError(XYShape.error) @genType module Error = { @@ -39,6 +40,7 @@ module Error = { | PointSetConversionError(err) => SampleSetDist.pointsetConversionErrorToString(err) | SparklineError(err) => PointSetTypes.sparklineErrorToString(err) | RequestedStrategyInvalidError(err) => `Requested strategy invalid: ${err}` + | XYShapeError(err) => `XY Shape Error: ${XYShape.Error.toString(err)}` | OtherError(s) => s } diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index aab3d160..35699c5c 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -162,6 +162,12 @@ exception Assertion(string) module R = { let result = Rationale.Result.result let id = e => e |> result(U.id, U.id) + let isOk = Belt.Result.isOk + let getError = (r: result<'a, 'b>) => + switch r { + | Ok(_) => None + | Error(e) => Some(e) + } let fmap = Rationale.Result.fmap let bind = Rationale.Result.bind let toExn = (msg: string, x: result<'a, 'b>): 'a => diff --git a/packages/squiggle-lang/src/rescript/Utility/Errors.res b/packages/squiggle-lang/src/rescript/Utility/Errors.res deleted file mode 100644 index bdd41869..00000000 --- a/packages/squiggle-lang/src/rescript/Utility/Errors.res +++ /dev/null @@ -1,31 +0,0 @@ -type property = {fnName: string, propertyName: string} - -type rec error = - | NotSorted(property) - | IsEmpty(property) - | NotFinite(property, float) - | DifferentLengths({fnName: string, p1Name: string, p2Name: string, p1Length: int, p2Length: int}) - | Multiple(array) - -let mapErrorArrayToError = (errors: array): option => { - switch errors { - | [] => None - | [error] => Some(error) - | _ => Some(Multiple(errors)) - } -} - -let rec toString = (t: error) => - switch t { - | NotSorted({fnName, propertyName}) => `${fnName} ${propertyName} is not sorted` - | IsEmpty({fnName, propertyName}) => `${fnName} ${propertyName} is empty` - | NotFinite({fnName, propertyName}, exampleValue) => - `${fnName} ${propertyName} is not finite. Example value: ${E.Float.toString(exampleValue)}` - | DifferentLengths({fnName, p1Name, p2Name, p1Length, p2Length}) => - `${fnName} ${p1Name} and ${p2Name} have different lengths. ${p1Name} has length ${E.I.toString( - p1Length, - )} and ${p2Name} has length ${E.I.toString(p2Length)}` - | Multiple(errors) => - `Multiple Errors: ${E.A2.fmap(errors, toString)->E.A2.fmap(r => `[${r}]`) - |> E.A.joinWith(", ")}` - } diff --git a/packages/squiggle-lang/src/rescript/Utility/XYShape.res b/packages/squiggle-lang/src/rescript/Utility/XYShape.res index 1d96a3ee..1f1e87ca 100644 --- a/packages/squiggle-lang/src/rescript/Utility/XYShape.res +++ b/packages/squiggle-lang/src/rescript/Utility/XYShape.res @@ -4,6 +4,42 @@ type xyShape = { ys: array, } +type propertyName = string + +@genType +type rec error = + | NotSorted(propertyName) + | IsEmpty(propertyName) + | NotFinite(propertyName, float) + | DifferentLengths({p1Name: string, p2Name: string, p1Length: int, p2Length: int}) + | MultipleErrors(array) + +@genType +module Error = { + let mapErrorArrayToError = (errors: array): option => { + switch errors { + | [] => None + | [error] => Some(error) + | _ => Some(MultipleErrors(errors)) + } + } + + let rec toString = (t: error) => + switch t { + | NotSorted(propertyName) => `${propertyName} is not sorted` + | IsEmpty(propertyName) => `${propertyName} is empty` + | NotFinite(propertyName, exampleValue) => + `${propertyName} is not finite. Example value: ${E.Float.toString(exampleValue)}` + | DifferentLengths({p1Name, p2Name, p1Length, p2Length}) => + `${p1Name} and ${p2Name} have different lengths. ${p1Name} has length ${E.I.toString( + p1Length, + )} and ${p2Name} has length ${E.I.toString(p2Length)}` + | MultipleErrors(errors) => + `Multiple Errors: ${E.A2.fmap(errors, toString)->E.A2.fmap(r => `[${r}]`) + |> E.A.joinWith(", ")}` + } +} + @genType type interpolationStrategy = [ | #Stepwise @@ -63,15 +99,10 @@ module T = { module Validator = { let fnName = "XYShape validate" - let property = (propertyName: string): Errors.property => { - fnName: fnName, - propertyName: propertyName, - } - let notSortedError = (p: string): Errors.error => NotSorted(property(p)) - let notFiniteError = (p, exampleValue): Errors.error => NotFinite(property(p), exampleValue) - let isEmptyError = (propertyName): Errors.error => IsEmpty(property(propertyName)) - let differentLengthsError = (t): Errors.error => DifferentLengths({ - fnName: fnName, + let notSortedError = (p: string): error => NotSorted(p) + let notFiniteError = (p, exampleValue): error => NotFinite(p, exampleValue) + let isEmptyError = (propertyName): error => IsEmpty(propertyName) + let differentLengthsError = (t): error => DifferentLengths({ p1Name: "Xs", p2Name: "Ys", p1Length: E.A.length(xs(t)), @@ -92,7 +123,15 @@ module T = { let ysNotFinite = getNonFiniteYs(t)->E.O2.fmap(notFiniteError("Ys")) [xsNotSorted, xsEmpty, differentLengths, xsNotFinite, ysNotFinite] ->E.A.O.concatSomes - ->Errors.mapErrorArrayToError + ->Error.mapErrorArrayToError + } + } + + let make = (~xs: array, ~ys: array) => { + let attempt: t = {xs: xs, ys: ys} + switch Validator.validate(attempt) { + | Some(error) => Error(error) + | None => Ok(attempt) } } } From b894f78466b8d0e1edb3fc81876a2af08a6a50b5 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Thu, 28 Apr 2022 16:57:27 -0400 Subject: [PATCH 042/146] Changed `0.2.6` to `^0.2.6` for squiggle-lang dep Value: [1e-3 to 1e-1] --- packages/components/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/package.json b/packages/components/package.json index 5d21b9cc..218747b9 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -5,7 +5,7 @@ "dependencies": { "antd": "^4.20.1", "react-ace": "10.1.0", - "@quri/squiggle-lang": "0.2.6", + "@quri/squiggle-lang": "^0.2.6", "react-dom": "^18.1.0", "vega": "^5.22.1", "vega-embed": "^6.20.6", From 6e9315170f68361c1888a931e780a2904458f7b6 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Thu, 28 Apr 2022 17:25:47 -0400 Subject: [PATCH 043/146] Spelling license correctly Value: [1e-7 to 1e-5] --- packages/squiggle-lang/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index f5002481..b9941b0f 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -2,7 +2,7 @@ "name": "@quri/squiggle-lang", "version": "0.2.6", "homepage": "https://squiggle-language.com", - "licence": "MIT", + "license": "MIT", "scripts": { "build": "rescript build -with-deps && tsc", "bundle": "webpack", From c4ee0959ec5b61893af74d7e248b7e558350946c Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Thu, 28 Apr 2022 17:28:37 -0400 Subject: [PATCH 044/146] `dist/js/index.d.ts` => `dist/src/js/index.d.ts` Value: [1e-4 to 5e-3] --- packages/squiggle-lang/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index b9941b0f..4d146ef8 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -1,6 +1,6 @@ { "name": "@quri/squiggle-lang", - "version": "0.2.6", + "version": "0.2.7", "homepage": "https://squiggle-language.com", "license": "MIT", "scripts": { @@ -62,5 +62,5 @@ }, "source": "./src/js/index.ts", "main": "./dist/src/js/index.js", - "types": "./dist/js/index.d.ts" + "types": "./dist/src/js/index.d.ts" } From fde75d4bc3e52b1fa720fe4f75239b41044016a7 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Thu, 28 Apr 2022 17:54:43 -0400 Subject: [PATCH 045/146] No antd and everything compiles Value: [1e-3 to 3e-2] --- packages/components/package.json | 3 +-- .../src/components/SquigglePlayground.tsx | 26 ++++++++++++++----- yarn.lock | 2 +- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 218747b9..4a71a150 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -3,9 +3,8 @@ "version": "0.2.13", "license": "MIT", "dependencies": { - "antd": "^4.20.1", "react-ace": "10.1.0", - "@quri/squiggle-lang": "^0.2.6", + "@quri/squiggle-lang": "^0.2.7", "react-dom": "^18.1.0", "vega": "^5.22.1", "vega-embed": "^6.20.6", diff --git a/packages/components/src/components/SquigglePlayground.tsx b/packages/components/src/components/SquigglePlayground.tsx index 93e8e9c6..30833ae7 100644 --- a/packages/components/src/components/SquigglePlayground.tsx +++ b/packages/components/src/components/SquigglePlayground.tsx @@ -1,11 +1,11 @@ import _ from "lodash"; -import React, { FC, useState } from "react"; +import React, { FC, ReactElement, useState } from "react"; import ReactDOM from "react-dom"; import { SquiggleChart } from "./SquiggleChart"; import CodeEditor from "./CodeEditor"; -import { Form, Input, Row, Col } from "antd"; +// import { Form, Input, Row, Col } from "antd"; import styled from "styled-components"; -import "antd/dist/antd.css"; +// import "antd/dist/antd.css"; interface FieldFloatProps { label: string; @@ -14,10 +14,19 @@ interface FieldFloatProps { onChange: (value: number) => void; } +const Input = styled.input`` + +const FormItem = (props: {label:string, children:ReactElement}) => ( +
+ + {props.children} +
+) + function FieldFloat(Props: FieldFloatProps) { let [contents, setContents] = useState(Props.value + ""); return ( - + - + ); } @@ -65,6 +74,9 @@ const Display = styled.div` max-height: ${(props) => props.maxHeight}px; `; +const Row = styled.div`` +const Col = styled.div`` + let SquigglePlayground: FC = ({ initialSquiggleString = "", height = 300, @@ -79,7 +91,7 @@ let SquigglePlayground: FC = ({ return ( - + = ({ height={height - 3} /> - + Date: Thu, 28 Apr 2022 18:25:01 -0400 Subject: [PATCH 046/146] fixed width stuff, playground, and fonts after antd factor-out Value: [1e-3 to 2e-2] --- .../src/components/DistributionChart.tsx | 9 ++++++--- .../components/src/components/SquiggleChart.tsx | 16 ++++++++-------- .../src/components/SquigglePlayground.tsx | 17 +++++++++-------- .../src/vega-specs/spec-distributions.json | 1 + 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index a27f325a..6bef36c7 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -6,6 +6,7 @@ import { distributionErrorToString } from "@quri/squiggle-lang"; import { createClassFromSpec } from "react-vega"; import * as chartSpecification from "../vega-specs/spec-distributions.json"; import { ErrorBox } from "./ErrorBox"; +import styled from "styled-components"; let SquiggleVegaChart = createClassFromSpec({ spec: chartSpecification as Spec, @@ -24,19 +25,21 @@ export const DistributionChart: React.FC = ({ }: DistributionChartProps) => { let shape = distribution.pointSet(); if (shape.tag === "Ok") { - return ( + let widthProp = width ? width - 20 : undefined; + var result = ( ); } else { - return ( + var result = ( {distributionErrorToString(shape.value)} ); } + return result; }; diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 7dda92e4..137f23c0 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -150,6 +150,12 @@ export interface SquiggleChartProps { height?: number; } +const ChartWrapper = styled.div` + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, + "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", + "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +`; + export const SquiggleChart: React.FC = ({ squiggleString = "", sampleCount = 1000, @@ -158,11 +164,6 @@ export const SquiggleChart: React.FC = ({ height = 60, width = NaN, }: SquiggleChartProps) => { - const target = React.useRef(null); - const [componentWidth] = useSize(target); - // I would have wanted to just use componentWidth, but this created infinite loops with SquiggleChart.stories. - //So you can manually add a width, as an escape hatch. - let _width = width || componentWidth; let samplingInputs: samplingParams = { sampleCount: sampleCount, xyPointLength: outputXYPoints, @@ -173,15 +174,14 @@ export const SquiggleChart: React.FC = ({ let expression = expressionResult.value; onChange(expression); internal = ( - + ); } else { - // At this point, we came across an error. What was our error? internal = ( {errorValueToString(expressionResult.value)} ); } - return
{internal}
; + return {internal}; }; diff --git a/packages/components/src/components/SquigglePlayground.tsx b/packages/components/src/components/SquigglePlayground.tsx index 30833ae7..a8ad84d5 100644 --- a/packages/components/src/components/SquigglePlayground.tsx +++ b/packages/components/src/components/SquigglePlayground.tsx @@ -3,9 +3,7 @@ import React, { FC, ReactElement, useState } from "react"; import ReactDOM from "react-dom"; import { SquiggleChart } from "./SquiggleChart"; import CodeEditor from "./CodeEditor"; -// import { Form, Input, Row, Col } from "antd"; import styled from "styled-components"; -// import "antd/dist/antd.css"; interface FieldFloatProps { label: string; @@ -14,14 +12,14 @@ interface FieldFloatProps { onChange: (value: number) => void; } -const Input = styled.input`` +const Input = styled.input``; -const FormItem = (props: {label:string, children:ReactElement}) => ( +const FormItem = (props: { label: string; children: ReactElement }) => (
{props.children} -
-) + +); function FieldFloat(Props: FieldFloatProps) { let [contents, setContents] = useState(Props.value + ""); @@ -74,8 +72,11 @@ const Display = styled.div` max-height: ${(props) => props.maxHeight}px; `; -const Row = styled.div`` -const Col = styled.div`` +const Row = styled.div` + display: grid; + grid-template-columns: 1fr 1fr; +`; +const Col = styled.div``; let SquigglePlayground: FC = ({ initialSquiggleString = "", diff --git a/packages/components/src/vega-specs/spec-distributions.json b/packages/components/src/vega-specs/spec-distributions.json index ef30bdf2..129183a5 100644 --- a/packages/components/src/vega-specs/spec-distributions.json +++ b/packages/components/src/vega-specs/spec-distributions.json @@ -3,6 +3,7 @@ "description": "A basic area chart example", "width": 500, "height": 100, + "autosize": "fit", "padding": 5, "data": [ { From 1d5a0a30d4e766d052827b3dbd54b413980e7e82 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Thu, 28 Apr 2022 19:06:39 -0400 Subject: [PATCH 047/146] version increment; piggyback README.md improvements Value: [1e-5 to 6e-4] --- README.md | 18 ++++++++++++++---- packages/components/README.md | 21 +++++++++++++++++++-- packages/components/package.json | 2 +- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2f1de7f7..137fb1cb 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,22 @@ # Squiggle [![Packages check](https://github.com/quantified-uncertainty/squiggle/actions/workflows/ci.yml/badge.svg)](https://github.com/quantified-uncertainty/squiggle/actions/workflows/ci.yml) -[![npm version](https://badge.fury.io/js/@quri%2Fsquiggle-lang.svg)](https://www.npmjs.com/package/@quri/squiggle-lang) -[![npm version](https://badge.fury.io/js/@quri%2Fsquiggle-components.svg)](https://www.npmjs.com/package/@quri/squiggle-components) +[![npm version - lang](https://badge.fury.io/js/@quri%2Fsquiggle-lang.svg)](https://www.npmjs.com/package/@quri/squiggle-lang) +[![npm version - components](https://badge.fury.io/js/@quri%2Fsquiggle-components.svg)](https://www.npmjs.com/package/@quri/squiggle-components) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/quantified-uncertainty/squiggle/blob/develop/LICENSE) [![codecov](https://codecov.io/gh/quantified-uncertainty/squiggle/branch/develop/graph/badge.svg?token=QRLBL5CQ7C)](https://codecov.io/gh/quantified-uncertainty/squiggle) -This is an experimental DSL/language for making probabilistic estimates. The full story can be found [here](https://www.lesswrong.com/s/rDe8QE5NvXcZYzgZ3). +_An estimation language_. + +## Get started + +- [Gallery](https://www.squiggle-language.com/docs/Discussions/Gallery) +- [Squiggle playground](https://squiggle-language.com/playground) +- [Language basics](https://www.squiggle-language.com/docs/Features/Language) +- [Squiggle functions source of truth](https://www.squiggle-language.com/docs/Features/Functions) +- [Known bugs](https://www.squiggle-language.com/docs/Discussions/Bugs) +- [Original lesswrong sequence](https://www.lesswrong.com/s/rDe8QE5NvXcZYzgZ3) +- [Author your squiggle models as Observable notebooks](https://observablehq.com/@hazelfire/squiggle) ## Our deployments @@ -27,7 +37,7 @@ the packages can be found in `packages`. - `@quri/squiggle-components` in `packages/components` contains React components that can be passed squiggle strings as props, and return a presentation of the result of the calculation. -- `@quri/squiggle-website` in `packages/website` The main descriptive website for squiggle, +- `packages/website` is the main descriptive website for squiggle, it is hosted at `squiggle-language.com`. The playground depends on the components library which then depends on the language. This means that if you wish to work on the components library, you will need to build (no need to bundle) the language, and as of this writing playground doesn't really work. diff --git a/packages/components/README.md b/packages/components/README.md index 282230d9..87c39ebe 100644 --- a/packages/components/README.md +++ b/packages/components/README.md @@ -1,8 +1,26 @@ +[![npm version](https://badge.fury.io/js/@quri%2Fsquiggle-components.svg)](https://www.npmjs.com/package/@quri/squiggle-components) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/quantified-uncertainty/squiggle/blob/develop/LICENSE) + # Squiggle Components This package contains all the components for squiggle. These can be used either as a library or hosted as a [storybook](https://storybook.js.org/). -# Build for development +# Usage in a `react` project + +For example, in a fresh `create-react-app` project + +```sh +yarn add @quri/squiggle-components +``` + +Add to `App.js`: + +```sh +import {SquiggleEditor} from '@quri/squiggle-components'; + +``` + +# Build storybook for development We assume that you had run `yarn` at monorepo level, installing dependencies. @@ -24,6 +42,5 @@ yarn start And build artefacts for production, ```sh -yarn bundle # builds components library yarn build # builds storybook app ``` diff --git a/packages/components/package.json b/packages/components/package.json index 4a71a150..ac70581b 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@quri/squiggle-components", - "version": "0.2.13", + "version": "0.2.14", "license": "MIT", "dependencies": { "react-ace": "10.1.0", From 8bc8fd92283e6b115be2b91b4a731a81f2b1cd2c Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Thu, 28 Apr 2022 19:08:04 -0400 Subject: [PATCH 048/146] wrong syntax highlighting in markdown Value: [1e-8 to 1e-6] --- packages/components/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/README.md b/packages/components/README.md index 87c39ebe..26d73c6b 100644 --- a/packages/components/README.md +++ b/packages/components/README.md @@ -15,7 +15,7 @@ yarn add @quri/squiggle-components Add to `App.js`: -```sh +```jsx import {SquiggleEditor} from '@quri/squiggle-components'; ``` From b15ba6563c77b32c7f0fb6bb1d8847ec44fb9cea Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Thu, 28 Apr 2022 19:15:15 -0400 Subject: [PATCH 049/146] Incremental README.md improvements Value: [1e-7 to 1e-6] --- packages/components/README.md | 4 ++-- packages/squiggle-lang/README.md | 20 +++++++++----------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/packages/components/README.md b/packages/components/README.md index 26d73c6b..ad35c67f 100644 --- a/packages/components/README.md +++ b/packages/components/README.md @@ -16,8 +16,8 @@ yarn add @quri/squiggle-components Add to `App.js`: ```jsx -import {SquiggleEditor} from '@quri/squiggle-components'; - +import { SquiggleEditor } from "@quri/squiggle-components"; +; ``` # Build storybook for development diff --git a/packages/squiggle-lang/README.md b/packages/squiggle-lang/README.md index fcd0c7a2..05bb969c 100644 --- a/packages/squiggle-lang/README.md +++ b/packages/squiggle-lang/README.md @@ -1,3 +1,6 @@ +[![npm version](https://badge.fury.io/js/@quri%2Fsquiggle-lang.svg)](https://www.npmjs.com/package/@quri/squiggle-lang) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/quantified-uncertainty/squiggle/blob/develop/LICENSE) + # Squiggle language ## Build for development @@ -15,13 +18,16 @@ Other: ```sh yarn start # listens to files and recompiles at every mutation yarn test -yarn test:watch # keeps an active session and runs all tests at every mutation # where o := open in osx and o := xdg-open in linux, -yarn coverage; o _coverage/index.html # produces coverage report and opens it in browser +yarn coverage:rescript; o _coverage/index.html # produces coverage report and opens it in browser ``` -## Information +## Distributing this package or using this package from other monorepo packages + +As it says in the other `packages/*/README.md`s, building this package is an essential step of building other packages. + +# Information Squiggle is a language for representing probability distributions, as well as functions that return probability distributions. Its original intended use is for improving epistemics around EA decisions. @@ -34,11 +40,3 @@ This package is mainly written in [ReScript](https://rescript-lang.org/), but ha ReScript has an interesting philosophy of not providing much in the way of effective build tools. Every ReScript file is compiled into `.bs.js` and `.gen.ts` files with the same name and same location, and then you can use these files in other `.js` files to create your program. To generate these files to build the package, you run `yarn build`. `.gen.ts` files are created by the [`@genType`](https://rescript-lang.org/docs/gentype/latest/getting-started) decorator, which creates typescript typings for needed parts of the codebase so that they can be easily used in typescript. These .gen.ts files reference the .bs.js files generated by rescript. - -### Errors regarding the `rationale` package - -You may notice sometimes, that there are errors about the `rationale` package. If you ever get these errors, `yarn build` should fix this issue. These errors occur because `yarn build` also needs to create build files that are in `node_modules`. So if you replace `node_modules` you may need to rebuild to get those files back. - -## Distributing this package or using this package from other monorepo packages - -As it says in the other `packages/*/README.md`s, building this package is an essential step of building other packages. From 282fa7726b7c5ff906a9fa1062faa7bfb2fcedb9 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 28 Apr 2022 21:14:03 -0400 Subject: [PATCH 050/146] Added scalePower and scaleLog --- .../DistributionOperation.res | 10 ++++++++++ .../Distributions/DistributionTypes.res | 10 ++++++++++ .../Distributions/GenericDist/GenericDist.res | 1 + .../Distributions/PointSetDist/Continuous.res | 6 ++++-- .../Distributions/PointSetDist/Discrete.res | 17 ++++++++++++----- .../Distributions/PointSetDist/Mixed.res | 9 ++++++--- .../Distributions/PointSetDist/PointSetDist.res | 7 ++++++- .../ReducerInterface_GenericDistribution.res | 9 +++++++++ 8 files changed, 58 insertions(+), 11 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res index 18ee2d6a..91910824 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res @@ -154,6 +154,16 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => { ->GenericDist.toPointSet(~xyPointLength, ~sampleCount, ()) ->E.R2.fmap(r => Dist(PointSet(r))) ->OutputLocal.fromResult + | ToDist(Scale(#Logarithm, f)) => + dist + ->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~algebraicCombination=#Logarithm, ~f) + ->E.R2.fmap(r => Dist(r)) + ->OutputLocal.fromResult + | ToDist(Scale(#Power, f)) => + dist + ->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~algebraicCombination=#Power, ~f) + ->E.R2.fmap(r => Dist(r)) + ->OutputLocal.fromResult | ToDistCombination(Algebraic(_), _, #Float(_)) => GenDistError(NotYetImplemented) | ToDistCombination(Algebraic(strategy), arithmeticOperation, #Dist(t2)) => dist diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res index 93f86798..e970505d 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res @@ -70,10 +70,16 @@ module DistributionOperation = { | #Sample ] + type toScaleFn = [ + | #Power + | #Logarithm + ] + type toDist = | Normalize | ToPointSet | ToSampleSet(int) + | Scale(toScaleFn, float) | Truncate(option, option) | Inspect @@ -113,6 +119,8 @@ module DistributionOperation = { | ToDist(ToSampleSet(r)) => `toSampleSet(${E.I.toString(r)})` | ToDist(Truncate(_, _)) => `truncate` | ToDist(Inspect) => `inspect` + | ToDist(Scale(#Power, r)) => `scalePower(${E.Float.toFixed(r)})` + | ToDist(Scale(#Logarithm, r)) => `scaleLog(${E.Float.toFixed(r)})` | ToString(ToString) => `toString` | ToString(ToSparkline(n)) => `toSparkline(${E.I.toString(n)})` | ToBool(IsNormalized) => `isNormalized` @@ -142,6 +150,8 @@ module Constructors = { let toSampleSet = (dist, r): t => FromDist(ToDist(ToSampleSet(r)), dist) let truncate = (dist, left, right): t => FromDist(ToDist(Truncate(left, right)), dist) let inspect = (dist): t => FromDist(ToDist(Inspect), dist) + let scalePower = (dist, n): t => FromDist(ToDist(Scale(#Power, n)), dist) + let scaleLogarithm = (dist, n): t => FromDist(ToDist(Scale(#Logarithm, n)), dist) let toString = (dist): t => FromDist(ToString(ToString), dist) let toSparkline = (dist, n): t => FromDist(ToString(ToSparkline(n)), dist) let algebraicAdd = (dist1, dist2: genericDist): t => FromDist( diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res index c19bdf7f..25b83bd3 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res @@ -366,6 +366,7 @@ let pointwiseCombination = ( ~algebraicCombination: Operation.algebraicOperation, ~t2: t, ): result => { + Js.log2("PointwiseCombination", algebraicCombination); E.R.merge(toPointSetFn(t1), toPointSetFn(t2))->E.R.bind(((t1, t2)) => PointSetDist.combinePointwise(Operation.Algebraic.toFn(algebraicCombination), t1, t2) ->E.R2.fmap(r => DistributionTypes.PointSet(r)) diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Continuous.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Continuous.res index d4286387..105b5a05 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Continuous.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Continuous.res @@ -156,8 +156,10 @@ let reduce = ( ~integralSumCachesFn: (float, float) => option=(_, _) => None, fn: (float, float) => result, continuousShapes, -): result => - continuousShapes |> E.A.R.foldM(combinePointwise(~integralSumCachesFn, fn), empty) +): result => { + let merge = combinePointwise(~integralSumCachesFn, fn) + continuousShapes |> E.A.R.foldM(merge, empty) +} let mapYResult = ( ~integralSumCacheFn=_ => None, diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res index fdc921c6..1149df7e 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res @@ -34,9 +34,10 @@ let lastY = (t: t) => t |> getShape |> XYShape.T.lastY let combinePointwise = ( ~integralSumCachesFn=(_, _) => None, + fn, t1: PointSetTypes.discreteShape, t2: PointSetTypes.discreteShape, -): PointSetTypes.discreteShape => { +): result => { let combinedIntegralSum = Common.combineIntegralSums( integralSumCachesFn, t1.integralSumCache, @@ -49,16 +50,22 @@ let combinePointwise = ( make( ~integralSumCache=combinedIntegralSum, XYShape.PointwiseCombination.combine( - (a, b) => Ok(a +. b), + fn, XYShape.XtoY.discreteInterpolator, t1.xyShape, t2.xyShape, )->E.R.toExn("Addition operation should never fail", _), - ) + )->Ok } -let reduce = (~integralSumCachesFn=(_, _) => None, discreteShapes): PointSetTypes.discreteShape => - discreteShapes |> E.A.fold_left(combinePointwise(~integralSumCachesFn), empty) +let reduce = ( + ~integralSumCachesFn=(_, _) => None, + fn: (float, float) => result, + discreteShapes: array, +): result => { + let merge = combinePointwise(~integralSumCachesFn, fn) + discreteShapes |> E.A.R.foldM(merge, empty) +} let updateIntegralSumCache = (integralSumCache, t: t): t => { ...t, diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Mixed.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Mixed.res index 4ce2bdd6..98e7923a 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Mixed.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Mixed.res @@ -316,7 +316,10 @@ let combinePointwise = ( t2: t, ): result => { let reducedDiscrete = - [t1, t2] |> E.A.fmap(toDiscrete) |> E.A.O.concatSomes |> Discrete.reduce(~integralSumCachesFn) + [t1, t2] + |> E.A.fmap(toDiscrete) + |> E.A.O.concatSomes + |> Discrete.reduce(~integralSumCachesFn, fn) let reducedContinuous = [t1, t2] @@ -335,11 +338,11 @@ let combinePointwise = ( t1.integralCache, t2.integralCache, ) - reducedContinuous->E.R2.fmap(continuous => + E.R.merge(reducedContinuous, reducedDiscrete)->E.R2.fmap(((continuous, discrete)) => make( ~integralSumCache=combinedIntegralSum, ~integralCache=combinedIntegral, - ~discrete=reducedDiscrete, + ~discrete, ~continuous, ) ) diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res index 12aa5477..00c900dc 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res @@ -84,7 +84,12 @@ let combinePointwise = ( m2, )->E.R2.fmap(x => PointSetTypes.Continuous(x)) | (Discrete(m1), Discrete(m2)) => - Ok(PointSetTypes.Discrete(Discrete.combinePointwise(~integralSumCachesFn, m1, m2))) + Discrete.combinePointwise( + ~integralSumCachesFn, + fn, + m1, + m2, + )->E.R2.fmap(x => PointSetTypes.Discrete(x)) | (m1, m2) => Mixed.combinePointwise( ~integralSumCachesFn, diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index ab76f469..f69ff8b5 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -211,6 +211,15 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option< | ("normalize", [EvDistribution(dist)]) => Helpers.toDistFn(Normalize, dist) | ("isNormalized", [EvDistribution(dist)]) => Helpers.toBoolFn(IsNormalized, dist) | ("toPointSet", [EvDistribution(dist)]) => Helpers.toDistFn(ToPointSet, dist) + | ("scaleLog", [EvDistribution(dist)]) => + Helpers.toDistFn(Scale(#Logarithm, MagicNumbers.Math.e), dist) + | ("scaleLog10", [EvDistribution(dist)]) => Helpers.toDistFn(Scale(#Logarithm, 10.0), dist) + | ("scaleLog", [EvDistribution(dist), EvNumber(float)]) => + Helpers.toDistFn(Scale(#Logarithm, float), dist) + | ("scalePow", [EvDistribution(dist), EvNumber(float)]) => + Helpers.toDistFn(Scale(#Power, float), dist) + | ("scaleExp", [EvDistribution(dist)]) => + Helpers.toDistFn(Scale(#Power, MagicNumbers.Math.e), dist) | ("cdf", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Cdf(float), dist) | ("pdf", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Pdf(float), dist) | ("inv", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Inv(float), dist) From 900aeeae29ea6fad0f7efb7594ac4f4445ff633e Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 28 Apr 2022 21:31:15 -0400 Subject: [PATCH 051/146] Expose integralSum to Squiggle --- .../Distributions/DistributionTypes.res | 1 + .../Distributions/GenericDist/GenericDist.res | 40 ++++++++++--------- .../GenericDist/GenericDist.resi | 2 +- .../ReducerInterface_GenericDistribution.res | 1 + 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res index e970505d..255819d1 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res @@ -68,6 +68,7 @@ module DistributionOperation = { | #Pdf(float) | #Mean | #Sample + | #IntegralSum ] type toScaleFn = [ diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res index 25b83bd3..160ce640 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res @@ -62,26 +62,31 @@ let isNormalized = (t: t): bool => Js.Math.abs_float(integralEndY(t) -. 1.0) < 1 let toFloatOperation = ( t, ~toPointSetFn: toPointSetFn, - ~distToFloatOperation: Operation.distToFloatOperation, + ~distToFloatOperation: DistributionTypes.DistributionOperation.toFloat, ) => { - let trySymbolicSolution = switch (t: t) { - | Symbolic(r) => SymbolicDist.T.operate(distToFloatOperation, r)->E.R.toOption - | _ => None - } + switch distToFloatOperation { + | #IntegralSum => Ok(integralEndY(t)) + | (#Pdf(_) | #Cdf(_) | #Inv(_) | #Mean | #Sample) as op => { + let trySymbolicSolution = switch (t: t) { + | Symbolic(r) => SymbolicDist.T.operate(op, r)->E.R.toOption + | _ => None + } - let trySampleSetSolution = switch ((t: t), distToFloatOperation) { - | (SampleSet(sampleSet), #Mean) => SampleSetDist.mean(sampleSet)->Some - | (SampleSet(sampleSet), #Sample) => SampleSetDist.sample(sampleSet)->Some - | (SampleSet(sampleSet), #Inv(r)) => SampleSetDist.percentile(sampleSet, r)->Some - | _ => None - } + let trySampleSetSolution = switch ((t: t), distToFloatOperation) { + | (SampleSet(sampleSet), #Mean) => SampleSetDist.mean(sampleSet)->Some + | (SampleSet(sampleSet), #Sample) => SampleSetDist.sample(sampleSet)->Some + | (SampleSet(sampleSet), #Inv(r)) => SampleSetDist.percentile(sampleSet, r)->Some + | _ => None + } - switch trySymbolicSolution { - | Some(r) => Ok(r) - | None => - switch trySampleSetSolution { - | Some(r) => Ok(r) - | None => toPointSetFn(t)->E.R2.fmap(PointSetDist.operate(distToFloatOperation)) + switch trySymbolicSolution { + | Some(r) => Ok(r) + | None => + switch trySampleSetSolution { + | Some(r) => Ok(r) + | None => toPointSetFn(t)->E.R2.fmap(PointSetDist.operate(op)) + } + } } } } @@ -366,7 +371,6 @@ let pointwiseCombination = ( ~algebraicCombination: Operation.algebraicOperation, ~t2: t, ): result => { - Js.log2("PointwiseCombination", algebraicCombination); E.R.merge(toPointSetFn(t1), toPointSetFn(t2))->E.R.bind(((t1, t2)) => PointSetDist.combinePointwise(Operation.Algebraic.toFn(algebraicCombination), t1, t2) ->E.R2.fmap(r => DistributionTypes.PointSet(r)) diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi index e91803e2..3d143edc 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi @@ -20,7 +20,7 @@ let isNormalized: t => bool let toFloatOperation: ( t, ~toPointSetFn: toPointSetFn, - ~distToFloatOperation: Operation.distToFloatOperation, + ~distToFloatOperation: DistributionTypes.DistributionOperation.toFloat, ) => result @genType diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index f69ff8b5..a53425e8 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -196,6 +196,7 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option< ->SymbolicConstructors.symbolicResultToOutput | ("sample", [EvDistribution(dist)]) => Helpers.toFloatFn(#Sample, dist) | ("mean", [EvDistribution(dist)]) => Helpers.toFloatFn(#Mean, dist) + | ("integralSum", [EvDistribution(dist)]) => Helpers.toFloatFn(#IntegralSum, dist) | ("toString", [EvDistribution(dist)]) => Helpers.toStringFn(ToString, dist) | ("toSparkline", [EvDistribution(dist)]) => Helpers.toStringFn(ToSparkline(20), dist) | ("toSparkline", [EvDistribution(dist), EvNumber(n)]) => From 454ac0c252e6bb8d8a6cc133e9b1917eaa4944cf Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 29 Apr 2022 13:50:57 +0000 Subject: [PATCH 052/146] Add bindings to Squiggle Editor --- packages/components/package.json | 1 + .../src/components/SquiggleChart.tsx | 9 ++- .../src/components/SquiggleEditor.tsx | 81 ++++++++++++++++++- packages/components/src/index.ts | 2 + .../squiggle-lang/__tests__/TS/JS_test.ts | 22 +---- .../squiggle-lang/__tests__/TS/TestHelpers.ts | 2 +- packages/squiggle-lang/src/js/index.ts | 23 +++++- .../src/rescript/TypescriptInterface.res | 6 ++ 8 files changed, 118 insertions(+), 28 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 218747b9..e9549700 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -89,6 +89,7 @@ "@types/react": "17.0.43" }, "source": "./src/index.ts", + "browser": "dist/bundle.js", "main": "dist/src/index.js", "types": "dist/src/index.d.ts" } diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 7dda92e4..a6bf12af 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -3,10 +3,12 @@ import _ from "lodash"; import styled from "styled-components"; import { run, + runPartial, errorValueToString, squiggleExpression, + bindings, + samplingParams, } from "@quri/squiggle-lang"; -import type { samplingParams } from "@quri/squiggle-lang"; import { NumberShower } from "./NumberShower"; import { DistributionChart } from "./DistributionChart"; import { ErrorBox } from "./ErrorBox"; @@ -148,6 +150,8 @@ export interface SquiggleChartProps { /** CSS width of the element */ width?: number; height?: number; + /** Bindings of previous variables declared */ + bindings?: bindings; } export const SquiggleChart: React.FC = ({ @@ -156,6 +160,7 @@ export const SquiggleChart: React.FC = ({ outputXYPoints = 1000, onChange = () => {}, height = 60, + bindings = {}, width = NaN, }: SquiggleChartProps) => { const target = React.useRef(null); @@ -167,7 +172,7 @@ export const SquiggleChart: React.FC = ({ sampleCount: sampleCount, xyPointLength: outputXYPoints, }; - let expressionResult = run(squiggleString, samplingInputs); + let expressionResult = run(squiggleString, bindings, samplingInputs); let internal: JSX.Element; if (expressionResult.tag === "Ok") { let expression = expressionResult.value; diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index 580db580..f85cf1e8 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -3,7 +3,9 @@ import * as ReactDOM from "react-dom"; import { SquiggleChart } from "./SquiggleChart"; import { CodeEditor } from "./CodeEditor"; import styled from "styled-components"; -import type { squiggleExpression } from "@quri/squiggle-lang"; +import type { squiggleExpression, bindings } from "@quri/squiggle-lang"; +import { runPartial, errorValueToString } from "@quri/squiggle-lang"; +import { ErrorBox } from "./ErrorBox"; export interface SquiggleEditorProps { /** The input string for squiggle */ @@ -26,6 +28,8 @@ export interface SquiggleEditorProps { onChange?(expr: squiggleExpression): void; /** The width of the element */ width: number; + /** Previous variable declarations */ + bindings: bindings; } const Input = styled.div` @@ -46,6 +50,7 @@ export let SquiggleEditor: React.FC = ({ diagramCount, onChange, environment, + bindings = {}, }: SquiggleEditorProps) => { let [expression, setExpression] = React.useState(initialSquiggleString); return ( @@ -71,6 +76,7 @@ export let SquiggleEditor: React.FC = ({ diagramCount={diagramCount} environment={environment} onChange={onChange} + bindings={bindings} /> ); @@ -107,3 +113,76 @@ export function renderSquiggleEditorToDom(props: SquiggleEditorProps) { ); return parent; } + +export interface SquigglePartialProps { + /** The input string for squiggle */ + initialSquiggleString?: string; + /** If the output requires monte carlo sampling, the amount of samples */ + sampleCount?: number; + /** The amount of points returned to draw the distribution */ + outputXYPoints?: number; + kernelWidth?: number; + pointDistLength?: number; + /** If the result is a function, where the function starts */ + diagramStart?: number; + /** If the result is a function, where the function ends */ + diagramStop?: number; + /** If the result is a function, how many points along the function it samples */ + diagramCount?: number; + /** when the environment changes. Used again for notebook magic*/ + onChange?(expr: bindings): void; + /** The width of the element */ + width: number; + /** Previously declared variables */ + bindings: bindings; +} + +export let SquigglePartial: React.FC = ({ + initialSquiggleString = "", + onChange, + bindings, +}: SquigglePartialProps) => { + let [expression, setExpression] = React.useState(initialSquiggleString); + let squiggleResult = runPartial(expression, bindings); + if (squiggleResult.tag == "Ok") { + if (onChange) onChange(squiggleResult.value); + } + return ( +
+ + + + {squiggleResult.tag == "Error" ? ( + + {errorValueToString(squiggleResult.value)} + + ) : ( + <> + )} +
+ ); +}; + +export function renderSquigglePartialToDom(props: SquigglePartialProps) { + let parent = document.createElement("div"); + ReactDOM.render( + { + // @ts-ignore + parent.value = bindings; + + parent.dispatchEvent(new CustomEvent("input")); + if (props.onChange) props.onChange(bindings); + }} + />, + parent + ); + return parent; +} diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 364e6dcb..ffd9c8e0 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -1,7 +1,9 @@ export { SquiggleChart } from "./components/SquiggleChart"; export { SquiggleEditor, + SquigglePartial, renderSquiggleEditorToDom, + renderSquigglePartialToDom, } from "./components/SquiggleEditor"; import SquigglePlayground, { renderSquigglePlaygroundToDom, diff --git a/packages/squiggle-lang/__tests__/TS/JS_test.ts b/packages/squiggle-lang/__tests__/TS/JS_test.ts index 43f981eb..33aae7db 100644 --- a/packages/squiggle-lang/__tests__/TS/JS_test.ts +++ b/packages/squiggle-lang/__tests__/TS/JS_test.ts @@ -1,23 +1,5 @@ -import { - run, - Distribution, - resultMap, - squiggleExpression, - errorValueToString, -} from "../../src/js/index"; - -let testRun = (x: string): squiggleExpression => { - let result = run(x, { sampleCount: 100, xyPointLength: 100 }); - expect(result.tag).toEqual("Ok"); - if (result.tag === "Ok") { - return result.value; - } else { - throw Error( - "Expected squiggle expression to evaluate but got error: " + - errorValueToString(result.value) - ); - } -}; +import { Distribution, resultMap } from "../../src/js/index"; +import { testRun } from "./TestHelpers"; function Ok(x: b) { return { tag: "Ok", value: x }; diff --git a/packages/squiggle-lang/__tests__/TS/TestHelpers.ts b/packages/squiggle-lang/__tests__/TS/TestHelpers.ts index 3d4153ef..8ec0c3e1 100644 --- a/packages/squiggle-lang/__tests__/TS/TestHelpers.ts +++ b/packages/squiggle-lang/__tests__/TS/TestHelpers.ts @@ -8,7 +8,7 @@ import { } from "../../src/js/index"; export function testRun(x: string): squiggleExpression { - let squiggleResult = run(x, { sampleCount: 1000, xyPointLength: 100 }); + let squiggleResult = run(x, {}, { sampleCount: 1000, xyPointLength: 100 }); // return squiggleResult.value if (squiggleResult.tag === "Ok") { return squiggleResult.value; diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index bc66ab99..fb67e47a 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -2,7 +2,9 @@ import * as _ from "lodash"; import { genericDist, samplingParams, - evaluate, + evaluateUsingExternalBindings, + evaluatePartialUsingExternalBindings, + externalBindings, expressionValue, errorValue, distributionError, @@ -46,7 +48,7 @@ import { Constructors_pointwiseLogarithm, Constructors_pointwisePower, } from "../rescript/Distributions/DistributionOperation/DistributionOperation.gen"; -export type { samplingParams, errorValue }; +export type { samplingParams, errorValue, externalBindings as bindings }; export let defaultSamplingInputs: samplingParams = { sampleCount: 10000, @@ -96,15 +98,28 @@ export type squiggleExpression = export function run( squiggleString: string, + bindings?: externalBindings, samplingInputs?: samplingParams ): result { + let b = bindings ? bindings : {}; let si: samplingParams = samplingInputs ? samplingInputs : defaultSamplingInputs; - let result: result = evaluate(squiggleString); + + let result: result = + evaluateUsingExternalBindings(squiggleString, b); return resultMap(result, (x) => createTsExport(x, si)); } +// Run Partial. A partial is a block of code that doesn't return a value +export function runPartial( + squiggleString: string, + bindings: externalBindings, + _samplingInputs?: samplingParams +): result { + return evaluatePartialUsingExternalBindings(squiggleString, bindings); +} + function createTsExport( x: expressionValue, sampEnv: samplingParams @@ -166,7 +181,7 @@ function createTsExport( } } -// Helper functions to convert the recsript representations that genType doesn't +// Helper functions to convert the rescript representations that genType doesn't // cover function convertRawToTypescript( result: rescriptExport, diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index c4265178..f2758ba3 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -40,6 +40,12 @@ let evaluate = Reducer.evaluate @genType let evaluateUsingExternalBindings = Reducer.evaluateUsingExternalBindings +@genType +let evaluatePartialUsingExternalBindings = Reducer.evaluatePartialUsingExternalBindings + +@genType +type externalBindings = Reducer.externalBindings + @genType type expressionValue = ReducerInterface_ExpressionValue.expressionValue From 58a357cce5d5a9c9d5430e5975a3c4e634e0ef3c Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 29 Apr 2022 14:10:41 +0000 Subject: [PATCH 053/146] Add basic partial test --- .../squiggle-lang/__tests__/TS/JS_test.ts | 13 ++++++++- .../squiggle-lang/__tests__/TS/TestHelpers.ts | 28 +++++++++++++++---- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/packages/squiggle-lang/__tests__/TS/JS_test.ts b/packages/squiggle-lang/__tests__/TS/JS_test.ts index 33aae7db..e522eb95 100644 --- a/packages/squiggle-lang/__tests__/TS/JS_test.ts +++ b/packages/squiggle-lang/__tests__/TS/JS_test.ts @@ -1,5 +1,5 @@ import { Distribution, resultMap } from "../../src/js/index"; -import { testRun } from "./TestHelpers"; +import { testRun, testRunPartial } from "./TestHelpers"; function Ok(x: b) { return { tag: "Ok", value: x }; @@ -57,6 +57,17 @@ describe("Record", () => { }); }); +describe("Partials", () => { + test("Can pass variables between partials and cells", () => { + let bindings = testRunPartial(`x = 5`); + let bindings2 = testRunPartial(`y = x + 2`, bindings); + expect(testRun(`y + 3`, bindings2)).toEqual({ + tag: "number", + value: 10, + }); + }); +}); + describe("Distribution", () => { //It's important that sampleCount is less than 9. If it's more, than that will create randomness //Also, note, the value should be created using makeSampleSetDist() later on. diff --git a/packages/squiggle-lang/__tests__/TS/TestHelpers.ts b/packages/squiggle-lang/__tests__/TS/TestHelpers.ts index 8ec0c3e1..7d51c98e 100644 --- a/packages/squiggle-lang/__tests__/TS/TestHelpers.ts +++ b/packages/squiggle-lang/__tests__/TS/TestHelpers.ts @@ -1,14 +1,16 @@ import { run, - // Distribution, + runPartial, + bindings, squiggleExpression, errorValueToString, - // errorValue, - // result, } from "../../src/js/index"; -export function testRun(x: string): squiggleExpression { - let squiggleResult = run(x, {}, { sampleCount: 1000, xyPointLength: 100 }); +export function testRun(x: string, bindings = {}): squiggleExpression { + let squiggleResult = run(x, bindings, { + sampleCount: 1000, + xyPointLength: 100, + }); // return squiggleResult.value if (squiggleResult.tag === "Ok") { return squiggleResult.value; @@ -21,6 +23,22 @@ export function testRun(x: string): squiggleExpression { } } +export function testRunPartial(x: string, bindings: bindings = {}): bindings { + let squiggleResult = runPartial(x, bindings, { + sampleCount: 1000, + xyPointLength: 100, + }); + if (squiggleResult.tag === "Ok") { + return squiggleResult.value; + } else { + throw new Error( + `Expected squiggle expression to evaluate but got error: ${errorValueToString( + squiggleResult.value + )}` + ); + } +} + export function failDefault() { expect("be reached").toBe("codepath should never"); } From a866270af8f18b6f759c52350e29e0a646c346fd Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 29 Apr 2022 14:19:26 +0000 Subject: [PATCH 054/146] Update dependencies --- yarn.lock | 51 ++++++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/yarn.lock b/yarn.lock index bf2d7be9..3597fea6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2506,9 +2506,9 @@ integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== "@sinclair/typebox@^0.23.3": - version "0.23.4" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.23.4.tgz#6ff93fd2585ce44f7481c9ff6af610fbb5de98a4" - integrity sha512-0/WqSvpVbCBAV1yPeko7eAczKbs78dNVAaX14quVlwOb2wxfKuXCx91h4NrEfkYK9zEnyVSW4JVI/trP3iS+Qg== + version "0.23.5" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.23.5.tgz#93f7b9f4e3285a7a9ade7557d9a8d36809cbc47d" + integrity sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg== "@sindresorhus/is@^0.14.0": version "0.14.0" @@ -4071,9 +4071,9 @@ form-data "^3.0.0" "@types/node@*", "@types/node@^17.0.29", "@types/node@^17.0.5": - version "17.0.29" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.29.tgz#7f2e1159231d4a077bb660edab0fde373e375a3d" - integrity sha512-tx5jMmMFwx7wBwq/V7OohKDVb/JwJU5qCVkeLMh1//xycAJ/ESuw9aJ9SEtlCZDYi2pBfe4JkisSoAtbOsBNAA== + version "17.0.30" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.30.tgz#2c6e8512acac70815e8176aa30c38025067880ef" + integrity sha512-oNBIZjIqyHYP8VCNAV9uEytXVeXG2oR0w9lgAXro20eugRQfY002qr3CUl6BAe+Yf/z3CRjPdz27Pu6WWtuSRw== "@types/node@^14.0.10": version "14.18.16" @@ -4140,17 +4140,10 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== -"@types/react-dom@^18.0.0": - version "18.0.0" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.0.tgz#b13f8d098e4b0c45df4f1ed123833143b0c71141" - integrity sha512-49897Y0UiCGmxZqpC8Blrf6meL8QUla6eb+BBhn69dTXlmuOlzkfr7HHY/O8J25e1lTUMs+YYxSlVDAaGHCOLg== - dependencies: - "@types/react" "*" - -"@types/react-dom@^18.0.2": - version "18.0.2" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.2.tgz#2d6b46557aa30257e87e67a6d952146d15979d79" - integrity sha512-UxeS+Wtj5bvLRREz9tIgsK4ntCuLDo0EcAcACgw3E+9wE8ePDr9uQpq53MfcyxyIS55xJ+0B6mDS8c4qkkHLBg== +"@types/react-dom@^18.0.0", "@types/react-dom@^18.0.2": + version "18.0.3" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.3.tgz#a022ea08c75a476fe5e96b675c3e673363853831" + integrity sha512-1RRW9kst+67gveJRYPxGmVy8eVJ05O43hg77G2j5m76/RFJtMbcfAs2viQ2UNsvvDg8F7OfQZx8qQcl6ymygaQ== dependencies: "@types/react" "*" @@ -4809,9 +4802,9 @@ acorn@^8.0.4, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.0: integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== address@^1.0.1, address@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" - integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== + version "1.2.0" + resolved "https://registry.yarnpkg.com/address/-/address-1.2.0.tgz#d352a62c92fee90f89a693eccd2a8b2139ab02d9" + integrity sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig== adjust-sourcemap-loader@^4.0.0: version "4.0.0" @@ -7906,9 +7899,9 @@ ejs@^3.1.6: jake "^10.8.5" electron-to-chromium@^1.4.118: - version "1.4.124" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.124.tgz#e9015e234d8632920dcdf5480351da9e845ed220" - integrity sha512-VhaE9VUYU6d2eIb+4xf83CATD+T+3bTzvxvlADkQE+c2hisiw3sZmvEDtsW704+Zky9WZGhBuQXijDVqSriQLA== + version "1.4.127" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.127.tgz#4ef19d5d920abe2676d938f4170729b44f7f423a" + integrity sha512-nhD6S8nKI0O2MueC6blNOEZio+/PWppE/pevnf3LOlQA/fKPCrDp2Ao4wx4LFwmIkJpVdFdn2763YWLy9ENIZg== element-resize-detector@^1.2.2: version "1.2.4" @@ -16599,9 +16592,9 @@ terser@^4.1.2, terser@^4.6.3: source-map-support "~0.5.12" terser@^5.0.0, terser@^5.10.0, terser@^5.3.4, terser@^5.7.2: - version "5.13.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.13.0.tgz#d43fd71861df1b4df743980caa257c6fa03acc44" - integrity sha512-sgQ99P+fRBM1jAYzN9RTnD/xEWx/7LZgYTCRgmYriSq1wxxqiQPJgXkkLBBuwySDWJ2PP0PnVQyuf4xLUuH4Ng== + version "5.13.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.13.1.tgz#66332cdc5a01b04a224c9fad449fc1a18eaa1799" + integrity sha512-hn4WKOfwnwbYfe48NgrQjqNOH9jzLqRcIfbYytOXCOv46LBfWr9bDS17MQqOi+BWGD0sJK3Sj5NC/gJjiojaoA== dependencies: acorn "^8.5.0" commander "^2.20.0" @@ -16968,9 +16961,9 @@ typedarray@^0.0.6: integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= typescript@^4.6.3: - version "4.6.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" - integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== + version "4.6.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9" + integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg== ua-parser-js@^0.7.30: version "0.7.31" From 8e318a8aa9e4306e165475a334831f86477d4e9c Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Thu, 28 Apr 2022 18:35:09 +0200 Subject: [PATCH 055/146] refactor reducer removed some extra array references rename Builder to ExpressionBuilder Expression Builder Trash Warning remove parsePartial/Outer, add context to lambda format module Bindings simplify types module Macro reduceValueList do macro call result map bindings stop replacing on macro calls Macro Test doBindStatement bind a statement bindings tested. TODO bind shadowing in lambda block tests defined block tests defined blocks tested macro lambda test defined --- .../Reducer_Dispatch_BuiltInMacros_test.res | 121 ++++++++ .../Reducer_Expression_test.res | 6 + .../__tests__/Reducer/Reducer_TestHelpers.res | 53 +--- .../Reducer/Reducer_TestMacroHelpers.res | 81 ++++++ .../Reducer/Reducer_externalBindings_test.res | 91 +++--- .../Reducer_functionAssignment_test.res | 4 +- .../__tests__/Reducer/Reducer_test.res | 51 ++-- .../ReducerInterface_Distribution_test.res | 26 +- .../ReducerInterface_ExpressionValue_test.res | 4 +- .../src/rescript/Reducer/Reducer.res | 2 - .../src/rescript/Reducer/Reducer.resi | 3 - .../Reducer_Dispatch_BuiltIn.res | 18 ++ .../Reducer_Dispatch_BuiltInMacros.res | 272 ++++++++---------- .../Reducer_Expression/Reducer_Expression.res | 227 ++++----------- .../Reducer_Expression_Bindings.res | 73 +++++ .../Reducer_Expression_Builder.res | 16 -- .../Reducer_Expression_ExpressionBuilder.res | 60 ++++ .../Reducer_Expression_Lambda.res | 35 +++ .../Reducer_Expression_Macro.res | 35 +++ .../Reducer_Expression_T.res | 50 +++- .../Reducer_MathJs_ToExpression.res | 149 +++------- .../ReducerInterface_ExpressionValue.res | 37 +-- 22 files changed, 800 insertions(+), 614 deletions(-) create mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res create mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_Expression/Reducer_Expression_test.res create mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res create mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Builder.res create mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res create mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res create mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res 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 new file mode 100644 index 00000000..ecf97697 --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res @@ -0,0 +1,121 @@ +open Jest +// open Expect + +open Reducer_Expression_ExpressionBuilder +open Reducer_TestMacroHelpers +module ExpressionT = Reducer_Expression_T + +let exampleExpression = eNumber(1.) +let exampleExpressionY = eSymbol("y") +let exampleStatement = eLetStatement("y", eNumber(1.)) +let exampleStatementX = eLetStatement("y", eSymbol("x")) +let exampleStatementZ = eLetStatement("z", eSymbol("y")) + +// If it is not a mactro then it is not expanded +testMacro([], exampleExpression, "Ok(1)") + +describe("bindStatement", () => { + // A statement is bound by the bindings created by the previous statement + testMacro([], eBindStatement(eBindings([]), exampleStatement), "Ok((:$setBindings {} :y 1))") + // Then it answers the bindings for the next statement when reduced + testMacroEval([], eBindStatement(eBindings([]), exampleStatement), "Ok({y: 1})") + // Now let's feed a binding to see what happens + testMacro( + [], + eBindStatement(eBindings([("x", EvNumber(2.))]), exampleStatementX), + "Ok((:$setBindings {x: 2} :y 2))", + ) + // An expression does not return a binding, thus error + testMacro([], eBindStatement(eBindings([]), exampleExpression), "Error(Assignment expected)") + // When bindings from previous statement are missing the context is injected. This must be the first statement of a block + testMacro( + [("z", EvNumber(99.))], + eBindStatementDefault(exampleStatement), + "Ok((:$setBindings {z: 99} :y 1))", + ) +}) + +describe("bindExpression", () => { + // x is simply bound in the expression + testMacro([], eBindExpression(eBindings([("x", EvNumber(2.))]), eSymbol("x")), "Ok(2)") + // When an let statement is the end expression then bindings are returned + testMacro( + [], + eBindExpression(eBindings([("x", EvNumber(2.))]), exampleStatement), + "Ok((:$exportBindings (:$setBindings {x: 2} :y 1)))", + ) + // Now let's reduce that expression + testMacroEval( + [], + eBindExpression(eBindings([("x", EvNumber(2.))]), exampleStatement), + "Ok({x: 2,y: 1})", + ) + // When bindings are missing the context is injected. This must be the first and last statement of a block + testMacroEval( + [("z", EvNumber(99.))], + eBindExpressionDefault(exampleStatement), + "Ok({y: 1,z: 99})", + ) +}) + +describe("block", () => { + // Block with a single expression + testMacro([], eBlock(list{exampleExpression}), "Ok((:$$bindExpression 1))") + testMacroEval([], eBlock(list{exampleExpression}), "Ok(1)") + // Block with a single statement + testMacro([], eBlock(list{exampleStatement}), "Ok((:$$bindExpression (:$let :y 1)))") + testMacroEval([], eBlock(list{exampleStatement}), "Ok({y: 1})") + // Block with a statement and an expression + testMacro( + [], + eBlock(list{exampleStatement, exampleExpressionY}), + "Ok((:$$bindExpression (:$$bindStatement (:$let :y 1)) :y))", + ) + testMacroEval([], eBlock(list{exampleStatement, exampleExpressionY}), "Ok(1)") + // Block with a statement and another statement + testMacro( + [], + eBlock(list{exampleStatement, exampleStatementZ}), + "Ok((:$$bindExpression (:$$bindStatement (:$let :y 1)) (:$let :z :y)))", + ) + testMacroEval([], eBlock(list{exampleStatement, exampleStatementZ}), "Ok({y: 1,z: 1})") + // Block inside a block + testMacro( + [], + eBlock(list{eBlock(list{exampleExpression})}), + "Ok((:$$bindExpression (:$$block 1)))", + ) + testMacroEval([], eBlock(list{eBlock(list{exampleExpression})}), "Ok(1)") + // Block assigned to a variable + testMacro( + [], + eBlock(list{eLetStatement("z", eBlock(list{eBlock(list{exampleExpressionY})}))}), + "Ok((:$$bindExpression (:$let :z (:$$block (:$$block :y)))))", + ) + testMacroEval( + [], + eBlock(list{eLetStatement("z", eBlock(list{eBlock(list{exampleExpressionY})}))}), + "Ok({z: :y})", + ) + // Empty block + testMacro([], eBlock(list{}), "Ok(:undefined block)") //TODO: should be an error +}) + +describe("lambda", () => { + // assign a lambda to a variable + let lambdaExpression = eFunction("$$lambda", list{eArrayString(["y"]), exampleExpressionY}) + testMacro([], lambdaExpression, "Ok(lambda(y=>internal))") + // call a lambda + let callLambdaExpression = list{lambdaExpression, eNumber(1.)}->ExpressionT.EList + testMacro([], callLambdaExpression, "Ok(((:$$lambda [y] :y) 1))") + testMacroEval([], callLambdaExpression, "Ok(1)") + // Parameters shadow the outer scope + testMacroEval([("y", EvNumber(666.))], callLambdaExpression, "Ok(1)") + // When not shadowed by the parameters, the outer scope variables are available + let lambdaExpression = eFunction( + "$$lambda", + list{eArrayString(["z"]), eFunction("add", list{eSymbol("y"), eSymbol("z")})}, + ) + let callLambdaExpression = eList(list{lambdaExpression, eNumber(1.)}) + testMacroEval([("y", EvNumber(666.))], callLambdaExpression, "Ok(667)") +}) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Expression/Reducer_Expression_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Expression/Reducer_Expression_test.res new file mode 100644 index 00000000..f20d95f7 --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Expression/Reducer_Expression_test.res @@ -0,0 +1,6 @@ +open Jest +open Expect + +test("dummy", () => { + expect(true)->toBe(true) +}) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res index a38624dc..766acd43 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res @@ -1,4 +1,4 @@ -module Expression = Reducer.Expression +module ExpressionT = Reducer_Expression_T module ExpressionValue = ReducerInterface.ExpressionValue module ErrorValue = Reducer_ErrorValue @@ -14,47 +14,18 @@ let unwrapRecord = rValue => ) let expectParseToBe = (expr: string, answer: string) => - Reducer.parse(expr)->Expression.toStringResult->expect->toBe(answer) - -let expectParseOuterToBe = (expr: string, answer: string) => - Reducer.parseOuter(expr)->Expression.toStringResult->expect->toBe(answer) - -let expectParsePartialToBe = (expr: string, answer: string) => - Reducer.parsePartial(expr)->Expression.toStringResult->expect->toBe(answer) + Reducer.parse(expr)->ExpressionT.toStringResult->expect->toBe(answer) let expectEvalToBe = (expr: string, answer: string) => Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toBe(answer) let expectEvalBindingsToBe = (expr: string, bindings: Reducer.externalBindings, answer: string) => - Reducer.evaluateUsingOptions( - expr, - ~externalBindings=Some(bindings), - ~isPartial=None, - ~environment=None, - ) + Reducer.evaluateUsingOptions(expr, ~externalBindings=Some(bindings), ~environment=None) ->ExpressionValue.toStringResult ->expect ->toBe(answer) -let expectEvalPartialBindingsToBe = ( - expr: string, - bindings: Reducer.externalBindings, - answer: string, -) => - Reducer.evaluateUsingOptions( - expr, - ~externalBindings=Some(bindings), - ~isPartial=Some(true), - ~environment=None, - ) - ->unwrapRecord - ->ExpressionValue.toStringResultRecord - ->expect - ->toBe(answer) - let testParseToBe = (expr, answer) => test(expr, () => expectParseToBe(expr, answer)) -let testParseOuterToBe = (expr, answer) => test(expr, () => expectParseOuterToBe(expr, answer)) -let testParsePartialToBe = (expr, answer) => test(expr, () => expectParsePartialToBe(expr, answer)) let testDescriptionParseToBe = (desc, expr, answer) => test(desc, () => expectParseToBe(expr, answer)) @@ -62,34 +33,16 @@ let testEvalToBe = (expr, answer) => test(expr, () => expectEvalToBe(expr, answe let testDescriptionEvalToBe = (desc, expr, answer) => test(desc, () => expectEvalToBe(expr, answer)) let testEvalBindingsToBe = (expr, bindingsList, answer) => test(expr, () => expectEvalBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer)) -let testEvalPartialBindingsToBe = (expr, bindingsList, answer) => - test(expr, () => expectEvalPartialBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer)) module MySkip = { let testParseToBe = (expr, answer) => Skip.test(expr, () => expectParseToBe(expr, answer)) - let testParseOuterToBe = (expr, answer) => - Skip.test(expr, () => expectParseOuterToBe(expr, answer)) - let testParsePartialToBe = (expr, answer) => - Skip.test(expr, () => expectParsePartialToBe(expr, answer)) let testEvalToBe = (expr, answer) => Skip.test(expr, () => expectEvalToBe(expr, answer)) let testEvalBindingsToBe = (expr, bindingsList, answer) => Skip.test(expr, () => expectEvalBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer)) - let testEvalPartialBindingsToBe = (expr, bindingsList, answer) => - Skip.test(expr, () => - expectEvalPartialBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer) - ) } module MyOnly = { let testParseToBe = (expr, answer) => Only.test(expr, () => expectParseToBe(expr, answer)) - let testParseOuterToBe = (expr, answer) => - Only.test(expr, () => expectParseOuterToBe(expr, answer)) - let testParsePartialToBe = (expr, answer) => - Only.test(expr, () => expectParsePartialToBe(expr, answer)) let testEvalToBe = (expr, answer) => Only.test(expr, () => expectEvalToBe(expr, answer)) let testEvalBindingsToBe = (expr, bindingsList, answer) => Only.test(expr, () => expectEvalBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer)) - let testEvalPartialBindingsToBe = (expr, bindingsList, answer) => - Only.test(expr, () => - expectEvalPartialBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer) - ) } diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res new file mode 100644 index 00000000..af88cac4 --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res @@ -0,0 +1,81 @@ +open Jest +open Expect + +module Macro = Reducer_Expression_Macro +module Bindings = Reducer_Expression_Bindings +module Expression = Reducer_Expression +module ExpressionValue = ReducerInterface_ExpressionValue +module T = Reducer_Expression_T + +let testMacro_ = ( + tester, + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedCode: string, +) => { + let bindings = Belt.Map.String.fromArray(bindArray) + tester(expr->T.toString, () => + expr + ->Macro.expandMacroCall( + bindings, + ExpressionValue.defaultEnvironment, + Expression.reduceExpression, + ) + ->T.toStringResult + ->expect + ->toEqual(expectedCode) + ) +} + +let testMacroEval_ = ( + tester, + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedValue: string, +) => { + let bindings = Belt.Map.String.fromArray(bindArray) + tester(expr->T.toString, () => + expr + ->Macro.doMacroCall(bindings, ExpressionValue.defaultEnvironment, Expression.reduceExpression) + ->ExpressionValue.toStringResult + ->expect + ->toEqual(expectedValue) + ) +} + +let testMacro = ( + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedExpr: string, +) => testMacro_(test, bindArray, expr, expectedExpr) +let testMacroEval = ( + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedValue: string, +) => testMacroEval_(test, bindArray, expr, expectedValue) + +module MySkip = { + let testMacro = ( + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedExpr: string, + ) => testMacro_(Skip.test, bindArray, expr, expectedExpr) + let testMacroEval = ( + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedValue: string, + ) => testMacroEval_(Skip.test, bindArray, expr, expectedValue) +} + +module MyOnly = { + let testMacro = ( + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedExpr: string, + ) => testMacro_(Only.test, bindArray, expr, expectedExpr) + let testMacroEval = ( + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedValue: string, + ) => testMacroEval_(Only.test, bindArray, expr, expectedValue) +} diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res index ce834ed1..4c2546f4 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res @@ -1,33 +1,34 @@ +// TODO: Reimplement with usual parse open Jest open Reducer_TestHelpers -describe("Parse for Bindings", () => { - testParseOuterToBe("x", "Ok((:$$bindExpression (:$$bindings) :x))") - testParseOuterToBe("x+1", "Ok((:$$bindExpression (:$$bindings) (:add :x 1)))") - testParseOuterToBe( - "y = x+1; y", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :y (:add :x 1))) :y))", - ) -}) +// describe("Parse for Bindings", () => { +// testParseOuterToBe("x", "Ok((:$$bindExpression (:$$bindings) :x))") +// testParseOuterToBe("x+1", "Ok((:$$bindExpression (:$$bindings) (:add :x 1)))") +// testParseOuterToBe( +// "y = x+1; y", +// "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :y (:add :x 1))) :y))", +// ) +// }) -describe("Parse Partial", () => { - testParsePartialToBe( - "x", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) :x) (:$exportVariablesExpression)))", - ) - testParsePartialToBe( - "y=x", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :y :x)) (:$exportVariablesExpression)))", - ) - testParsePartialToBe( - "y=x+1", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :y (:add :x 1))) (:$exportVariablesExpression)))", - ) - testParsePartialToBe( - "y = x+1; z = y", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindStatement (:$$bindings) (:$let :y (:add :x 1))) (:$let :z :y)) (:$exportVariablesExpression)))", - ) -}) +// describe("Parse Partial", () => { +// testParsePartialToBe( +// "x", +// "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) :x) (:$exportVariablesExpression)))", +// ) +// testParsePartialToBe( +// "y=x", +// "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :y :x)) (:$exportVariablesExpression)))", +// ) +// testParsePartialToBe( +// "y=x+1", +// "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :y (:add :x 1))) (:$exportVariablesExpression)))", +// ) +// testParsePartialToBe( +// "y = x+1; z = y", +// "Ok((:$$bindExpression (:$$bindStatement (:$$bindStatement (:$$bindings) (:$let :y (:add :x 1))) (:$let :z :y)) (:$exportVariablesExpression)))", +// ) +// }) describe("Eval with Bindings", () => { testEvalBindingsToBe("x", list{("x", ExpressionValue.EvNumber(1.))}, "Ok(1)") @@ -39,22 +40,22 @@ describe("Eval with Bindings", () => { Partial code is a partial code fragment that is cut out from a larger code. Therefore it does not end with an expression. */ -describe("Eval Partial", () => { - testEvalPartialBindingsToBe( - // A partial cannot end with an expression - "x", - list{("x", ExpressionValue.EvNumber(1.))}, - "Error(Assignment expected)", - ) - testEvalPartialBindingsToBe("y=x", list{("x", ExpressionValue.EvNumber(1.))}, "Ok({x: 1, y: 1})") - testEvalPartialBindingsToBe( - "y=x+1", - list{("x", ExpressionValue.EvNumber(1.))}, - "Ok({x: 1, y: 2})", - ) - testEvalPartialBindingsToBe( - "y = x+1; z = y", - list{("x", ExpressionValue.EvNumber(1.))}, - "Ok({x: 1, y: 2, z: 2})", - ) -}) +// describe("Eval Partial", () => { +// testEvalPartialBindingsToBe( +// // A partial cannot end with an expression +// "x", +// list{("x", ExpressionValue.EvNumber(1.))}, +// "Error(Assignment expected)", +// ) +// testEvalPartialBindingsToBe("y=x", list{("x", ExpressionValue.EvNumber(1.))}, "Ok({x: 1,y: 1})") +// testEvalPartialBindingsToBe( +// "y=x+1", +// list{("x", ExpressionValue.EvNumber(1.))}, +// "Ok({x: 1,y: 2})", +// ) +// testEvalPartialBindingsToBe( +// "y = x+1; z = y", +// list{("x", ExpressionValue.EvNumber(1.))}, +// "Ok({x: 1,y: 2,z: 2})", +// ) +// }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res index 9259dacd..bb3e2220 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res @@ -2,8 +2,8 @@ open Jest open Reducer_TestHelpers describe("Parse function assignment", () => { - testParseToBe("f(x)=x", "Ok((:$let :f (:$lambda (x) :x)))") - testParseToBe("f(x)=2*x", "Ok((:$let :f (:$lambda (x) (:multiply 2 :x))))") + testParseToBe("f(x)=x", "Ok((:$$block (:$let :f (:$$lambda [x] (:$$block :x)))))") + testParseToBe("f(x)=2*x", "Ok((:$$block (:$let :f (:$$lambda [x] (:$$block (:multiply 2 :x))))))") //MathJs does not allow blocks in function definitions }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res index 5514b67c..80468c0f 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res @@ -10,46 +10,39 @@ describe("reducer using mathjs parse", () => { // Those tests toString that we are converting mathjs parse tree to what we need describe("expressions", () => { - testParseToBe("1", "Ok(1)") - testParseToBe("(1)", "Ok(1)") - testParseToBe("1+2", "Ok((:add 1 2))") - testParseToBe("1+2", "Ok((:add 1 2))") - testParseToBe("1+2", "Ok((:add 1 2))") - testParseToBe("1+2*3", "Ok((:add 1 (:multiply 2 3)))") + testParseToBe("1", "Ok((:$$block 1))") + testParseToBe("(1)", "Ok((:$$block 1))") + testParseToBe("1+2", "Ok((:$$block (:add 1 2)))") + testParseToBe("1+2*3", "Ok((:$$block (:add 1 (:multiply 2 3))))") }) describe("arrays", () => { //Note. () is a empty list in Lisp // The only builtin structure in Lisp is list. There are no arrays // [1,2,3] becomes (1 2 3) - testDescriptionParseToBe("empty", "[]", "Ok(())") - testParseToBe("[1, 2, 3]", "Ok((1 2 3))") - testParseToBe("['hello', 'world']", "Ok(('hello' 'world'))") - testDescriptionParseToBe("index", "([0,1,2])[1]", "Ok((:$atIndex (0 1 2) (1)))") + testDescriptionParseToBe("empty", "[]", "Ok((:$$block ()))") + testParseToBe("[1, 2, 3]", "Ok((:$$block (1 2 3)))") + testParseToBe("['hello', 'world']", "Ok((:$$block ('hello' 'world')))") + testDescriptionParseToBe("index", "([0,1,2])[1]", "Ok((:$$block (:$atIndex (0 1 2) (1))))") }) describe("records", () => { - testDescriptionParseToBe("define", "{a: 1, b: 2}", "Ok((:$constructRecord (('a' 1) ('b' 2))))") + testDescriptionParseToBe( + "define", + "{a: 1, b: 2}", + "Ok((:$$block (:$constructRecord (('a' 1) ('b' 2)))))", + ) testDescriptionParseToBe( "use", "{a: 1, b: 2}.a", - "Ok((:$atIndex (:$constructRecord (('a' 1) ('b' 2))) ('a')))", + "Ok((:$$block (:$atIndex (:$constructRecord (('a' 1) ('b' 2))) ('a'))))", ) }) describe("multi-line", () => { - testParseToBe("1; 2", "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) 1) 2))") - testParseToBe( - "1+1; 2+1", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:add 1 1)) (:add 2 1)))", - ) + testParseToBe("1; 2", "Ok((:$$block (:$$block 1 2)))") + testParseToBe("1+1; 2+1", "Ok((:$$block (:$$block (:add 1 1) (:add 2 1))))") }) describe("assignment", () => { - testParseToBe( - "x=1; x", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :x 1)) :x))", - ) - testParseToBe( - "x=1+1; x+1", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :x (:add 1 1))) (:add :x 1)))", - ) + testParseToBe("x=1; x", "Ok((:$$block (:$$block (:$let :x 1) :x)))") + testParseToBe("x=1+1; x+1", "Ok((:$$block (:$$block (:$let :x (:add 1 1)) (:add :x 1))))") }) }) @@ -70,13 +63,13 @@ describe("eval", () => { }) describe("arrays", () => { test("empty array", () => expectEvalToBe("[]", "Ok([])")) - testEvalToBe("[1, 2, 3]", "Ok([1, 2, 3])") - testEvalToBe("['hello', 'world']", "Ok(['hello', 'world'])") + testEvalToBe("[1, 2, 3]", "Ok([1,2,3])") + testEvalToBe("['hello', 'world']", "Ok(['hello','world'])") testEvalToBe("([0,1,2])[1]", "Ok(1)") testDescriptionEvalToBe("index not found", "([0,1,2])[10]", "Error(Array index not found: 10)") }) describe("records", () => { - test("define", () => expectEvalToBe("{a: 1, b: 2}", "Ok({a: 1, b: 2})")) + test("define", () => expectEvalToBe("{a: 1, b: 2}", "Ok({a: 1,b: 2})")) test("index", () => expectEvalToBe("{a: 1}.a", "Ok(1)")) test("index not found", () => expectEvalToBe("{a: 1}.b", "Error(Record property not found: b)")) }) @@ -91,7 +84,7 @@ describe("eval", () => { testEvalToBe("x=1; y=x+1; y+1", "Ok(3)") testEvalToBe("1; x=1", "Error(Assignment expected)") testEvalToBe("1; 1", "Error(Assignment expected)") - testEvalToBe("x=1; x=1", "Error(Expression expected)") + testEvalToBe("x=1; x=1", "Ok({x: 1})") }) }) diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res index 33afd311..1ff1c85e 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res @@ -119,27 +119,33 @@ 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("3 ^ normal(5,1)", "Ok((:pow 3 (:normal 5 1)))") - testParse("normal(5,2) ^ 3", "Ok((:pow (:normal 5 2) 3))") + testParse("normal(5,2) ^ normal(5,1)", "Ok((:$$block (:pow (:normal 5 2) (:normal 5 1))))") + testParse("3 ^ normal(5,1)", "Ok((:$$block (:pow 3 (:normal 5 1))))") + testParse("normal(5,2) ^ 3", "Ok((:$$block (:pow (:normal 5 2) 3)))") }) describe("subtraction", () => { - testParse("10 - normal(5,1)", "Ok((:subtract 10 (:normal 5 1)))") - testParse("normal(5,1) - 10", "Ok((:subtract (:normal 5 1) 10))") + testParse("10 - normal(5,1)", "Ok((:$$block (:subtract 10 (:normal 5 1))))") + testParse("normal(5,1) - 10", "Ok((:$$block (:subtract (:normal 5 1) 10)))") }) describe("pointwise arithmetic expressions", () => { testParse(~skip=true, "normal(5,2) .+ normal(5,1)", "Ok((:dotAdd (:normal 5 2) (:normal 5 1)))") testParse( ~skip=true, "normal(5,2) .- normal(5,1)", - "Ok((:dotSubtract (:normal 5 2) (:normal 5 1)))", + "Ok((:$$block (: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((:$$block (:dotMultiply (:normal 5 2) (:normal 5 1))))", + ) + testParse( + "normal(5,2) ./ normal(5,1)", + "Ok((:$$block (:dotDivide (:normal 5 2) (:normal 5 1))))", + ) + testParse("normal(5,2) .^ normal(5,1)", "Ok((:$$block (:dotPow (:normal 5 2) (:normal 5 1))))") }) describe("equality", () => { - testParse("5 == normal(5,2)", "Ok((:equal 5 (:normal 5 2)))") + testParse("5 == normal(5,2)", "Ok((:$$block (:equal 5 (:normal 5 2))))") }) describe("pointwise adding two normals", () => { testParse(~skip=true, "normal(5,2) .+ normal(5,1)", "Ok((:dotAdd (:normal 5 2) (:normal 5 1)))") diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res index fc2d555e..888aca7e 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res @@ -3,9 +3,9 @@ open Jest open Expect describe("ExpressionValue", () => { - test("argsToString", () => expect([EvNumber(1.), EvString("a")]->argsToString)->toBe("1, 'a'")) + test("argsToString", () => expect([EvNumber(1.), EvString("a")]->argsToString)->toBe("1,'a'")) test("toStringFunctionCall", () => - expect(("fn", [EvNumber(1.), EvString("a")])->toStringFunctionCall)->toBe("fn(1, 'a')") + expect(("fn", [EvNumber(1.), EvString("a")])->toStringFunctionCall)->toBe("fn(1,'a')") ) }) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res index a403ccd3..c9c9f41e 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res @@ -12,5 +12,3 @@ type externalBindings = ReducerInterface_ExpressionValue.externalBindings let evaluate = Expression.evaluate let evaluateUsingOptions = Expression.evaluateUsingOptions let parse = Expression.parse -let parseOuter = Expression.parseOuter -let parsePartial = Expression.parsePartial diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi index 8ea6047a..880dd1e7 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi @@ -18,12 +18,9 @@ type externalBindings = ReducerInterface_ExpressionValue.externalBindings let evaluateUsingOptions: ( ~environment: option, ~externalBindings: option, - ~isPartial: option, string, ) => result @genType let evaluate: string => result let parse: string => result -let parseOuter: string => result -let parsePartial: string => result diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 93960cf6..04bd1be4 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -1,5 +1,6 @@ module ExternalLibrary = ReducerInterface.ExternalLibrary module MathJs = Reducer_MathJs +module Bindings = Reducer_Expression_Bindings open ReducerInterface.ExpressionValue open Reducer_ErrorValue @@ -68,6 +69,20 @@ let callInternal = (call: functionCall, _environment): result<'b, errorValue> => value->Ok } + let doSetBindings = ( + externalBindings: externalBindings, + symbol: string, + value: expressionValue, + ) => { + Bindings.fromExternalBindings(externalBindings) + ->Belt.Map.String.set(symbol, value) + ->Bindings.toExternalBindings + ->EvRecord + ->Ok + } + + let doExportBindings = (externalBindings: externalBindings) => EvRecord(externalBindings)->Ok + switch call { | ("$atIndex", [EvArray(aValueArray), EvArray([EvNumber(fIndex)])]) => arrayAtIndex(aValueArray, fIndex) @@ -78,6 +93,9 @@ let callInternal = (call: functionCall, _environment): result<'b, errorValue> => | ("inspect", [value, EvString(label)]) => inspectLabel(value, label) | ("inspect", [value]) => inspect(value) | ("inspectPerformance", [value, EvString(label)]) => inspectPerformance(value, label) + | ("$setBindings", [EvRecord(externalBindings), EvSymbol(symbol), value]) => + doSetBindings(externalBindings, symbol, value) + | ("$exportBindings", [EvRecord(externalBindings)]) => doExportBindings(externalBindings) | call => callMathJs(call) } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index 185897e9..951f444f 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -3,179 +3,143 @@ they take expressions as parameters and return a new expression. Macros are used to define language building blocks. They are like Lisp macros. */ +module Bindings = Reducer_Expression_Bindings module ExpressionT = Reducer_Expression_T module ExpressionValue = ReducerInterface.ExpressionValue module Result = Belt.Result - -open Reducer_ErrorValue +open Reducer_Expression_ExpressionBuilder type expression = ExpressionT.expression type environment = ExpressionValue.environment - -type reducerFn = ( - expression, - ExpressionT.bindings, - environment, -) => result - -let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings): result< - expression, - errorValue, -> => { - let getParameters = (bindings: ExpressionT.bindings): array => { - let eParameters = Belt.Map.String.getWithDefault(bindings, "$parameters", EParameters([])) - switch eParameters { - | EParameters(parameters) => parameters - | _ => [] - } - } - - let putParameters = ( - bindings: ExpressionT.bindings, - parameters: array, - ): ExpressionT.bindings => - Belt.Map.String.set(bindings, "$parameters", ExpressionT.EParameters(parameters)) - - let answerBindingIfNotParameter = (aSymbol, defaultExpression, parameters, bindings) => - switch Js.Array2.some(parameters, a => a == aSymbol) { - | true => defaultExpression->Ok // We cannot bind the parameters with global values - | false => - switch bindings->Belt.Map.String.get(aSymbol) { - | Some(boundExpression) => boundExpression->Ok - | None => RESymbolNotFound(aSymbol)->Error - } - } - - let answerCallBindingIfNotParameter = (aSymbol, defaultExpression, parameters, bindings) => - switch Js.Array2.some(parameters, a => a == aSymbol) { - | true => defaultExpression->Ok // We cannot bind the parameters with global values - | false => - switch bindings->Belt.Map.String.get(aSymbol) { - | Some(boundExpression) => boundExpression->Ok - | None => defaultExpression->Ok - } - } - - switch expression { - | ExpressionT.EValue(EvSymbol(aSymbol)) => { - let parameters = getParameters(bindings) - answerBindingIfNotParameter(aSymbol, expression, parameters, bindings) - } - | ExpressionT.EValue(EvCall(aSymbol)) => { - let parameters = getParameters(bindings) - answerCallBindingIfNotParameter(aSymbol, expression, parameters, bindings) - } - | ExpressionT.EValue(_) => expression->Ok - | ExpressionT.EBindings(_) => expression->Ok - | ExpressionT.EParameters(_) => expression->Ok - | ExpressionT.EList(list{ - ExpressionT.EValue(EvCall("$lambda")), - ExpressionT.EParameters(parameters), - expr, - }) => { - let oldParameters = getParameters(bindings) - let newParameters = oldParameters->Js.Array2.concat(parameters) - let newBindings = putParameters(bindings, newParameters) - let rNewExpr = replaceSymbols(expr, newBindings) - rNewExpr->Result.flatMap(newExpr => - ExpressionT.EList(list{ - ExpressionT.EValue(EvCall("$lambda")), - ExpressionT.EParameters(parameters), - newExpr, - })->Ok - ) - } - | ExpressionT.EList(list) => { - let racc = list->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) => - racc->Result.flatMap(acc => { - each - ->replaceSymbols(bindings) - ->Result.flatMap(newNode => { - acc->Belt.List.add(newNode)->Ok - }) - }) - ) - racc->Result.map(acc => acc->ExpressionT.EList) - } - } -} +type errorValue = Reducer_ErrorValue.errorValue let dispatchMacroCall = ( - list: list, + macroExpression: expression, bindings: ExpressionT.bindings, environment, - reduceExpression: reducerFn, -): result => { - let doBindStatement = (statement: expression, bindings: ExpressionT.bindings) => { + reduceExpression: ExpressionT.reducerFn, +): result => { + let doBindStatement = (bindingExpr: expression, statement: expression, environment) => switch statement { - | ExpressionT.EList(list{ - ExpressionT.EValue(EvCall("$let")), - ExpressionT.EValue(EvSymbol(aSymbol)), - expressionToReduce, - }) => { - let rNewExpressionToReduce = replaceSymbols(expressionToReduce, bindings) - - let rNewValue = - rNewExpressionToReduce->Result.flatMap(newExpressionToReduce => - reduceExpression(newExpressionToReduce, bindings, environment) - ) - - let rNewExpression = rNewValue->Result.map(newValue => ExpressionT.EValue(newValue)) - rNewExpression->Result.map(newExpression => - Belt.Map.String.set(bindings, aSymbol, newExpression)->ExpressionT.EBindings + | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), symbolExpr, statement}) => { + let rExternalBindingsValue = reduceExpression( + bindingExpr, + Bindings.defaultBindings, + environment, ) + + rExternalBindingsValue->Result.flatMap(externalBindingsValue => { + let newBindings = Bindings.fromValue(externalBindingsValue) + let rNewStatement = Bindings.replaceSymbols(newBindings, statement) + rNewStatement->Result.map(newStatement => + eFunction( + "$setBindings", + list{newBindings->Bindings.toExternalBindings->eRecord, symbolExpr, newStatement}, + ) + ) + }) } | _ => REAssignmentExpected->Error } - } - let doExportVariableExpression = (bindings: ExpressionT.bindings) => { - let emptyDictionary: Js.Dict.t = Js.Dict.empty() - let reducedBindings = bindings->Belt.Map.String.keep((_key, value) => - switch value { - | ExpressionT.EValue(_) => true - | _ => false - } - ) - let externalBindings = reducedBindings->Belt.Map.String.reduce(emptyDictionary, ( - acc, - key, - expressionValue, - ) => { - let value = switch expressionValue { - | ExpressionT.EValue(aValue) => aValue - | _ => EvSymbol("internal") - } - Js.Dict.set(acc, key, value) - acc - }) - externalBindings->ExpressionValue.EvRecord->ExpressionT.EValue->Ok - } + let doBindExpression = (bindingExpr: expression, statement: expression, environment) => + switch statement { + | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), symbolExpr, statement}) => { + let rExternalBindingsValue = reduceExpression( + bindingExpr, + Bindings.defaultBindings, + environment, + ) - let doBindExpression = (expression: expression, bindings: ExpressionT.bindings) => - switch expression { - | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), ..._}) => - REExpressionExpected->Error - | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$exportVariablesExpression"))}) => - doExportVariableExpression(bindings) - | _ => replaceSymbols(expression, bindings) + rExternalBindingsValue->Result.flatMap(externalBindingsValue => { + let newBindings = Bindings.fromValue(externalBindingsValue) + let rNewStatement = Bindings.replaceSymbols(newBindings, statement) + rNewStatement->Result.map(newStatement => + eFunction( + "$exportBindings", + list{ + eFunction( + "$setBindings", + list{newBindings->Bindings.toExternalBindings->eRecord, symbolExpr, newStatement}, + ), + }, + ) + ) + }) + } + | _ => { + let rExternalBindingsValue = reduceExpression( + bindingExpr, + Bindings.defaultBindings, + environment, + ) + rExternalBindingsValue->Result.flatMap(externalBindingsValue => { + let newBindings = Bindings.fromValue(externalBindingsValue) + let rNewStatement = Bindings.replaceSymbols(newBindings, statement) + rNewStatement + }) + } } - switch list { - | list{ExpressionT.EValue(EvCall("$$bindings"))} => bindings->ExpressionT.EBindings->Ok + let doBlock = (exprs: list, _bindings: ExpressionT.bindings, _environment): result< + expression, + errorValue, + > => { + let exprsArray = Belt.List.toArray(exprs) + let maxIndex = Js.Array2.length(exprsArray) - 1 + exprsArray->Js.Array2.reducei((acc, statement, index) => + if index == 0 { + if index == maxIndex { + eBindExpressionDefault(statement) + } else { + eBindStatementDefault(statement) + } + } else if index == maxIndex { + eBindExpression(acc, statement) + } else { + eBindStatement(acc, statement) + } + , eSymbol("undefined block"))->Ok + } - | list{ - ExpressionT.EValue(EvCall("$$bindStatement")), - ExpressionT.EBindings(bindings), - statement, - } => - doBindStatement(statement, bindings) - | list{ - ExpressionT.EValue(EvCall("$$bindExpression")), - ExpressionT.EBindings(bindings), - expression, - } => - doBindExpression(expression, bindings) - | _ => list->ExpressionT.EList->Ok + let doLambdaDefinition = ( + bindings: ExpressionT.bindings, + parameters: array, + lambdaDefinition: ExpressionT.expression, + ) => eLambda(parameters, bindings->Bindings.toExternalBindings, lambdaDefinition)->Ok + + let expandExpressionList = (aList, bindings: ExpressionT.bindings, environment) => + switch aList { + | list{ + ExpressionT.EValue(EvCall("$$bindStatement")), + bindingExpr: ExpressionT.expression, + statement, + } => + doBindStatement(bindingExpr, statement, environment) + | list{ExpressionT.EValue(EvCall("$$bindStatement")), statement} => + // bindings of the context are used when there is no binding expression + doBindStatement(eRecord(Bindings.toExternalBindings(bindings)), statement, environment) + | list{ + ExpressionT.EValue(EvCall("$$bindExpression")), + bindingExpr: ExpressionT.expression, + expression, + } => + doBindExpression(bindingExpr, expression, environment) + | list{ExpressionT.EValue(EvCall("$$bindExpression")), expression} => + // bindings of the context are used when there is no binding expression + doBindExpression(eRecord(Bindings.toExternalBindings(bindings)), expression, environment) + | list{ExpressionT.EValue(EvCall("$$block")), ...exprs} => doBlock(exprs, bindings, environment) + | list{ + ExpressionT.EValue(EvCall("$$lambda")), + ExpressionT.EValue(EvArrayString(parameters)), + lambdaDefinition, + } => + doLambdaDefinition(bindings, parameters, lambdaDefinition) + | _ => ExpressionT.EList(aList)->Ok + } + + switch macroExpression { + | EList(aList) => expandExpressionList(aList, bindings, environment) + | _ => macroExpression->Ok } } 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 1713476f..e69c27d8 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 @@ -1,13 +1,14 @@ -module Builder = Reducer_Expression_Builder +module Bindings = Reducer_Expression_Bindings module BuiltIn = Reducer_Dispatch_BuiltIn +module ExpressionBuilder = Reducer_Expression_ExpressionBuilder module ExpressionValue = ReducerInterface.ExpressionValue module Extra = Reducer_Extra +module Lambda = Reducer_Expression_Lambda +module Macro = Reducer_Expression_Macro module MathJs = Reducer_MathJs module Result = Belt.Result module T = Reducer_Expression_T -open Reducer_ErrorValue - type environment = ReducerInterface_ExpressionValue.environment type errorValue = Reducer_ErrorValue.errorValue type expression = T.expression @@ -16,30 +17,6 @@ type externalBindings = ReducerInterface_ExpressionValue.externalBindings type internalCode = ReducerInterface_ExpressionValue.internalCode type t = expression -external castExpressionToInternalCode: expression => internalCode = "%identity" -external castInternalCodeToExpression: internalCode => expression = "%identity" - -/* - Shows the expression as text of expression -*/ -let rec toString = expression => - switch expression { - | T.EBindings(_) => "$$bound" - | T.EParameters(params) => `(${Js.Array2.toString(params)})` - | T.EList(aList) => - `(${Belt.List.map(aList, aValue => toString(aValue)) - ->Extra.List.interperse(" ") - ->Belt.List.toArray - ->Js.String.concatMany("")})` - | EValue(aValue) => ExpressionValue.toString(aValue) - } - -let toStringResult = codeResult => - switch codeResult { - | Ok(a) => `Ok(${toString(a)})` - | Error(m) => `Error(${Js.String.make(m)})` - } - /* Converts a MathJs code to expression */ @@ -49,14 +26,6 @@ let parse_ = (expr: string, parser, converter): result => let parse = (mathJsCode: string): result => mathJsCode->parse_(MathJs.Parse.parse, MathJs.ToExpression.fromNode) -let parsePartial = (mathJsCode: string): result => - mathJsCode->parse_(MathJs.Parse.parse, MathJs.ToExpression.fromPartialNode) - -let parseOuter = (mathJsCode: string): result => - mathJsCode->parse_(MathJs.Parse.parse, MathJs.ToExpression.fromOuterNode) - -let defaultBindings: T.bindings = Belt.Map.String.empty - /* Recursively evaluate/reduce the expression (Lisp AST) */ @@ -64,144 +33,63 @@ let rec reduceExpression = (expression: t, bindings: T.bindings, environment: en expressionValue, 'e, > => { - /* - Macros are like functions but instead of taking values as parameters, - they take expressions as parameters and return a new expression. - Macros are used to define language building blocks. They are like Lisp macros. - */ - let doMacroCall = (list: list, bindings: T.bindings, environment: environment): result< - t, - 'e, - > => - Reducer_Dispatch_BuiltInMacros.dispatchMacroCall(list, bindings, environment, reduceExpression) - - let applyParametersToLambda = ( - internal: internalCode, - parameters: array, - args: list, - environment, - ): result => { - let expr = castInternalCodeToExpression(internal) - let parameterList = parameters->Belt.List.fromArray - let zippedParameterList = parameterList->Belt.List.zip(args) - let bindings = Belt.List.reduce(zippedParameterList, defaultBindings, (a, (p, e)) => - a->Belt.Map.String.set(p, e->T.EValue) - ) - let newExpression = Builder.passToFunction( - "$$bindExpression", - list{Builder.passToFunction("$$bindings", list{}), expr}, - ) - reduceExpression(newExpression, bindings, environment) + switch expression { + | T.EValue(value) => value->Ok + | T.EList(list) => + switch list { + | list{EValue(EvCall(fName)), ..._args} => + switch Macro.isMacroName(fName) { + // A macro expands then reduces itself + | true => Macro.doMacroCall(expression, bindings, environment, reduceExpression) + | false => reduceExpressionList(list, bindings, environment) + } + | _ => reduceExpressionList(list, bindings, environment) + } } - - /* - After reducing each level of expression(Lisp AST), we have a value list to evaluate - */ - let reduceValueList = (valueList: list, environment): result< - expressionValue, - 'e, - > => - switch valueList { - | list{EvCall(fName), ...args} => - (fName, args->Belt.List.toArray)->BuiltIn.dispatch(environment) - // "(lambda(x=>internal) param)" - | list{EvLambda((parameters, internal)), ...args} => - applyParametersToLambda(internal, parameters, args, environment) - | _ => valueList->Belt.List.toArray->ExpressionValue.EvArray->Ok - } - - let rec seekMacros = (expression: t, bindings: T.bindings, environment): result => - switch expression { - | T.EValue(_value) => expression->Ok - | T.EBindings(_value) => expression->Ok - | T.EParameters(_value) => expression->Ok - | T.EList(list) => { - let racc: result, 'e> = list->Belt.List.reduceReverse(Ok(list{}), ( - racc, - each: expression, - ) => - racc->Result.flatMap(acc => { - each - ->seekMacros(bindings, environment) - ->Result.flatMap(newNode => { - acc->Belt.List.add(newNode)->Ok - }) - }) - ) - racc->Result.flatMap(acc => acc->doMacroCall(bindings, environment)) - } - } - - let rec reduceExpandedExpression = (expression: t, environment): result => - switch expression { - | T.EList(list{T.EValue(EvCall("$lambda")), T.EParameters(parameters), functionDefinition}) => - EvLambda((parameters, functionDefinition->castExpressionToInternalCode))->Ok - | T.EValue(value) => value->Ok - | T.EList(list) => { - let racc: result, 'e> = list->Belt.List.reduceReverse(Ok(list{}), ( - racc, - each: expression, - ) => - racc->Result.flatMap(acc => { - each - ->reduceExpandedExpression(environment) - ->Result.flatMap(newNode => { - acc->Belt.List.add(newNode)->Ok - }) - }) - ) - racc->Result.flatMap(acc => acc->reduceValueList(environment)) - } - | EBindings(_bindings) => RETodo("Error: Bindings cannot be reduced to values")->Error - | EParameters(_parameters) => - RETodo("Error: Lambda Parameters cannot be reduced to values")->Error - } - - let rExpandedExpression: result = expression->seekMacros(bindings, environment) - rExpandedExpression->Result.flatMap(expandedExpression => - expandedExpression->reduceExpandedExpression(environment) +} +and reduceExpressionList = ( + expressions: list, + bindings: T.bindings, + environment: environment, +): result => { + let racc: result, 'e> = expressions->Belt.List.reduceReverse(Ok(list{}), ( + racc, + each: expression, + ) => + racc->Result.flatMap(acc => { + each + ->reduceExpression(bindings, environment) + ->Result.map(newNode => { + acc->Belt.List.add(newNode) + }) + }) ) + racc->Result.flatMap(acc => acc->reduceValueList(environment)) } -let evalUsingExternalBindingsExpression_ = (aExpression, bindings, environment): result< +/* + After reducing each level of expression(Lisp AST), we have a value list to evaluate + */ +and reduceValueList = (valueList: list, environment): result< + expressionValue, + 'e, +> => + switch valueList { + | list{EvCall(fName), ...args} => (fName, args->Belt.List.toArray)->BuiltIn.dispatch(environment) + + | list{EvLambda(lamdaCall), ...args} => + Lambda.doLambdaCall(lamdaCall, args, environment, reduceExpression) + | _ => valueList->Belt.List.toArray->ExpressionValue.EvArray->Ok + } + +let evalUsingBindingsExpression_ = (aExpression, bindings, environment): result< expressionValue, 'e, > => reduceExpression(aExpression, bindings, environment) -/* - Evaluates MathJs code via Reducer using bindings and answers the result. - When bindings are used, the code is a partial code as if it is cut from a larger code. - Therefore all statements are assignments. -*/ -let evalPartial_ = (codeText: string, bindings: T.bindings, environment: environment) => { - parsePartial(codeText)->Result.flatMap(expression => - expression->evalUsingExternalBindingsExpression_(bindings, environment) - ) -} - -/* - Evaluates MathJs code via Reducer using bindings and answers the result. - When bindings are used, the code is a partial code as if it is cut from a larger code. - Therefore all statments are assignments. -*/ -let evalOuter_ = (codeText: string, bindings: T.bindings, environment: environment) => { - parseOuter(codeText)->Result.flatMap(expression => - expression->evalUsingExternalBindingsExpression_(bindings, environment) - ) -} - -let externalBindingsToBindings = (externalBindings: externalBindings): T.bindings => { - let keys = Js.Dict.keys(externalBindings) - keys->Belt.Array.reduce(defaultBindings, (acc, key) => { - let value = Js.Dict.unsafeGet(externalBindings, key) - acc->Belt.Map.String.set(key, T.EValue(value)) - }) -} - let evaluateUsingOptions = ( ~environment: option, ~externalBindings: option, - ~isPartial: option, code: string, ): result => { let anEnvironment = switch environment { @@ -214,24 +102,15 @@ let evaluateUsingOptions = ( | None => ReducerInterface_ExpressionValue.defaultExternalBindings } - let anIsPartial = switch isPartial { - | Some(isPartial) => isPartial - | None => false - } + let bindings = anExternalBindings->Bindings.fromExternalBindings - let bindings = anExternalBindings->externalBindingsToBindings - - if anIsPartial { - evalPartial_(code, bindings, anEnvironment) - } else { - evalOuter_(code, bindings, anEnvironment) - } + parse(code)->Result.flatMap(expr => evalUsingBindingsExpression_(expr, bindings, anEnvironment)) } /* Evaluates MathJs code and bindings via Reducer and answers the result */ let evaluate = (code: string): result => { - evaluateUsingOptions(~environment=None, ~externalBindings=None, ~isPartial=None, code) + evaluateUsingOptions(~environment=None, ~externalBindings=None, code) } let eval = evaluate diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res new file mode 100644 index 00000000..add7f614 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res @@ -0,0 +1,73 @@ +module ExpressionT = Reducer_Expression_T +module ExpressionValue = ReducerInterface.ExpressionValue +module Result = Belt.Result + +type errorValue = Reducer_ErrorValue.errorValue +type expression = ExpressionT.expression +type expressionValue = ExpressionValue.expressionValue +type externalBindings = ReducerInterface_ExpressionValue.externalBindings + +let defaultBindings: ExpressionT.bindings = Belt.Map.String.empty + +let fromExternalBindings = (externalBindings: externalBindings): ExpressionT.bindings => { + let keys = Js.Dict.keys(externalBindings) + keys->Belt.Array.reduce(defaultBindings, (acc, key) => { + let value = Js.Dict.unsafeGet(externalBindings, key) + acc->Belt.Map.String.set(key, value) + }) +} + +let toExternalBindings = (bindings: ExpressionT.bindings): externalBindings => { + let keys = Belt.Map.String.keysToArray(bindings) + keys->Belt.Array.reduce(Js.Dict.empty(), (acc, key) => { + let value = bindings->Belt.Map.String.getExn(key) + Js.Dict.set(acc, key, value) + acc + }) +} + +let fromValue = (aValue: expressionValue) => + switch aValue { + | EvRecord(externalBindings) => fromExternalBindings(externalBindings) + | _ => defaultBindings + } + +let externalFromArray = anArray => Js.Dict.fromArray(anArray) + +let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") + +let rec replaceSymbols = (bindings: ExpressionT.bindings, expression: expression): result< + expression, + errorValue, +> => + switch expression { + | ExpressionT.EValue(value) => + replaceSymbolOnValue(bindings, value)->Result.map(evValue => evValue->ExpressionT.EValue) + | ExpressionT.EList(list) => + switch list { + | list{EValue(EvCall(fName)), ..._args} => + switch isMacroName(fName) { + // A macro reduces itself so we dont dive in it + | true => expression->Ok + | false => replaceSymbolsOnExpressionList(bindings, list) + } + | _ => replaceSymbolsOnExpressionList(bindings, list) + } + } + +and replaceSymbolsOnExpressionList = (bindings, list) => { + let racc = list->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) => + racc->Result.flatMap(acc => { + replaceSymbols(bindings, each)->Result.flatMap(newNode => { + acc->Belt.List.add(newNode)->Ok + }) + }) + ) + racc->Result.map(acc => acc->ExpressionT.EList) +} +and replaceSymbolOnValue = (bindings, evValue: expressionValue) => + switch evValue { + | EvSymbol(symbol) | EvCall(symbol) => + Belt.Map.String.getWithDefault(bindings, symbol, evValue)->Ok + | _ => evValue->Ok + } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Builder.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Builder.res deleted file mode 100644 index 4e5a988e..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Builder.res +++ /dev/null @@ -1,16 +0,0 @@ -module ErrorValue = Reducer_ErrorValue -module ExpressionT = Reducer_Expression_T -module ExpressionValue = ReducerInterface.ExpressionValue -module Result = Belt.Result - -type errorValue = ErrorValue.errorValue -type expression = ExpressionT.expression - -let passToFunction = (fName: string, lispArgs: list): expression => { - let toEvCallValue = (name: string): expression => name->ExpressionValue.EvCall->ExpressionT.EValue - let fn = fName->toEvCallValue - list{fn, ...lispArgs}->ExpressionT.EList -} - -let toEvSymbolValue = (name: string): expression => - name->ExpressionValue.EvSymbol->ExpressionT.EValue diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res new file mode 100644 index 00000000..ec3a0214 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res @@ -0,0 +1,60 @@ +module BBindings = Reducer_Expression_Bindings +module BErrorValue = Reducer_ErrorValue +module BExpressionT = Reducer_Expression_T +module BExpressionValue = ReducerInterface.ExpressionValue + +type errorValue = BErrorValue.errorValue +type expression = BExpressionT.expression +type internalCode = ReducerInterface_ExpressionValue.internalCode + +external castExpressionToInternalCode: expression => internalCode = "%identity" + +let eArray = anArray => anArray->BExpressionValue.EvArray->BExpressionT.EValue + +let eArrayString = anArray => anArray->BExpressionValue.EvArrayString->BExpressionT.EValue + +let eBindings = (anArray: array<(string, BExpressionValue.expressionValue)>) => + anArray->Js.Dict.fromArray->EvRecord->BExpressionT.EValue + +let eBool = aBool => aBool->BExpressionValue.EvBool->BExpressionT.EValue + +let eCall = (name: string): expression => name->BExpressionValue.EvCall->BExpressionT.EValue + +let eFunction = (fName: string, lispArgs: list): expression => { + let fn = fName->eCall + list{fn, ...lispArgs}->BExpressionT.EList +} + +let eLambda = (parameters: array, context, expr) => + BExpressionValue.EvLambda( + parameters, + context, + expr->castExpressionToInternalCode, + )->BExpressionT.EValue + +let eNumber = aNumber => aNumber->BExpressionValue.EvNumber->BExpressionT.EValue + +let eRecord = aRecord => aRecord->BExpressionValue.EvRecord->BExpressionT.EValue + +let eString = aString => aString->BExpressionValue.EvString->BExpressionT.EValue + +let eSymbol = (name: string): expression => name->BExpressionValue.EvSymbol->BExpressionT.EValue + +let eList = (list: list): expression => list->BExpressionT.EList + +let eBlock = (exprs: list): expression => eFunction("$$block", exprs) + +let eLetStatement = (symbol: string, valueExpression: expression): expression => + eFunction("$let", list{eSymbol(symbol), valueExpression}) + +let eBindStatement = (bindingExpr: expression, letStatement: expression): expression => + eFunction("$$bindStatement", list{bindingExpr, letStatement}) + +let eBindStatementDefault = (letStatement: expression): expression => + eFunction("$$bindStatement", list{letStatement}) + +let eBindExpression = (bindingExpr: expression, expression: expression): expression => + eFunction("$$bindExpression", list{bindingExpr, expression}) + +let eBindExpressionDefault = (expression: expression): expression => + eFunction("$$bindExpression", list{expression}) 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 new file mode 100644 index 00000000..a2d795c0 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res @@ -0,0 +1,35 @@ +module Bindings = Reducer_Expression_Bindings +module ExpressionBuilder = Reducer_Expression_ExpressionBuilder +module ExpressionT = Reducer_Expression_T +module ExpressionValue = ReducerInterface.ExpressionValue + +type environment = ReducerInterface_ExpressionValue.environment +type expression = ExpressionT.expression +type expressionValue = ReducerInterface_ExpressionValue.expressionValue +type externalBindings = ReducerInterface_ExpressionValue.externalBindings +type internalCode = ReducerInterface_ExpressionValue.internalCode + +external castInternalCodeToExpression: internalCode => expression = "%identity" + +let applyParametersToLambda = ( + internal: internalCode, + parameters: array, + args: list, + context: externalBindings, + environment, + reducer: ExpressionT.reducerFn, +): result => { + let expr = castInternalCodeToExpression(internal) + let parameterList = parameters->Belt.List.fromArray + let zippedParameterList = parameterList->Belt.List.zip(args) + let bindings = Belt.List.reduce(zippedParameterList, context->Bindings.fromExternalBindings, ( + acc, + (variable, variableValue), + ) => acc->Belt.Map.String.set(variable, variableValue)) + let newExpression = ExpressionBuilder.eBlock(list{expr}) + reducer(newExpression, bindings, environment) +} + +let doLambdaCall = ((parameters, context, internal), args, environment, reducer) => { + applyParametersToLambda(internal, parameters, args, context, environment, reducer) +} diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res new file mode 100644 index 00000000..5ac19502 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res @@ -0,0 +1,35 @@ +module ExpressionT = Reducer_Expression_T +module ExpressionValue = ReducerInterface.ExpressionValue +module Result = Belt.Result + +type environment = ExpressionValue.environment +type expression = ExpressionT.expression +type expressionValue = ExpressionValue.expressionValue + +let expandMacroCall = ( + macroExpression: expression, + bindings: ExpressionT.bindings, + environment: environment, + reduceExpression: ExpressionT.reducerFn, +): result => + Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( + macroExpression, + bindings, + environment, + reduceExpression, + ) + +let doMacroCall = ( + macroExpression: expression, + bindings: ExpressionT.bindings, + environment: environment, + reduceExpression: ExpressionT.reducerFn, +): result => + expandMacroCall( + macroExpression, + bindings, + environment, + reduceExpression, + )->Result.flatMap(expression => reduceExpression(expression, bindings, environment)) + +let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") 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 c3fd822c..b21ba8b7 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 @@ -1,5 +1,3 @@ -open ReducerInterface.ExpressionValue - /* An expression is a Lisp AST. An expression is either a primitive value or a list of expressions. In the case of a list of expressions (e1, e2, e3, ...eN), the semantic is @@ -8,9 +6,51 @@ open ReducerInterface.ExpressionValue A Lisp AST contains only expressions/primitive values to apply to their left. The act of defining the semantics of a functional language is to write it in terms of Lisp AST. */ +module Extra = Reducer_Extra +module ExpressionValue = ReducerInterface.ExpressionValue + +type expressionValue = ExpressionValue.expressionValue +type environment = ExpressionValue.environment + type rec expression = | EList(list) // A list to map-reduce | EValue(expressionValue) // Irreducible built-in value. Reducer should not know the internals. External libraries are responsible - | EBindings(bindings) // $let kind of statements return bindings; for internal use only - | EParameters(array) // for $defun; for internal use only -and bindings = Belt.Map.String.t +and bindings = Belt.Map.String.t + +type reducerFn = ( + expression, + bindings, + environment, +) => result + +/* + Converts the expression to String +*/ +let rec toString = expression => + switch expression { + | EList(aList) => + `(${Belt.List.map(aList, aValue => toString(aValue)) + ->Extra.List.interperse(" ") + ->Belt.List.toArray + ->Js.String.concatMany("")})` + | EValue(aValue) => ExpressionValue.toString(aValue) + } + +let toStringResult = codeResult => + switch codeResult { + | Ok(a) => `Ok(${toString(a)})` + | Error(m) => `Error(${Reducer_ErrorValue.errorToString(m)})` + } + +let inspect = (expr: expression): expression => { + Js.log(toString(expr)) + expr +} + +let inspectResult = (r: result): result< + expression, + Reducer_ErrorValue.errorValue, +> => { + Js.log(toStringResult(r)) + r +} diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res index 5dc53413..ca040190 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res @@ -1,37 +1,34 @@ -module Builder = Reducer_Expression_Builder +/* * WARNING. DO NOT EDIT, BEAUTIFY, COMMENT ON OR REFACTOR THIS CODE. +We will stop using MathJs parser and +this whole file will go to trash +**/ module ErrorValue = Reducer_ErrorValue +module ExpressionBuilder = Reducer_Expression_ExpressionBuilder module ExpressionT = Reducer_Expression_T module ExpressionValue = ReducerInterface.ExpressionValue module JavaScript = Reducer_Js module Parse = Reducer_MathJs_Parse module Result = Belt.Result +type errorValue = ErrorValue.errorValue type expression = ExpressionT.expression type expressionValue = ExpressionValue.expressionValue -type errorValue = ErrorValue.errorValue -type blockTag = - | ImportVariablesStatement - | ExportVariablesExpression -type tagOrNode = - | BlockTag(blockTag) - | BlockNode(Parse.node) +let blockToNode = block => block["node"] -let toTagOrNode = block => BlockNode(block["node"]) - -let rec fromNode = (mathJsNode: Parse.node): result => +let rec fromInnerNode = (mathJsNode: Parse.node): result => Parse.castNodeType(mathJsNode)->Result.flatMap(typedMathJsNode => { let fromNodeList = (nodeList: list): result, 'e> => Belt.List.reduceReverse(nodeList, Ok(list{}), (racc, currNode) => racc->Result.flatMap(acc => - fromNode(currNode)->Result.map(currCode => list{currCode, ...acc}) + fromInnerNode(currNode)->Result.map(currCode => list{currCode, ...acc}) ) ) let caseFunctionNode = fNode => { let rLispArgs = fNode["args"]->Belt.List.fromArray->fromNodeList - rLispArgs->Result.flatMap(lispArgs => - Builder.passToFunction(fNode->Parse.nameOfFunctionNode, lispArgs)->Ok + rLispArgs->Result.map(lispArgs => + ExpressionBuilder.eFunction(fNode->Parse.nameOfFunctionNode, lispArgs) ) } @@ -42,18 +39,15 @@ let rec fromNode = (mathJsNode: Parse.node): result => (key: string, value: Parse.node), ) => racc->Result.flatMap(acc => - fromNode(value)->Result.map(valueExpression => { + fromInnerNode(value)->Result.map(valueExpression => { let entryCode = - list{ - key->ExpressionValue.EvString->ExpressionT.EValue, - valueExpression, - }->ExpressionT.EList + list{ExpressionBuilder.eString(key), valueExpression}->ExpressionT.EList list{entryCode, ...acc} }) ) ) rargs->Result.flatMap(args => - Builder.passToFunction("$constructRecord", list{ExpressionT.EList(args)})->Ok + ExpressionBuilder.eFunction("$constructRecord", list{ExpressionT.EList(args)})->Ok ) // $constructRecord gets a single argument: List of key-value paiers } @@ -66,7 +60,7 @@ let rec fromNode = (mathJsNode: Parse.node): result => Ok(list{}), (racc, currentPropertyMathJsNode) => racc->Result.flatMap(acc => - fromNode(currentPropertyMathJsNode)->Result.map(propertyCode => list{ + fromInnerNode(currentPropertyMathJsNode)->Result.map(propertyCode => list{ propertyCode, ...acc, }) @@ -77,28 +71,41 @@ let rec fromNode = (mathJsNode: Parse.node): result => let caseAccessorNode = (objectNode, indexNode) => { caseIndexNode(indexNode)->Result.flatMap(indexCode => { - fromNode(objectNode)->Result.flatMap(objectCode => - Builder.passToFunction("$atIndex", list{objectCode, indexCode})->Ok + fromInnerNode(objectNode)->Result.flatMap(objectCode => + ExpressionBuilder.eFunction("$atIndex", list{objectCode, indexCode})->Ok ) }) } + let caseBlock = (nodesArray: array): result => { + let rStatements: result, 'a> = + nodesArray + ->Belt.List.fromArray + ->Belt.List.reduceReverse(Ok(list{}), (racc, currNode) => + racc->Result.flatMap(acc => + fromInnerNode(currNode)->Result.map(currCode => list{currCode, ...acc}) + ) + ) + rStatements->Result.map(statements => ExpressionBuilder.eBlock(statements)) + } + let caseAssignmentNode = aNode => { - let symbol = aNode["object"]["name"]->Builder.toEvSymbolValue - let rValueExpression = fromNode(aNode["value"]) - rValueExpression->Result.flatMap(valueExpression => - Builder.passToFunction("$let", list{symbol, valueExpression})->Ok + let symbolName = aNode["object"]["name"] + let rValueExpression = fromInnerNode(aNode["value"]) + rValueExpression->Result.map(valueExpression => + ExpressionBuilder.eLetStatement(symbolName, valueExpression) ) } let caseFunctionAssignmentNode = faNode => { - let symbol = faNode["name"]->Builder.toEvSymbolValue - let rValueExpression = fromNode(faNode["expr"]) + let symbol = faNode["name"]->ExpressionBuilder.eSymbol + let rValueExpression = fromInnerNode(faNode["expr"]) rValueExpression->Result.flatMap(valueExpression => { - let lispParams = faNode["params"]->ExpressionT.EParameters - let lambda = Builder.passToFunction("$lambda", list{lispParams, valueExpression}) - Builder.passToFunction("$let", list{symbol, lambda})->Ok + let lispParams = ExpressionBuilder.eArrayString(faNode["params"]) + let valueBlock = ExpressionBuilder.eBlock(list{valueExpression}) + let lambda = ExpressionBuilder.eFunction("$$lambda", list{lispParams, valueBlock}) + ExpressionBuilder.eFunction("$let", list{symbol, lambda})->Ok }) } @@ -111,11 +118,11 @@ let rec fromNode = (mathJsNode: Parse.node): result => | MjArrayNode(aNode) => caseArrayNode(aNode) | MjAssignmentNode(aNode) => caseAssignmentNode(aNode) | MjSymbolNode(sNode) => { - let expr: expression = Builder.toEvSymbolValue(sNode["name"]) + let expr: expression = ExpressionBuilder.eSymbol(sNode["name"]) let rExpr: result = expr->Ok rExpr } - | MjBlockNode(bNode) => bNode["blocks"]->Belt.Array.map(toTagOrNode)->caseTagOrNodes + | MjBlockNode(bNode) => bNode["blocks"]->Js.Array2.map(blockToNode)->caseBlock | MjConstantNode(cNode) => cNode["value"]->JavaScript.Gate.jsToEv->Result.flatMap(v => v->ExpressionT.EValue->Ok) | MjFunctionAssignmentNode(faNode) => caseFunctionAssignmentNode(faNode) @@ -123,78 +130,10 @@ let rec fromNode = (mathJsNode: Parse.node): result => | MjIndexNode(iNode) => caseIndexNode(iNode) | MjObjectNode(oNode) => caseObjectNode(oNode) | MjOperatorNode(opNode) => opNode->Parse.castOperatorNodeToFunctionNode->caseFunctionNode - | MjParenthesisNode(pNode) => pNode["content"]->fromNode + | MjParenthesisNode(pNode) => pNode["content"]->fromInnerNode } rFinalExpression }) -and caseTagOrNodes = (tagOrNodes): result => { - let initialBindings = Builder.passToFunction("$$bindings", list{})->Ok - let lastIndex = Belt.Array.length(tagOrNodes) - 1 - tagOrNodes->Belt.Array.reduceWithIndex(initialBindings, (rPreviousBindings, tagOrNode, i) => { - rPreviousBindings->Result.flatMap(previousBindings => { - let rStatement: result = switch tagOrNode { - | BlockNode(node) => fromNode(node) - | BlockTag(tag) => - switch tag { - | ImportVariablesStatement => - Builder.passToFunction("$importVariablesStatement", list{})->Ok - | ExportVariablesExpression => - Builder.passToFunction("$exportVariablesExpression", list{})->Ok - } - } - let bindName = if i == lastIndex { - "$$bindExpression" - } else { - "$$bindStatement" - } - - rStatement->Result.flatMap((statement: expression) => { - Builder.passToFunction(bindName, list{previousBindings, statement})->Ok - }) - }) - }) -} - -let fromPartialNode = (mathJsNode: Parse.node): result => { - Parse.castNodeType(mathJsNode)->Result.flatMap(typedMathJsNode => { - let casePartialBlockNode = (bNode: Parse.blockNode) => { - let blocksOrTags = bNode["blocks"]->Belt.Array.map(toTagOrNode) - let completed = Js.Array2.concat(blocksOrTags, [BlockTag(ExportVariablesExpression)]) - completed->caseTagOrNodes - } - - let casePartialExpression = (node: Parse.node) => { - let completed = [BlockNode(node), BlockTag(ExportVariablesExpression)] - - completed->caseTagOrNodes - } - - let rFinalExpression: result = switch typedMathJsNode { - | MjBlockNode(bNode) => casePartialBlockNode(bNode) - | _ => casePartialExpression(mathJsNode) - } - rFinalExpression - }) -} - -let fromOuterNode = (mathJsNode: Parse.node): result => { - Parse.castNodeType(mathJsNode)->Result.flatMap(typedMathJsNode => { - let casePartialBlockNode = (bNode: Parse.blockNode) => { - let blocksOrTags = bNode["blocks"]->Belt.Array.map(toTagOrNode) - let completed = blocksOrTags - completed->caseTagOrNodes - } - - let casePartialExpression = (node: Parse.node) => { - let completed = [BlockNode(node)] - completed->caseTagOrNodes - } - - let rFinalExpression: result = switch typedMathJsNode { - | MjBlockNode(bNode) => casePartialBlockNode(bNode) - | _ => casePartialExpression(mathJsNode) - } - rFinalExpression - }) -} +let fromNode = (node: Parse.node): result => + fromInnerNode(node)->Result.map(expr => ExpressionBuilder.eBlock(list{expr})) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res index 7e8d1150..31168425 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res @@ -11,17 +11,19 @@ type internalCode = Object @genType type rec expressionValue = | EvArray(array) + | EvArrayString(array) | EvBool(bool) | EvCall(string) // External function call | EvDistribution(DistributionTypes.genericDist) - | EvLambda((array, internalCode)) + | EvLambda((array, record, internalCode)) | EvNumber(float) - | EvRecord(Js.Dict.t) + | EvRecord(record) | EvString(string) | EvSymbol(string) +and record = Js.Dict.t @genType -type externalBindings = Js.Dict.t +type externalBindings = record @genType let defaultExternalBindings: externalBindings = Js.Dict.empty() @@ -29,20 +31,21 @@ type functionCall = (string, array) let rec toString = aValue => switch aValue { + | EvArray(anArray) => { + let args = anArray->Js.Array2.map(each => toString(each))->Js.Array2.toString + `[${args}]` + } + | EvArrayString(anArray) => { + let args = anArray->Js.Array2.toString + `[${args}]` + } | EvBool(aBool) => Js.String.make(aBool) | EvCall(fName) => `:${fName}` - | EvLambda((parameters, _internalCode)) => `lambda(${Js.Array2.toString(parameters)}=>internal)` + | EvLambda((parameters, _context, _internalCode)) => + `lambda(${Js.Array2.toString(parameters)}=>internal)` | EvNumber(aNumber) => Js.String.make(aNumber) | EvString(aString) => `'${aString}'` | EvSymbol(aString) => `:${aString}` - | EvArray(anArray) => { - let args = - anArray - ->Belt.Array.map(each => toString(each)) - ->Extra_Array.interperse(", ") - ->Js.String.concatMany("") - `[${args}]` - } | EvRecord(aRecord) => aRecord->toStringRecord | EvDistribution(dist) => GenericDist.toString(dist) } @@ -50,19 +53,19 @@ and toStringRecord = aRecord => { let pairs = aRecord ->Js.Dict.entries - ->Belt.Array.map(((eachKey, eachValue)) => `${eachKey}: ${toString(eachValue)}`) - ->Extra_Array.interperse(", ") - ->Js.String.concatMany("") + ->Js.Array2.map(((eachKey, eachValue)) => `${eachKey}: ${toString(eachValue)}`) + ->Js.Array2.toString `{${pairs}}` } let toStringWithType = aValue => switch aValue { | EvArray(_) => `Array::${toString(aValue)}` + | EvArrayString(_) => `ArrayString::${toString(aValue)}` | EvBool(_) => `Bool::${toString(aValue)}` | EvCall(_) => `Call::${toString(aValue)}` | EvDistribution(_) => `Distribution::${toString(aValue)}` - | EvLambda((_parameters, _internalCode)) => `Lambda::${toString(aValue)}` + | EvLambda((_parameters, _context, _internalCode)) => `Lambda::${toString(aValue)}` | EvNumber(_) => `Number::${toString(aValue)}` | EvRecord(_) => `Record::${toString(aValue)}` | EvString(_) => `String::${toString(aValue)}` @@ -70,7 +73,7 @@ let toStringWithType = aValue => } let argsToString = (args: array): string => { - args->Belt.Array.map(arg => arg->toString)->Extra_Array.interperse(", ")->Js.String.concatMany("") + args->Js.Array2.map(arg => arg->toString)->Js.Array2.toString } let toStringFunctionCall = ((fn, args)): string => `${fn}(${argsToString(args)})` From 351381339c443155d824b68f5ae88a49f2e7bdd8 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 29 Apr 2022 18:14:02 +0200 Subject: [PATCH 056/146] bug fixed logs removed --- .../Reducer_Dispatch_BuiltInMacros_test.res | 21 ++++++++++++++++++ .../Reducer/Reducer_externalBindings_test.res | 2 ++ .../Reducer_Dispatch_BuiltIn.res | 4 ++-- .../Reducer_Dispatch_BuiltInMacros.res | 22 +++++++------------ .../Reducer_Expression/Reducer_Expression.res | 4 ++-- .../Reducer/Reducer_Js/Reducer_Js_Gate.res | 4 ++-- .../ReducerInterface_GenericDistribution.res | 8 +++---- 7 files changed, 41 insertions(+), 24 deletions(-) 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 ecf97697..eb6e6c0d 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 @@ -99,6 +99,27 @@ describe("block", () => { ) // Empty block testMacro([], eBlock(list{}), "Ok(:undefined block)") //TODO: should be an error + // :$$block (:$$block (:$let :y (:add :x 1)) :y)" + testMacro( + [], + eBlock(list{ + eBlock(list{ + eLetStatement("y", eFunction("add", list{eSymbol("x"), eNumber(1.)})), + eSymbol("y"), + }), + }), + "Ok((:$$bindExpression (:$$block (:$let :y (:add :x 1)) :y)))", + ) + MyOnly.testMacroEval( + [("x", EvNumber(1.))], + eBlock(list{ + eBlock(list{ + eLetStatement("y", eFunction("add", list{eSymbol("x"), eNumber(1.)})), + eSymbol("y"), + }), + }), + "Ok(2)", + ) }) describe("lambda", () => { diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res index 4c2546f4..3a903343 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res @@ -33,7 +33,9 @@ open Reducer_TestHelpers describe("Eval with Bindings", () => { testEvalBindingsToBe("x", list{("x", ExpressionValue.EvNumber(1.))}, "Ok(1)") testEvalBindingsToBe("x+1", list{("x", ExpressionValue.EvNumber(1.))}, "Ok(2)") + testParseToBe("y = x+1; y", "Ok((:$$block (:$$block (:$let :y (:add :x 1)) :y)))") testEvalBindingsToBe("y = x+1; y", list{("x", ExpressionValue.EvNumber(1.))}, "Ok(2)") + testEvalBindingsToBe("y = x+1", list{("x", ExpressionValue.EvNumber(1.))}, "Ok({x: 1,y: 2})") }) /* diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 04bd1be4..0067441c 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -21,12 +21,12 @@ let callInternal = (call: functionCall, _environment): result<'b, errorValue> => } let constructRecord = arrayOfPairs => { - Belt.Array.map(arrayOfPairs, pairValue => { + Belt.Array.map(arrayOfPairs, pairValue => switch pairValue { | EvArray([EvString(key), valueValue]) => (key, valueValue) | _ => ("wrong key type", pairValue->toStringWithType->EvString) } - }) + ) ->Js.Dict.fromArray ->EvRecord ->Ok diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index 951f444f..b18c927a 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -19,14 +19,10 @@ let dispatchMacroCall = ( environment, reduceExpression: ExpressionT.reducerFn, ): result => { - let doBindStatement = (bindingExpr: expression, statement: expression, environment) => + let doBindStatement = (bindingExpr: expression, statement: expression, environment) => switch statement { | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), symbolExpr, statement}) => { - let rExternalBindingsValue = reduceExpression( - bindingExpr, - Bindings.defaultBindings, - environment, - ) + let rExternalBindingsValue = reduceExpression(bindingExpr, bindings, environment) rExternalBindingsValue->Result.flatMap(externalBindingsValue => { let newBindings = Bindings.fromValue(externalBindingsValue) @@ -41,13 +37,15 @@ let dispatchMacroCall = ( } | _ => REAssignmentExpected->Error } + - let doBindExpression = (bindingExpr: expression, statement: expression, environment) => + let doBindExpression = (bindingExpr: expression, statement: expression, environment) => switch statement { | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), symbolExpr, statement}) => { let rExternalBindingsValue = reduceExpression( bindingExpr, - Bindings.defaultBindings, + Belt.Map.String.fromArray([("x", ExpressionValue.EvNumber(666.))]), + // bindingsToHandDown, environment, ) @@ -68,11 +66,7 @@ let dispatchMacroCall = ( }) } | _ => { - let rExternalBindingsValue = reduceExpression( - bindingExpr, - Bindings.defaultBindings, - environment, - ) + let rExternalBindingsValue = reduceExpression(bindingExpr, bindings, environment) rExternalBindingsValue->Result.flatMap(externalBindingsValue => { let newBindings = Bindings.fromValue(externalBindingsValue) let rNewStatement = Bindings.replaceSymbols(newBindings, statement) @@ -80,7 +74,7 @@ let dispatchMacroCall = ( }) } } - + let doBlock = (exprs: list, _bindings: ExpressionT.bindings, _environment): result< expression, errorValue, 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 e69c27d8..bbd7cc3b 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 @@ -32,7 +32,7 @@ let parse = (mathJsCode: string): result => let rec reduceExpression = (expression: t, bindings: T.bindings, environment: environment): result< expressionValue, 'e, -> => { +> => switch expression { | T.EValue(value) => value->Ok | T.EList(list) => @@ -46,7 +46,7 @@ let rec reduceExpression = (expression: t, bindings: T.bindings, environment: en | _ => reduceExpressionList(list, bindings, environment) } } -} + and reduceExpressionList = ( expressions: list, bindings: T.bindings, diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res index ad83edb1..691a571c 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res @@ -8,11 +8,11 @@ external castString: unit => string = "%identity" /* As JavaScript returns us any type, we need to type check and cast type propertype before using it */ -let jsToEv = (jsValue): result => { +let jsToEv = (jsValue): result => switch Js.typeof(jsValue) { | "boolean" => jsValue->castBool->EvBool->Ok | "number" => jsValue->castNumber->EvNumber->Ok | "string" => jsValue->castString->EvString->Ok | other => RETodo(`Unhandled MathJs literal type: ${Js.String.make(other)}`)->Error } -} + diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index c782e6af..a5c5b22e 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -28,14 +28,14 @@ module Helpers = { let catchAndConvertTwoArgsToDists = (args: array): option<( DistributionTypes.genericDist, DistributionTypes.genericDist, - )> => { + )> => switch args { | [EvDistribution(a), EvDistribution(b)] => Some((a, b)) | [EvNumber(a), EvDistribution(b)] => Some((GenericDist.fromFloat(a), b)) | [EvDistribution(a), EvNumber(b)] => Some((a, GenericDist.fromFloat(b))) | _ => None } - } + let toFloatFn = ( fnCall: DistributionTypes.DistributionOperation.toFloat, @@ -119,7 +119,7 @@ module Helpers = { mixtureWithGivenWeights(distributions, weights) } - let mixture = (args: array): DistributionOperation.outputType => { + let mixture = (args: array): DistributionOperation.outputType => switch E.A.last(args) { | Some(EvArray(b)) => { let weights = parseNumberArray(b) @@ -138,7 +138,7 @@ module Helpers = { } | _ => GenDistError(ArgumentError("Last argument of mx must be array or distribution")) } - } + } module SymbolicConstructors = { From 3bbc5e7149d0a71a0f4274d9eaa845aef93b7277 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 29 Apr 2022 19:03:58 +0200 Subject: [PATCH 057/146] Add evaluate partial for back compatibility --- .../squiggle-lang/src/rescript/Reducer/Reducer.res | 1 + .../squiggle-lang/src/rescript/Reducer/Reducer.resi | 6 ++++++ .../Reducer_Expression/Reducer_Expression.res | 12 ++++++++++++ 3 files changed, 19 insertions(+) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res index c9c9f41e..24c985d8 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res @@ -11,4 +11,5 @@ type expressionValue = ReducerInterface_ExpressionValue.expressionValue type externalBindings = ReducerInterface_ExpressionValue.externalBindings let evaluate = Expression.evaluate let evaluateUsingOptions = Expression.evaluateUsingOptions +let evaluatePartialUsingExternalBindings = Expression.evaluatePartialUsingExternalBindings let parse = Expression.parse diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi index 880dd1e7..4e86361a 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi @@ -21,6 +21,12 @@ let evaluateUsingOptions: ( string, ) => result @genType +let evaluatePartialUsingExternalBindings: ( + string, + QuriSquiggleLang.ReducerInterface_ExpressionValue.externalBindings, + QuriSquiggleLang.ReducerInterface_ExpressionValue.environment, +) => result +@genType let evaluate: string => result let parse: string => result 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 bbd7cc3b..02043320 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 @@ -114,3 +114,15 @@ let evaluate = (code: string): result => { evaluateUsingOptions(~environment=None, ~externalBindings=None, code) } let eval = evaluate +let evaluatePartialUsingExternalBindings = ( + code: string, + externalBindings: ReducerInterface_ExpressionValue.externalBindings, + environment: ReducerInterface_ExpressionValue.environment, +): result => { + let rAnswer = evaluateUsingOptions(~environment=Some(environment), ~externalBindings=Some(externalBindings), code) + switch rAnswer { + | Ok(EvRecord(externalBindings)) => Ok(externalBindings) + | Ok(_) => Error(Reducer_ErrorValue.RESyntaxError(`Partials must end with an assignment or record`)) + | Error(err) => err->Error + } +} From bbe8eced29d5cb2adfc31072c20bce5032a9a276 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 29 Apr 2022 19:31:34 +0200 Subject: [PATCH 058/146] format --- .../Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res | 2 +- .../Reducer_Dispatch_BuiltInMacros.res | 7 +++---- .../Reducer_Expression/Reducer_Expression.res | 15 ++++++++++----- .../Reducer/Reducer_Js/Reducer_Js_Gate.res | 3 +-- .../ReducerInterface_GenericDistribution.res | 6 ++---- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 0067441c..25fc05a7 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -21,7 +21,7 @@ let callInternal = (call: functionCall, _environment): result<'b, errorValue> => } let constructRecord = arrayOfPairs => { - Belt.Array.map(arrayOfPairs, pairValue => + Belt.Array.map(arrayOfPairs, pairValue => switch pairValue { | EvArray([EvString(key), valueValue]) => (key, valueValue) | _ => ("wrong key type", pairValue->toStringWithType->EvString) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index b18c927a..f3f6d8c3 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -19,7 +19,7 @@ let dispatchMacroCall = ( environment, reduceExpression: ExpressionT.reducerFn, ): result => { - let doBindStatement = (bindingExpr: expression, statement: expression, environment) => + let doBindStatement = (bindingExpr: expression, statement: expression, environment) => switch statement { | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), symbolExpr, statement}) => { let rExternalBindingsValue = reduceExpression(bindingExpr, bindings, environment) @@ -37,9 +37,8 @@ let dispatchMacroCall = ( } | _ => REAssignmentExpected->Error } - - let doBindExpression = (bindingExpr: expression, statement: expression, environment) => + let doBindExpression = (bindingExpr: expression, statement: expression, environment) => switch statement { | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), symbolExpr, statement}) => { let rExternalBindingsValue = reduceExpression( @@ -74,7 +73,7 @@ let dispatchMacroCall = ( }) } } - + let doBlock = (exprs: list, _bindings: ExpressionT.bindings, _environment): result< expression, errorValue, 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 02043320..5eeb51c7 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 @@ -32,7 +32,7 @@ let parse = (mathJsCode: string): result => let rec reduceExpression = (expression: t, bindings: T.bindings, environment: environment): result< expressionValue, 'e, -> => +> => switch expression { | T.EValue(value) => value->Ok | T.EList(list) => @@ -119,10 +119,15 @@ let evaluatePartialUsingExternalBindings = ( externalBindings: ReducerInterface_ExpressionValue.externalBindings, environment: ReducerInterface_ExpressionValue.environment, ): result => { - let rAnswer = evaluateUsingOptions(~environment=Some(environment), ~externalBindings=Some(externalBindings), code) + let rAnswer = evaluateUsingOptions( + ~environment=Some(environment), + ~externalBindings=Some(externalBindings), + code, + ) switch rAnswer { - | Ok(EvRecord(externalBindings)) => Ok(externalBindings) - | Ok(_) => Error(Reducer_ErrorValue.RESyntaxError(`Partials must end with an assignment or record`)) - | Error(err) => err->Error + | Ok(EvRecord(externalBindings)) => Ok(externalBindings) + | Ok(_) => + Error(Reducer_ErrorValue.RESyntaxError(`Partials must end with an assignment or record`)) + | Error(err) => err->Error } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res index 691a571c..7cd220bc 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res @@ -8,11 +8,10 @@ external castString: unit => string = "%identity" /* As JavaScript returns us any type, we need to type check and cast type propertype before using it */ -let jsToEv = (jsValue): result => +let jsToEv = (jsValue): result => switch Js.typeof(jsValue) { | "boolean" => jsValue->castBool->EvBool->Ok | "number" => jsValue->castNumber->EvNumber->Ok | "string" => jsValue->castString->EvString->Ok | other => RETodo(`Unhandled MathJs literal type: ${Js.String.make(other)}`)->Error } - diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index a5c5b22e..0bfd3cba 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -28,14 +28,13 @@ module Helpers = { let catchAndConvertTwoArgsToDists = (args: array): option<( DistributionTypes.genericDist, DistributionTypes.genericDist, - )> => + )> => switch args { | [EvDistribution(a), EvDistribution(b)] => Some((a, b)) | [EvNumber(a), EvDistribution(b)] => Some((GenericDist.fromFloat(a), b)) | [EvDistribution(a), EvNumber(b)] => Some((a, GenericDist.fromFloat(b))) | _ => None } - let toFloatFn = ( fnCall: DistributionTypes.DistributionOperation.toFloat, @@ -119,7 +118,7 @@ module Helpers = { mixtureWithGivenWeights(distributions, weights) } - let mixture = (args: array): DistributionOperation.outputType => + let mixture = (args: array): DistributionOperation.outputType => switch E.A.last(args) { | Some(EvArray(b)) => { let weights = parseNumberArray(b) @@ -138,7 +137,6 @@ module Helpers = { } | _ => GenDistError(ArgumentError("Last argument of mx must be array or distribution")) } - } module SymbolicConstructors = { From 2c452163b6593d90b8364e9134e5f7090744521f Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Fri, 29 Apr 2022 14:41:30 -0400 Subject: [PATCH 059/146] I believe I have functionality in place for new `run` command, but I could be wrong. Pushing so Sam can review Value: [1e-5 to 9e-3] --- packages/squiggle-lang/src/js/index.ts | 30 ++++++++++++------- .../ReducerInterface_GenericDistribution.res | 8 +++-- .../ReducerInterface_GenericDistribution.resi | 1 + .../src/rescript/TypescriptInterface.res | 12 ++++++++ 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 34318424..98a79b84 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -2,9 +2,11 @@ import * as _ from "lodash"; import { genericDist, samplingParams, + environment, evaluatePartialUsingExternalBindings, externalBindings, expressionValue, + recordEV, errorValue, distributionError, toPointSet, @@ -15,6 +17,8 @@ import { mixedShape, sampleSetDist, symbolicDist, + defaultEnvironment, + defaultSamplingEnv, } from "../rescript/TypescriptInterface.gen"; export { makeSampleSetDist, @@ -50,10 +54,7 @@ import { } from "../rescript/Distributions/DistributionOperation/DistributionOperation.gen"; export type { samplingParams, errorValue, externalBindings as bindings }; -export let defaultSamplingInputs: samplingParams = { - sampleCount: 10000, - xyPointLength: 10000, -}; +export let defaultSamplingInputs: samplingParams = defaultSamplingEnv; export type result = | { @@ -90,8 +91,9 @@ export type squiggleExpression = | tagged<"symbol", string> | tagged<"string", string> | tagged<"call", string> - | tagged<"lambda", [string[], internalCode]> + | tagged<"lambda", [string[], recordEV, internalCode]> | tagged<"array", squiggleExpression[]> + | tagged<"arrayString", string[]> | tagged<"boolean", boolean> | tagged<"distribution", Distribution> | tagged<"number", number> @@ -100,16 +102,16 @@ export type squiggleExpression = export function run( squiggleString: string, bindings?: externalBindings, - samplingInputs?: samplingParams + samplingInputs?: samplingParams, + environ?: environment ): result { let b = bindings ? bindings : {}; let si: samplingParams = samplingInputs ? samplingInputs : defaultSamplingInputs; - - let result: result = - evaluateUsingExternalBindings(squiggleString, b); - return resultMap(result, (x) => createTsExport(x, si)); + let e = environ ? environ : defaultEnvironment; + let res: result = eval(squiggleString); // , b, e); + return resultMap(res, (x) => createTsExport(x, si)); } // Run Partial. A partial is a block of code that doesn't return a value @@ -118,7 +120,11 @@ export function runPartial( bindings: externalBindings, _samplingInputs?: samplingParams ): result { - return evaluatePartialUsingExternalBindings(squiggleString, bindings); + return evaluatePartialUsingExternalBindings( + squiggleString, + bindings, + defaultEnvironment + ); } function createTsExport( @@ -158,6 +164,8 @@ function createTsExport( } }) ); + case "EvArrayString": + return tag("arrayString", x.value); case "EvBool": return tag("boolean", x.value); case "EvCall": diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index a5c5b22e..ceac0800 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -1,11 +1,13 @@ module ExpressionValue = ReducerInterface_ExpressionValue type expressionValue = ReducerInterface_ExpressionValue.expressionValue -let runGenericOperation = DistributionOperation.run( - ~env={ +let defaultEnv: DistributionOperation.env = { sampleCount: MagicNumbers.Environment.defaultSampleCount, xyPointLength: MagicNumbers.Environment.defaultXYPointLength, - }, + } + +let runGenericOperation = DistributionOperation.run( + ~env=defaultEnv, ) module Helpers = { diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi index 7f26a610..038f4479 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi @@ -1,3 +1,4 @@ +let defaultEnv: DistributionOperation.env let dispatch: ( ReducerInterface_ExpressionValue.functionCall, ReducerInterface_ExpressionValue.environment, diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index 70f3a3d1..114dc4e6 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -49,6 +49,9 @@ type externalBindings = Reducer.externalBindings @genType type expressionValue = ReducerInterface_ExpressionValue.expressionValue +@genType +type recordEV = ReducerInterface_ExpressionValue.record + @genType type errorValue = Reducer_ErrorValue.errorValue @@ -72,3 +75,12 @@ let distributionErrorToString = DistributionTypes.Error.toString @genType type internalCode = ReducerInterface_ExpressionValue.internalCode + +@genType +let defaultSamplingEnv = ReducerInterface_GenericDistribution.defaultEnv + +@genType +type environment = ReducerInterface_ExpressionValue.environment + +@genType +let defaultEnvironment = ReducerInterface_ExpressionValue.defaultEnvironment From 0e9996256e02350383ab3e31a41ad8444b567f59 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Fri, 29 Apr 2022 14:42:34 -0400 Subject: [PATCH 060/146] Lint for Umur Value: [1e-8 to 1e-6] --- .../Reducer_Dispatch_BuiltIn.res | 2 +- .../Reducer_Dispatch_BuiltInMacros.res | 7 +++---- .../Reducer_Expression/Reducer_Expression.res | 15 ++++++++++----- .../Reducer/Reducer_Js/Reducer_Js_Gate.res | 3 +-- .../ReducerInterface_GenericDistribution.res | 16 ++++++---------- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 0067441c..25fc05a7 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -21,7 +21,7 @@ let callInternal = (call: functionCall, _environment): result<'b, errorValue> => } let constructRecord = arrayOfPairs => { - Belt.Array.map(arrayOfPairs, pairValue => + Belt.Array.map(arrayOfPairs, pairValue => switch pairValue { | EvArray([EvString(key), valueValue]) => (key, valueValue) | _ => ("wrong key type", pairValue->toStringWithType->EvString) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index b18c927a..f3f6d8c3 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -19,7 +19,7 @@ let dispatchMacroCall = ( environment, reduceExpression: ExpressionT.reducerFn, ): result => { - let doBindStatement = (bindingExpr: expression, statement: expression, environment) => + let doBindStatement = (bindingExpr: expression, statement: expression, environment) => switch statement { | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), symbolExpr, statement}) => { let rExternalBindingsValue = reduceExpression(bindingExpr, bindings, environment) @@ -37,9 +37,8 @@ let dispatchMacroCall = ( } | _ => REAssignmentExpected->Error } - - let doBindExpression = (bindingExpr: expression, statement: expression, environment) => + let doBindExpression = (bindingExpr: expression, statement: expression, environment) => switch statement { | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), symbolExpr, statement}) => { let rExternalBindingsValue = reduceExpression( @@ -74,7 +73,7 @@ let dispatchMacroCall = ( }) } } - + let doBlock = (exprs: list, _bindings: ExpressionT.bindings, _environment): result< expression, errorValue, 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 02043320..5eeb51c7 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 @@ -32,7 +32,7 @@ let parse = (mathJsCode: string): result => let rec reduceExpression = (expression: t, bindings: T.bindings, environment: environment): result< expressionValue, 'e, -> => +> => switch expression { | T.EValue(value) => value->Ok | T.EList(list) => @@ -119,10 +119,15 @@ let evaluatePartialUsingExternalBindings = ( externalBindings: ReducerInterface_ExpressionValue.externalBindings, environment: ReducerInterface_ExpressionValue.environment, ): result => { - let rAnswer = evaluateUsingOptions(~environment=Some(environment), ~externalBindings=Some(externalBindings), code) + let rAnswer = evaluateUsingOptions( + ~environment=Some(environment), + ~externalBindings=Some(externalBindings), + code, + ) switch rAnswer { - | Ok(EvRecord(externalBindings)) => Ok(externalBindings) - | Ok(_) => Error(Reducer_ErrorValue.RESyntaxError(`Partials must end with an assignment or record`)) - | Error(err) => err->Error + | Ok(EvRecord(externalBindings)) => Ok(externalBindings) + | Ok(_) => + Error(Reducer_ErrorValue.RESyntaxError(`Partials must end with an assignment or record`)) + | Error(err) => err->Error } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res index 691a571c..7cd220bc 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res @@ -8,11 +8,10 @@ external castString: unit => string = "%identity" /* As JavaScript returns us any type, we need to type check and cast type propertype before using it */ -let jsToEv = (jsValue): result => +let jsToEv = (jsValue): result => switch Js.typeof(jsValue) { | "boolean" => jsValue->castBool->EvBool->Ok | "number" => jsValue->castNumber->EvNumber->Ok | "string" => jsValue->castString->EvString->Ok | other => RETodo(`Unhandled MathJs literal type: ${Js.String.make(other)}`)->Error } - diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index ceac0800..d5926d0f 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -2,13 +2,11 @@ module ExpressionValue = ReducerInterface_ExpressionValue type expressionValue = ReducerInterface_ExpressionValue.expressionValue let defaultEnv: DistributionOperation.env = { - sampleCount: MagicNumbers.Environment.defaultSampleCount, - xyPointLength: MagicNumbers.Environment.defaultXYPointLength, - } + sampleCount: MagicNumbers.Environment.defaultSampleCount, + xyPointLength: MagicNumbers.Environment.defaultXYPointLength, +} -let runGenericOperation = DistributionOperation.run( - ~env=defaultEnv, -) +let runGenericOperation = DistributionOperation.run(~env=defaultEnv) module Helpers = { let arithmeticMap = r => @@ -30,14 +28,13 @@ module Helpers = { let catchAndConvertTwoArgsToDists = (args: array): option<( DistributionTypes.genericDist, DistributionTypes.genericDist, - )> => + )> => switch args { | [EvDistribution(a), EvDistribution(b)] => Some((a, b)) | [EvNumber(a), EvDistribution(b)] => Some((GenericDist.fromFloat(a), b)) | [EvDistribution(a), EvNumber(b)] => Some((a, GenericDist.fromFloat(b))) | _ => None } - let toFloatFn = ( fnCall: DistributionTypes.DistributionOperation.toFloat, @@ -121,7 +118,7 @@ module Helpers = { mixtureWithGivenWeights(distributions, weights) } - let mixture = (args: array): DistributionOperation.outputType => + let mixture = (args: array): DistributionOperation.outputType => switch E.A.last(args) { | Some(EvArray(b)) => { let weights = parseNumberArray(b) @@ -140,7 +137,6 @@ module Helpers = { } | _ => GenDistError(ArgumentError("Last argument of mx must be array or distribution")) } - } module SymbolicConstructors = { From d4f929367d4a9d098d6694ff6cec63078481e649 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 29 Apr 2022 18:46:44 +0000 Subject: [PATCH 061/146] JS parameters in squiggle lang --- packages/components/package.json | 35 ++++++------ .../squiggle-lang/__tests__/TS/JS_test.ts | 23 ++++++++ .../squiggle-lang/__tests__/TS/TestHelpers.ts | 38 +++++++++---- packages/squiggle-lang/src/js/index.ts | 56 +++++++++++++++++-- .../Reducer_MathJs/Reducer_MathJs_Eval.res | 1 + 5 files changed, 120 insertions(+), 33 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index de8efb96..3b50afbf 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,19 +1,19 @@ { "name": "@quri/squiggle-components", - "version": "0.2.14", + "version": "0.2.15", "license": "MIT", "dependencies": { - "react-ace": "10.1.0", "@quri/squiggle-lang": "^0.2.7", - "react-dom": "^18.1.0", - "vega": "^5.22.1", - "vega-embed": "^6.20.6", - "vega-lite": "^5.2.0", - "react-vega": "^7.5.0", - "react": "^18.1.0", "@react-hook/size": "^2.1.2", "lodash": "^4.17.21", - "styled-components": "^5.3.5" + "react": "^18.1.0", + "react-ace": "10.1.0", + "react-dom": "^18.1.0", + "react-vega": "^7.5.0", + "styled-components": "^5.3.5", + "vega": "^5.22.1", + "vega-embed": "^6.20.6", + "vega-lite": "^5.2.0" }, "devDependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.16.7", @@ -25,27 +25,26 @@ "@storybook/node-logger": "^6.4.22", "@storybook/preset-create-react-app": "^4.1.0", "@storybook/react": "^6.4.22", - "@types/styled-components": "^5.1.24", - "@types/webpack": "^5.28.0", - "style-loader": "^3.3.1", - "ts-loader": "^9.2.9", - "webpack": "^5.72.0", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.8.1", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.1.1", "@testing-library/user-event": "^14.1.1", "@types/jest": "^27.4.0", - "web-vitals": "^2.1.4", "@types/lodash": "^4.14.182", "@types/node": "^17.0.29", "@types/react": "^18.0.3", "@types/react-dom": "^18.0.2", + "@types/styled-components": "^5.1.24", + "@types/webpack": "^5.28.0", "cross-env": "^7.0.3", "react-scripts": "5.0.1", + "style-loader": "^3.3.1", + "ts-loader": "^9.2.9", "tsconfig-paths-webpack-plugin": "^3.5.2", "typescript": "^4.6.3", - "webpack-cli": "^4.9.2" + "web-vitals": "^2.1.4", + "webpack": "^5.72.0", + "webpack-cli": "^4.9.2", + "webpack-dev-server": "^4.8.1" }, "scripts": { "start": "cross-env REACT_APP_FAST_REFRESH=false && start-storybook -p 6006 -s public", diff --git a/packages/squiggle-lang/__tests__/TS/JS_test.ts b/packages/squiggle-lang/__tests__/TS/JS_test.ts index e522eb95..62051261 100644 --- a/packages/squiggle-lang/__tests__/TS/JS_test.ts +++ b/packages/squiggle-lang/__tests__/TS/JS_test.ts @@ -68,6 +68,29 @@ describe("Partials", () => { }); }); +describe("Parameters", () => { + test("Can pass parameters into partials and cells", () => { + let bindings = testRunPartial(`y = $x + 2`, {}, { x: 1 }); // y = 3 + let bindings2 = testRunPartial(`z = $x + y * $a`, bindings, { a: 3 }); // z = 1 + 3 * 3 = 10 + expect(testRun(`z + $x + $a + y`, bindings2)).toEqual({ + tag: "number", + value: 17, + }); + }); + test("Complicated deep parameters", () => { + expect( + testRun( + `$x.y[0][0].w + $x.z + $u.v`, + {}, + { x: { y: [[{ w: 1 }]], z: 2 }, u: { v: 3 } } + ) + ).toEqual({ + tag: "number", + value: 6, + }); + }); +}); + describe("Distribution", () => { //It's important that sampleCount is less than 9. If it's more, than that will create randomness //Also, note, the value should be created using makeSampleSetDist() later on. diff --git a/packages/squiggle-lang/__tests__/TS/TestHelpers.ts b/packages/squiggle-lang/__tests__/TS/TestHelpers.ts index 7d51c98e..3bbf42d8 100644 --- a/packages/squiggle-lang/__tests__/TS/TestHelpers.ts +++ b/packages/squiggle-lang/__tests__/TS/TestHelpers.ts @@ -6,11 +6,20 @@ import { errorValueToString, } from "../../src/js/index"; -export function testRun(x: string, bindings = {}): squiggleExpression { - let squiggleResult = run(x, bindings, { - sampleCount: 1000, - xyPointLength: 100, - }); +export function testRun( + x: string, + bindings = {}, + parameters = {} +): squiggleExpression { + let squiggleResult = run( + x, + bindings, + { + sampleCount: 1000, + xyPointLength: 100, + }, + parameters + ); // return squiggleResult.value if (squiggleResult.tag === "Ok") { return squiggleResult.value; @@ -23,11 +32,20 @@ export function testRun(x: string, bindings = {}): squiggleExpression { } } -export function testRunPartial(x: string, bindings: bindings = {}): bindings { - let squiggleResult = runPartial(x, bindings, { - sampleCount: 1000, - xyPointLength: 100, - }); +export function testRunPartial( + x: string, + bindings: bindings = {}, + parameters = {} +): bindings { + let squiggleResult = runPartial( + x, + bindings, + { + sampleCount: 1000, + xyPointLength: 100, + }, + parameters + ); if (squiggleResult.tag === "Ok") { return squiggleResult.value; } else { diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index fb67e47a..cd63c922 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -99,25 +99,71 @@ export type squiggleExpression = export function run( squiggleString: string, bindings?: externalBindings, - samplingInputs?: samplingParams + samplingInputs?: samplingParams, + parameters?: parameters ): result { let b = bindings ? bindings : {}; + let p = parameters ? parameters : {}; let si: samplingParams = samplingInputs ? samplingInputs : defaultSamplingInputs; let result: result = - evaluateUsingExternalBindings(squiggleString, b); + evaluateUsingExternalBindings(squiggleString, mergeParameters(b, p)); return resultMap(result, (x) => createTsExport(x, si)); } // Run Partial. A partial is a block of code that doesn't return a value export function runPartial( squiggleString: string, - bindings: externalBindings, - _samplingInputs?: samplingParams + bindings?: externalBindings, + _samplingInputs?: samplingParams, + parameters?: parameters ): result { - return evaluatePartialUsingExternalBindings(squiggleString, bindings); + let b = bindings ? bindings : {}; + let p = parameters ? parameters : {}; + + return evaluatePartialUsingExternalBindings( + squiggleString, + mergeParameters(b, p) + ); +} + +function mergeParameters( + bindings: externalBindings, + parameters: parameters +): externalBindings { + let transformedParemeters = Object.fromEntries( + Object.entries(parameters).map(([key, value]) => [ + "$" + key, + jsValueToBinding(value), + ]) + ); + return _.merge(bindings, transformedParemeters); +} + +type parameters = { [key: string]: jsValue }; + +type jsValue = + | string + | number + | jsValue[] + | { [key: string]: jsValue } + | boolean; + +function jsValueToBinding(value: jsValue): rescriptExport { + if (typeof value === "boolean") { + return { TAG: 1, _0: value as boolean }; + } else if (typeof value === "string") { + return { TAG: 6, _0: value as string }; + } else if (typeof value === "number") { + return { TAG: 4, _0: value as number }; + } else if (Array.isArray(value)) { + return { TAG: 0, _0: value.map(jsValueToBinding) }; + } else { + // Record + return { TAG: 5, _0: _.mapValues(value, jsValueToBinding) }; + } } function createTsExport( diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Eval.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Eval.res index ab9fb711..86a7a593 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Eval.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Eval.res @@ -19,6 +19,7 @@ let eval__: string => 'a = %raw(`function (expr) { return {value: Mathjs.evaluat */ let eval = (expr: string): result => { try { + Js.log(expr) let answer = eval__(expr) answer["value"]->JavaScript.Gate.jsToEv } catch { From f05d08952439d0d98da99d7d02f24152b78fadb0 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Fri, 29 Apr 2022 15:02:24 -0400 Subject: [PATCH 062/146] Fixed most tests Value: [1e-5 to 1e-3] --- packages/squiggle-lang/src/js/index.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 98a79b84..5bd02f67 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -4,6 +4,7 @@ import { samplingParams, environment, evaluatePartialUsingExternalBindings, + evaluateUsingOptions, externalBindings, expressionValue, recordEV, @@ -110,7 +111,10 @@ export function run( ? samplingInputs : defaultSamplingInputs; let e = environ ? environ : defaultEnvironment; - let res: result = eval(squiggleString); // , b, e); + let res: result = evaluateUsingOptions( + { externalBindings: b, environment: e }, + squiggleString + ); // , b, e); return resultMap(res, (x) => createTsExport(x, si)); } From 39be07cac0d7136d74078beba0097da79da74665 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 29 Apr 2022 19:02:43 +0000 Subject: [PATCH 063/146] Add parameters to components interface --- .../src/components/SquiggleChart.tsx | 17 +++++++++--- .../src/components/SquiggleEditor.tsx | 26 +++++++++++++++---- packages/squiggle-lang/src/js/index.ts | 18 +++++++++---- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 8730beaa..235a4cee 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -3,16 +3,17 @@ import _ from "lodash"; import styled from "styled-components"; import { run, - runPartial, errorValueToString, squiggleExpression, bindings, samplingParams, + parameters, + defaultParameters, + defaultBindings, } from "@quri/squiggle-lang"; import { NumberShower } from "./NumberShower"; import { DistributionChart } from "./DistributionChart"; import { ErrorBox } from "./ErrorBox"; -import useSize from "@react-hook/size"; const variableBox = { Component: styled.div` @@ -152,6 +153,8 @@ export interface SquiggleChartProps { height?: number; /** Bindings of previous variables declared */ bindings?: bindings; + /** JS imported parameters */ + parameters?: parameters; } const ChartWrapper = styled.div` @@ -166,14 +169,20 @@ export const SquiggleChart: React.FC = ({ outputXYPoints = 1000, onChange = () => {}, height = 60, - bindings = {}, + bindings = defaultBindings, + parameters = defaultParameters, width = NaN, }: SquiggleChartProps) => { let samplingInputs: samplingParams = { sampleCount: sampleCount, xyPointLength: outputXYPoints, }; - let expressionResult = run(squiggleString, bindings, samplingInputs); + let expressionResult = run( + squiggleString, + bindings, + samplingInputs, + parameters + ); let internal: JSX.Element; if (expressionResult.tag === "Ok") { let expression = expressionResult.value; diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index f85cf1e8..67f2e73b 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -3,8 +3,17 @@ import * as ReactDOM from "react-dom"; import { SquiggleChart } from "./SquiggleChart"; import { CodeEditor } from "./CodeEditor"; import styled from "styled-components"; -import type { squiggleExpression, bindings } from "@quri/squiggle-lang"; -import { runPartial, errorValueToString } from "@quri/squiggle-lang"; +import type { + squiggleExpression, + bindings, + parameters, +} from "@quri/squiggle-lang"; +import { + runPartial, + errorValueToString, + defaultParameters, + defaultBindings, +} from "@quri/squiggle-lang"; import { ErrorBox } from "./ErrorBox"; export interface SquiggleEditorProps { @@ -30,6 +39,8 @@ export interface SquiggleEditorProps { width: number; /** Previous variable declarations */ bindings: bindings; + /** JS Imported parameters */ + parameters: parameters; } const Input = styled.div` @@ -50,7 +61,8 @@ export let SquiggleEditor: React.FC = ({ diagramCount, onChange, environment, - bindings = {}, + bindings = defaultBindings, + parameters = defaultParameters, }: SquiggleEditorProps) => { let [expression, setExpression] = React.useState(initialSquiggleString); return ( @@ -77,6 +89,7 @@ export let SquiggleEditor: React.FC = ({ environment={environment} onChange={onChange} bindings={bindings} + parameters={parameters} /> ); @@ -134,13 +147,16 @@ export interface SquigglePartialProps { /** The width of the element */ width: number; /** Previously declared variables */ - bindings: bindings; + bindings?: bindings; + /** Parameters imported from js */ + parameters?: parameters; } export let SquigglePartial: React.FC = ({ initialSquiggleString = "", onChange, - bindings, + bindings = defaultBindings, + parameters = defaultParameters, }: SquigglePartialProps) => { let [expression, setExpression] = React.useState(initialSquiggleString); let squiggleResult = runPartial(expression, bindings); diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index cd63c922..1c0fb4e3 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -48,7 +48,12 @@ import { Constructors_pointwiseLogarithm, Constructors_pointwisePower, } from "../rescript/Distributions/DistributionOperation/DistributionOperation.gen"; -export type { samplingParams, errorValue, externalBindings as bindings }; +export type { + samplingParams, + errorValue, + externalBindings as bindings, + parameters, +}; export let defaultSamplingInputs: samplingParams = { sampleCount: 10000, @@ -102,8 +107,8 @@ export function run( samplingInputs?: samplingParams, parameters?: parameters ): result { - let b = bindings ? bindings : {}; - let p = parameters ? parameters : {}; + let b = bindings ? bindings : defaultBindings; + let p = parameters ? parameters : defaultParameters; let si: samplingParams = samplingInputs ? samplingInputs : defaultSamplingInputs; @@ -120,8 +125,8 @@ export function runPartial( _samplingInputs?: samplingParams, parameters?: parameters ): result { - let b = bindings ? bindings : {}; - let p = parameters ? parameters : {}; + let b = bindings ? bindings : defaultBindings; + let p = parameters ? parameters : defaultParameters; return evaluatePartialUsingExternalBindings( squiggleString, @@ -144,6 +149,9 @@ function mergeParameters( type parameters = { [key: string]: jsValue }; +export let defaultParameters: parameters = {}; +export let defaultBindings: externalBindings = {}; + type jsValue = | string | number From 237cdf12f9f925324af99a3f215dc46e03990895 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 29 Apr 2022 19:13:30 +0000 Subject: [PATCH 064/146] Remove accidental log --- .../src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Eval.res | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Eval.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Eval.res index 86a7a593..ab9fb711 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Eval.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Eval.res @@ -19,7 +19,6 @@ let eval__: string => 'a = %raw(`function (expr) { return {value: Mathjs.evaluat */ let eval = (expr: string): result => { try { - Js.log(expr) let answer = eval__(expr) answer["value"]->JavaScript.Gate.jsToEv } catch { From 8b30eb9f054f1ab01945c74fd1a592837cf26d16 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Fri, 29 Apr 2022 15:25:29 -0400 Subject: [PATCH 065/146] Added to convertRaw* stuff Value: [1e-4 to 1e-3] --- packages/squiggle-lang/src/js/index.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 5bd02f67..b944bc80 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -231,6 +231,8 @@ function convertRawToTypescript( return tag("string", result._0); case 7: // EvSymbol return tag("symbol", result._0); + case 8: // EvArrayString + return tag("arrayString", result._0); } } @@ -287,6 +289,10 @@ type rescriptExport = | { TAG: 7; // EvSymbol _0: string; + } + | { + TAG: 8; // EvArrayString + _0: string[]; }; type rescriptDist = From 74df093a42539f3255577a9cce54ccd8b7371860 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 29 Apr 2022 20:10:39 +0000 Subject: [PATCH 066/146] Cleanup TS code (and fix rescript build warning) --- .../squiggle-lang/__tests__/TS/JS_test.ts | 17 +- packages/squiggle-lang/src/js/distribution.ts | 247 ++++++++++ packages/squiggle-lang/src/js/index.ts | 439 +----------------- .../squiggle-lang/src/js/rescript_interop.ts | 155 +++++++ packages/squiggle-lang/src/js/types.ts | 30 ++ .../squiggle-lang/src/rescript/Utility/E.res | 2 +- 6 files changed, 454 insertions(+), 436 deletions(-) create mode 100644 packages/squiggle-lang/src/js/distribution.ts create mode 100644 packages/squiggle-lang/src/js/rescript_interop.ts create mode 100644 packages/squiggle-lang/src/js/types.ts diff --git a/packages/squiggle-lang/__tests__/TS/JS_test.ts b/packages/squiggle-lang/__tests__/TS/JS_test.ts index 62051261..004d715e 100644 --- a/packages/squiggle-lang/__tests__/TS/JS_test.ts +++ b/packages/squiggle-lang/__tests__/TS/JS_test.ts @@ -1,4 +1,4 @@ -import { Distribution, resultMap } from "../../src/js/index"; +import { Distribution, resultMap, defaultBindings } from "../../src/js/index"; import { testRun, testRunPartial } from "./TestHelpers"; function Ok(x: b) { @@ -70,20 +70,19 @@ describe("Partials", () => { describe("Parameters", () => { test("Can pass parameters into partials and cells", () => { - let bindings = testRunPartial(`y = $x + 2`, {}, { x: 1 }); // y = 3 - let bindings2 = testRunPartial(`z = $x + y * $a`, bindings, { a: 3 }); // z = 1 + 3 * 3 = 10 - expect(testRun(`z + $x + $a + y`, bindings2)).toEqual({ + let bindings = testRunPartial(`y = $x + 2`, defaultBindings, { x: 1 }); + let bindings2 = testRunPartial(`z = y + $a`, bindings, { a: 3 }); + expect(testRun(`z`, bindings2)).toEqual({ tag: "number", value: 17, }); }); test("Complicated deep parameters", () => { expect( - testRun( - `$x.y[0][0].w + $x.z + $u.v`, - {}, - { x: { y: [[{ w: 1 }]], z: 2 }, u: { v: 3 } } - ) + testRun(`$x.y[0][0].w + $x.z + $u.v`, defaultBindings, { + x: { y: [[{ w: 1 }]], z: 2 }, + u: { v: 3 }, + }) ).toEqual({ tag: "number", value: 6, diff --git a/packages/squiggle-lang/src/js/distribution.ts b/packages/squiggle-lang/src/js/distribution.ts new file mode 100644 index 00000000..603dfaa9 --- /dev/null +++ b/packages/squiggle-lang/src/js/distribution.ts @@ -0,0 +1,247 @@ +import * as _ from "lodash"; +import { + genericDist, + continuousShape, + discreteShape, + samplingParams, + distributionError, + toPointSet, + distributionErrorToString, +} from "../rescript/TypescriptInterface.gen"; +import { result, resultMap, Ok } from "./types"; +import { + Constructors_mean, + Constructors_sample, + Constructors_pdf, + Constructors_cdf, + Constructors_inv, + Constructors_normalize, + Constructors_isNormalized, + Constructors_toPointSet, + Constructors_toSampleSet, + Constructors_truncate, + Constructors_inspect, + Constructors_toString, + Constructors_toSparkline, + Constructors_algebraicAdd, + Constructors_algebraicMultiply, + Constructors_algebraicDivide, + Constructors_algebraicSubtract, + Constructors_algebraicLogarithm, + Constructors_algebraicPower, + Constructors_pointwiseAdd, + Constructors_pointwiseMultiply, + Constructors_pointwiseDivide, + Constructors_pointwiseSubtract, + Constructors_pointwiseLogarithm, + Constructors_pointwisePower, +} from "../rescript/Distributions/DistributionOperation/DistributionOperation.gen"; + +export type point = { x: number; y: number }; + +function shapePoints(x: continuousShape | discreteShape): point[] { + let xs = x.xyShape.xs; + let ys = x.xyShape.ys; + return _.zipWith(xs, ys, (x, y) => ({ x, y })); +} +export type shape = { + continuous: point[]; + discrete: point[]; +}; + +export class Distribution { + t: genericDist; + env: samplingParams; + + constructor(t: genericDist, env: samplingParams) { + this.t = t; + this.env = env; + return this; + } + + mapResultDist( + r: result + ): result { + return resultMap(r, (v: genericDist) => new Distribution(v, this.env)); + } + + mean(): result { + return Constructors_mean({ env: this.env }, this.t); + } + + sample(): result { + return Constructors_sample({ env: this.env }, this.t); + } + + pdf(n: number): result { + return Constructors_pdf({ env: this.env }, this.t, n); + } + + cdf(n: number): result { + return Constructors_cdf({ env: this.env }, this.t, n); + } + + inv(n: number): result { + return Constructors_inv({ env: this.env }, this.t, n); + } + + isNormalized(): result { + return Constructors_isNormalized({ env: this.env }, this.t); + } + + normalize(): result { + return this.mapResultDist( + Constructors_normalize({ env: this.env }, this.t) + ); + } + + type() { + return this.t.tag; + } + + pointSet(): result { + let pointSet = toPointSet( + this.t, + { + xyPointLength: this.env.xyPointLength, + sampleCount: this.env.sampleCount, + }, + undefined + ); + if (pointSet.tag === "Ok") { + let distribution = pointSet.value; + if (distribution.tag === "Continuous") { + return Ok({ + continuous: shapePoints(distribution.value), + discrete: [], + }); + } else if (distribution.tag === "Discrete") { + return Ok({ + discrete: shapePoints(distribution.value), + continuous: [], + }); + } else { + return Ok({ + discrete: shapePoints(distribution.value.discrete), + continuous: shapePoints(distribution.value.continuous), + }); + } + } else { + return pointSet; + } + } + + toPointSet(): result { + return this.mapResultDist( + Constructors_toPointSet({ env: this.env }, this.t) + ); + } + + toSampleSet(n: number): result { + return this.mapResultDist( + Constructors_toSampleSet({ env: this.env }, this.t, n) + ); + } + + truncate( + left: number, + right: number + ): result { + return this.mapResultDist( + Constructors_truncate({ env: this.env }, this.t, left, right) + ); + } + + inspect(): result { + return this.mapResultDist(Constructors_inspect({ env: this.env }, this.t)); + } + + toString(): string { + let result = Constructors_toString({ env: this.env }, this.t); + if (result.tag === "Ok") { + return result.value; + } else { + return distributionErrorToString(result.value); + } + } + + toSparkline(n: number): result { + return Constructors_toSparkline({ env: this.env }, this.t, n); + } + + algebraicAdd(d2: Distribution): result { + return this.mapResultDist( + Constructors_algebraicAdd({ env: this.env }, this.t, d2.t) + ); + } + + algebraicMultiply(d2: Distribution): result { + return this.mapResultDist( + Constructors_algebraicMultiply({ env: this.env }, this.t, d2.t) + ); + } + + algebraicDivide(d2: Distribution): result { + return this.mapResultDist( + Constructors_algebraicDivide({ env: this.env }, this.t, d2.t) + ); + } + + algebraicSubtract(d2: Distribution): result { + return this.mapResultDist( + Constructors_algebraicSubtract({ env: this.env }, this.t, d2.t) + ); + } + + algebraicLogarithm( + d2: Distribution + ): result { + return this.mapResultDist( + Constructors_algebraicLogarithm({ env: this.env }, this.t, d2.t) + ); + } + + algebraicPower(d2: Distribution): result { + return this.mapResultDist( + Constructors_algebraicPower({ env: this.env }, this.t, d2.t) + ); + } + + pointwiseAdd(d2: Distribution): result { + return this.mapResultDist( + Constructors_pointwiseAdd({ env: this.env }, this.t, d2.t) + ); + } + + pointwiseMultiply(d2: Distribution): result { + return this.mapResultDist( + Constructors_pointwiseMultiply({ env: this.env }, this.t, d2.t) + ); + } + + pointwiseDivide(d2: Distribution): result { + return this.mapResultDist( + Constructors_pointwiseDivide({ env: this.env }, this.t, d2.t) + ); + } + + pointwiseSubtract(d2: Distribution): result { + return this.mapResultDist( + Constructors_pointwiseSubtract({ env: this.env }, this.t, d2.t) + ); + } + + pointwiseLogarithm( + d2: Distribution + ): result { + return this.mapResultDist( + Constructors_pointwiseLogarithm({ env: this.env }, this.t, d2.t) + ); + } + + pointwisePower(d2: Distribution): result { + return this.mapResultDist( + Constructors_pointwisePower({ env: this.env }, this.t, d2.t) + ); + } +} diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 1c0fb4e3..04d6050a 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -1,106 +1,40 @@ import * as _ from "lodash"; import { - genericDist, samplingParams, evaluateUsingExternalBindings, evaluatePartialUsingExternalBindings, externalBindings, expressionValue, errorValue, - distributionError, - toPointSet, - continuousShape, - discreteShape, - distributionErrorToString, - mixedShape, - sampleSetDist, - symbolicDist, } from "../rescript/TypescriptInterface.gen"; export { makeSampleSetDist, errorValueToString, distributionErrorToString, } from "../rescript/TypescriptInterface.gen"; -import { - Constructors_mean, - Constructors_sample, - Constructors_pdf, - Constructors_cdf, - Constructors_inv, - Constructors_normalize, - Constructors_isNormalized, - Constructors_toPointSet, - Constructors_toSampleSet, - Constructors_truncate, - Constructors_inspect, - Constructors_toString, - Constructors_toSparkline, - Constructors_algebraicAdd, - Constructors_algebraicMultiply, - Constructors_algebraicDivide, - Constructors_algebraicSubtract, - Constructors_algebraicLogarithm, - Constructors_algebraicPower, - Constructors_pointwiseAdd, - Constructors_pointwiseMultiply, - Constructors_pointwiseDivide, - Constructors_pointwiseSubtract, - Constructors_pointwiseLogarithm, - Constructors_pointwisePower, -} from "../rescript/Distributions/DistributionOperation/DistributionOperation.gen"; export type { samplingParams, errorValue, externalBindings as bindings, parameters, }; +import { + jsValueToBinding, + jsValue, + rescriptExport, + squiggleExpression, + convertRawToTypescript, +} from "./rescript_interop"; +import { result, resultMap, tag, tagged } from "./types"; +import { Distribution } from "./distribution"; + +export { Distribution, squiggleExpression, result }; export let defaultSamplingInputs: samplingParams = { sampleCount: 10000, xyPointLength: 10000, }; -export type result = - | { - tag: "Ok"; - value: a; - } - | { - tag: "Error"; - value: b; - }; - -export function resultMap( - r: result, - mapFn: (x: a) => b -): result { - if (r.tag === "Ok") { - return { tag: "Ok", value: mapFn(r.value) }; - } else { - return r; - } -} - -function Ok(x: a): result { - return { tag: "Ok", value: x }; -} - -type tagged = { tag: a; value: b }; - -function tag(x: a, y: b): tagged { - return { tag: x, value: y }; -} - -export type squiggleExpression = - | tagged<"symbol", string> - | tagged<"string", string> - | tagged<"call", string> - | tagged<"array", squiggleExpression[]> - | tagged<"boolean", boolean> - | tagged<"distribution", Distribution> - | tagged<"number", number> - | tagged<"record", { [key: string]: squiggleExpression }>; - export function run( squiggleString: string, bindings?: externalBindings, @@ -138,13 +72,13 @@ function mergeParameters( bindings: externalBindings, parameters: parameters ): externalBindings { - let transformedParemeters = Object.fromEntries( + let transformedParameters = Object.fromEntries( Object.entries(parameters).map(([key, value]) => [ "$" + key, jsValueToBinding(value), ]) ); - return _.merge(bindings, transformedParemeters); + return _.merge(bindings, transformedParameters); } type parameters = { [key: string]: jsValue }; @@ -152,28 +86,6 @@ type parameters = { [key: string]: jsValue }; export let defaultParameters: parameters = {}; export let defaultBindings: externalBindings = {}; -type jsValue = - | string - | number - | jsValue[] - | { [key: string]: jsValue } - | boolean; - -function jsValueToBinding(value: jsValue): rescriptExport { - if (typeof value === "boolean") { - return { TAG: 1, _0: value as boolean }; - } else if (typeof value === "string") { - return { TAG: 6, _0: value as string }; - } else if (typeof value === "number") { - return { TAG: 4, _0: value as number }; - } else if (Array.isArray(value)) { - return { TAG: 0, _0: value.map(jsValueToBinding) }; - } else { - // Record - return { TAG: 5, _0: _.mapValues(value, jsValueToBinding) }; - } -} - function createTsExport( x: expressionValue, sampEnv: samplingParams @@ -235,328 +147,3 @@ function createTsExport( } } -// Helper functions to convert the rescript representations that genType doesn't -// cover -function convertRawToTypescript( - result: rescriptExport, - sampEnv: samplingParams -): squiggleExpression { - switch (result.TAG) { - case 0: // EvArray - return tag( - "array", - result._0.map((x) => convertRawToTypescript(x, sampEnv)) - ); - case 1: // EvBool - return tag("boolean", result._0); - case 2: // EvCall - return tag("call", result._0); - case 3: // EvDistribution - return tag( - "distribution", - new Distribution( - convertRawDistributionToGenericDist(result._0), - sampEnv - ) - ); - case 4: // EvNumber - return tag("number", result._0); - case 5: // EvRecord - return tag( - "record", - _.mapValues(result._0, (x) => convertRawToTypescript(x, sampEnv)) - ); - case 6: // EvString - return tag("string", result._0); - case 7: // EvSymbol - return tag("symbol", result._0); - } -} - -function convertRawDistributionToGenericDist( - result: rescriptDist -): genericDist { - switch (result.TAG) { - case 0: // Point Set Dist - switch (result._0.TAG) { - case 0: // Mixed - return tag("PointSet", tag("Mixed", result._0._0)); - case 1: // Discrete - return tag("PointSet", tag("Discrete", result._0._0)); - case 2: // Continuous - return tag("PointSet", tag("Continuous", result._0._0)); - } - case 1: // Sample Set Dist - return tag("SampleSet", result._0); - case 2: // Symbolic Dist - return tag("Symbolic", result._0); - } -} - -// Raw rescript types. -type rescriptExport = - | { - TAG: 0; // EvArray - _0: rescriptExport[]; - } - | { - TAG: 1; // EvBool - _0: boolean; - } - | { - TAG: 2; // EvCall - _0: string; - } - | { - TAG: 3; // EvDistribution - _0: rescriptDist; - } - | { - TAG: 4; // EvNumber - _0: number; - } - | { - TAG: 5; // EvRecord - _0: { [key: string]: rescriptExport }; - } - | { - TAG: 6; // EvString - _0: string; - } - | { - TAG: 7; // EvSymbol - _0: string; - }; - -type rescriptDist = - | { TAG: 0; _0: rescriptPointSetDist } - | { TAG: 1; _0: sampleSetDist } - | { TAG: 2; _0: symbolicDist }; - -type rescriptPointSetDist = - | { - TAG: 0; // Mixed - _0: mixedShape; - } - | { - TAG: 1; // Discrete - _0: discreteShape; - } - | { - TAG: 2; // ContinuousShape - _0: continuousShape; - }; - -export function resultExn(r: result): a | c { - return r.value; -} - -export type point = { x: number; y: number }; - -export type shape = { - continuous: point[]; - discrete: point[]; -}; - -function shapePoints(x: continuousShape | discreteShape): point[] { - let xs = x.xyShape.xs; - let ys = x.xyShape.ys; - return _.zipWith(xs, ys, (x, y) => ({ x, y })); -} - -export class Distribution { - t: genericDist; - env: samplingParams; - - constructor(t: genericDist, env: samplingParams) { - this.t = t; - this.env = env; - return this; - } - - mapResultDist( - r: result - ): result { - return resultMap(r, (v: genericDist) => new Distribution(v, this.env)); - } - - mean(): result { - return Constructors_mean({ env: this.env }, this.t); - } - - sample(): result { - return Constructors_sample({ env: this.env }, this.t); - } - - pdf(n: number): result { - return Constructors_pdf({ env: this.env }, this.t, n); - } - - cdf(n: number): result { - return Constructors_cdf({ env: this.env }, this.t, n); - } - - inv(n: number): result { - return Constructors_inv({ env: this.env }, this.t, n); - } - - isNormalized(): result { - return Constructors_isNormalized({ env: this.env }, this.t); - } - - normalize(): result { - return this.mapResultDist( - Constructors_normalize({ env: this.env }, this.t) - ); - } - - type() { - return this.t.tag; - } - - pointSet(): result { - let pointSet = toPointSet( - this.t, - { - xyPointLength: this.env.xyPointLength, - sampleCount: this.env.sampleCount, - }, - undefined - ); - if (pointSet.tag === "Ok") { - let distribution = pointSet.value; - if (distribution.tag === "Continuous") { - return Ok({ - continuous: shapePoints(distribution.value), - discrete: [], - }); - } else if (distribution.tag === "Discrete") { - return Ok({ - discrete: shapePoints(distribution.value), - continuous: [], - }); - } else { - return Ok({ - discrete: shapePoints(distribution.value.discrete), - continuous: shapePoints(distribution.value.continuous), - }); - } - } else { - return pointSet; - } - } - - toPointSet(): result { - return this.mapResultDist( - Constructors_toPointSet({ env: this.env }, this.t) - ); - } - - toSampleSet(n: number): result { - return this.mapResultDist( - Constructors_toSampleSet({ env: this.env }, this.t, n) - ); - } - - truncate( - left: number, - right: number - ): result { - return this.mapResultDist( - Constructors_truncate({ env: this.env }, this.t, left, right) - ); - } - - inspect(): result { - return this.mapResultDist(Constructors_inspect({ env: this.env }, this.t)); - } - - toString(): string { - let result = Constructors_toString({ env: this.env }, this.t); - if (result.tag === "Ok") { - return result.value; - } else { - return distributionErrorToString(result.value); - } - } - - toSparkline(n: number): result { - return Constructors_toSparkline({ env: this.env }, this.t, n); - } - - algebraicAdd(d2: Distribution): result { - return this.mapResultDist( - Constructors_algebraicAdd({ env: this.env }, this.t, d2.t) - ); - } - - algebraicMultiply(d2: Distribution): result { - return this.mapResultDist( - Constructors_algebraicMultiply({ env: this.env }, this.t, d2.t) - ); - } - - algebraicDivide(d2: Distribution): result { - return this.mapResultDist( - Constructors_algebraicDivide({ env: this.env }, this.t, d2.t) - ); - } - - algebraicSubtract(d2: Distribution): result { - return this.mapResultDist( - Constructors_algebraicSubtract({ env: this.env }, this.t, d2.t) - ); - } - - algebraicLogarithm( - d2: Distribution - ): result { - return this.mapResultDist( - Constructors_algebraicLogarithm({ env: this.env }, this.t, d2.t) - ); - } - - algebraicPower(d2: Distribution): result { - return this.mapResultDist( - Constructors_algebraicPower({ env: this.env }, this.t, d2.t) - ); - } - - pointwiseAdd(d2: Distribution): result { - return this.mapResultDist( - Constructors_pointwiseAdd({ env: this.env }, this.t, d2.t) - ); - } - - pointwiseMultiply(d2: Distribution): result { - return this.mapResultDist( - Constructors_pointwiseMultiply({ env: this.env }, this.t, d2.t) - ); - } - - pointwiseDivide(d2: Distribution): result { - return this.mapResultDist( - Constructors_pointwiseDivide({ env: this.env }, this.t, d2.t) - ); - } - - pointwiseSubtract(d2: Distribution): result { - return this.mapResultDist( - Constructors_pointwiseSubtract({ env: this.env }, this.t, d2.t) - ); - } - - pointwiseLogarithm( - d2: Distribution - ): result { - return this.mapResultDist( - Constructors_pointwiseLogarithm({ env: this.env }, this.t, d2.t) - ); - } - - pointwisePower(d2: Distribution): result { - return this.mapResultDist( - Constructors_pointwisePower({ env: this.env }, this.t, d2.t) - ); - } -} diff --git a/packages/squiggle-lang/src/js/rescript_interop.ts b/packages/squiggle-lang/src/js/rescript_interop.ts new file mode 100644 index 00000000..b017699f --- /dev/null +++ b/packages/squiggle-lang/src/js/rescript_interop.ts @@ -0,0 +1,155 @@ +import * as _ from "lodash"; +import { + mixedShape, + sampleSetDist, + genericDist, + samplingParams, + symbolicDist, + discreteShape, + continuousShape, +} from "../rescript/TypescriptInterface.gen"; +import { Distribution } from "./distribution"; +import { tagged, tag } from "./types"; +// This file is here to compensate for genType not fully recursively converting types + +// Raw rescript types. +export type rescriptExport = + | { + TAG: 0; // EvArray + _0: rescriptExport[]; + } + | { + TAG: 1; // EvBool + _0: boolean; + } + | { + TAG: 2; // EvCall + _0: string; + } + | { + TAG: 3; // EvDistribution + _0: rescriptDist; + } + | { + TAG: 4; // EvNumber + _0: number; + } + | { + TAG: 5; // EvRecord + _0: { [key: string]: rescriptExport }; + } + | { + TAG: 6; // EvString + _0: string; + } + | { + TAG: 7; // EvSymbol + _0: string; + }; + +type rescriptDist = + | { TAG: 0; _0: rescriptPointSetDist } + | { TAG: 1; _0: sampleSetDist } + | { TAG: 2; _0: symbolicDist }; + +type rescriptPointSetDist = + | { + TAG: 0; // Mixed + _0: mixedShape; + } + | { + TAG: 1; // Discrete + _0: discreteShape; + } + | { + TAG: 2; // ContinuousShape + _0: continuousShape; + }; + +export type squiggleExpression = + | tagged<"symbol", string> + | tagged<"string", string> + | tagged<"call", string> + | tagged<"array", squiggleExpression[]> + | tagged<"boolean", boolean> + | tagged<"distribution", Distribution> + | tagged<"number", number> + | tagged<"record", { [key: string]: squiggleExpression }>; + +export function convertRawToTypescript( + result: rescriptExport, + sampEnv: samplingParams +): squiggleExpression { + switch (result.TAG) { + case 0: // EvArray + return tag( + "array", + result._0.map((x) => convertRawToTypescript(x, sampEnv)) + ); + case 1: // EvBool + return tag("boolean", result._0); + case 2: // EvCall + return tag("call", result._0); + case 3: // EvDistribution + return tag( + "distribution", + new Distribution( + convertRawDistributionToGenericDist(result._0), + sampEnv + ) + ); + case 4: // EvNumber + return tag("number", result._0); + case 5: // EvRecord + return tag( + "record", + _.mapValues(result._0, (x) => convertRawToTypescript(x, sampEnv)) + ); + case 6: // EvString + return tag("string", result._0); + case 7: // EvSymbol + return tag("symbol", result._0); + } +} + +function convertRawDistributionToGenericDist( + result: rescriptDist +): genericDist { + switch (result.TAG) { + case 0: // Point Set Dist + switch (result._0.TAG) { + case 0: // Mixed + return tag("PointSet", tag("Mixed", result._0._0)); + case 1: // Discrete + return tag("PointSet", tag("Discrete", result._0._0)); + case 2: // Continuous + return tag("PointSet", tag("Continuous", result._0._0)); + } + case 1: // Sample Set Dist + return tag("SampleSet", result._0); + case 2: // Symbolic Dist + return tag("Symbolic", result._0); + } +} + +export type jsValue = + | string + | number + | jsValue[] + | { [key: string]: jsValue } + | boolean; + +export function jsValueToBinding(value: jsValue): rescriptExport { + if (typeof value === "boolean") { + return { TAG: 1, _0: value as boolean }; + } else if (typeof value === "string") { + return { TAG: 6, _0: value as string }; + } else if (typeof value === "number") { + return { TAG: 4, _0: value as number }; + } else if (Array.isArray(value)) { + return { TAG: 0, _0: value.map(jsValueToBinding) }; + } else { + // Record + return { TAG: 5, _0: _.mapValues(value, jsValueToBinding) }; + } +} diff --git a/packages/squiggle-lang/src/js/types.ts b/packages/squiggle-lang/src/js/types.ts new file mode 100644 index 00000000..8851b520 --- /dev/null +++ b/packages/squiggle-lang/src/js/types.ts @@ -0,0 +1,30 @@ +export type result = + | { + tag: "Ok"; + value: a; + } + | { + tag: "Error"; + value: b; + }; + +export function resultMap( + r: result, + mapFn: (x: a) => b +): result { + if (r.tag === "Ok") { + return { tag: "Ok", value: mapFn(r.value) }; + } else { + return r; + } +} + +export function Ok(x: a): result { + return { tag: "Ok", value: x }; +} + +export type tagged = { tag: a; value: b }; + +export function tag(x: a, y: b): tagged { + return { tag: x, value: y }; +} diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index e0bcaf5c..f5b38be7 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -350,7 +350,7 @@ module JsDate = { /* List */ module L = { module Util = { - let eq = (a, b) => a == b + let eq = \"==" } let fmap = List.map let get = Belt.List.get From b710289096c3ca54e8556f8e18b7bfd82479b6bb Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 29 Apr 2022 20:29:42 +0000 Subject: [PATCH 067/146] Rename parameters to imports --- .../src/components/SquiggleChart.tsx | 15 +++------ .../src/components/SquiggleEditor.tsx | 32 +++++++++++++------ .../squiggle-lang/__tests__/TS/JS_test.ts | 4 +-- .../squiggle-lang/__tests__/TS/TestHelpers.ts | 16 ++++++---- packages/squiggle-lang/src/js/index.ts | 31 +++++++++--------- 5 files changed, 53 insertions(+), 45 deletions(-) diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 235a4cee..be65d425 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -7,8 +7,8 @@ import { squiggleExpression, bindings, samplingParams, - parameters, - defaultParameters, + jsImports, + defaultImports, defaultBindings, } from "@quri/squiggle-lang"; import { NumberShower } from "./NumberShower"; @@ -154,7 +154,7 @@ export interface SquiggleChartProps { /** Bindings of previous variables declared */ bindings?: bindings; /** JS imported parameters */ - parameters?: parameters; + imports?: jsImports; } const ChartWrapper = styled.div` @@ -170,19 +170,14 @@ export const SquiggleChart: React.FC = ({ onChange = () => {}, height = 60, bindings = defaultBindings, - parameters = defaultParameters, + imports = defaultImports, width = NaN, }: SquiggleChartProps) => { let samplingInputs: samplingParams = { sampleCount: sampleCount, xyPointLength: outputXYPoints, }; - let expressionResult = run( - squiggleString, - bindings, - samplingInputs, - parameters - ); + let expressionResult = run(squiggleString, bindings, samplingInputs, imports); let internal: JSX.Element; if (expressionResult.tag === "Ok") { let expression = expressionResult.value; diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index 67f2e73b..697e9426 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -5,13 +5,14 @@ import { CodeEditor } from "./CodeEditor"; import styled from "styled-components"; import type { squiggleExpression, + samplingParams, bindings, - parameters, + jsImports, } from "@quri/squiggle-lang"; import { runPartial, errorValueToString, - defaultParameters, + defaultImports, defaultBindings, } from "@quri/squiggle-lang"; import { ErrorBox } from "./ErrorBox"; @@ -39,8 +40,8 @@ export interface SquiggleEditorProps { width: number; /** Previous variable declarations */ bindings: bindings; - /** JS Imported parameters */ - parameters: parameters; + /** JS Imports */ + imports: jsImports; } const Input = styled.div` @@ -62,7 +63,7 @@ export let SquiggleEditor: React.FC = ({ onChange, environment, bindings = defaultBindings, - parameters = defaultParameters, + imports = defaultImports, }: SquiggleEditorProps) => { let [expression, setExpression] = React.useState(initialSquiggleString); return ( @@ -89,7 +90,7 @@ export let SquiggleEditor: React.FC = ({ environment={environment} onChange={onChange} bindings={bindings} - parameters={parameters} + imports={imports} /> ); @@ -148,18 +149,29 @@ export interface SquigglePartialProps { width: number; /** Previously declared variables */ bindings?: bindings; - /** Parameters imported from js */ - parameters?: parameters; + /** Variables imported from js */ + imports?: jsImports; } export let SquigglePartial: React.FC = ({ initialSquiggleString = "", onChange, bindings = defaultBindings, - parameters = defaultParameters, + sampleCount = 1000, + outputXYPoints = 1000, + imports = defaultImports, }: SquigglePartialProps) => { + let samplingInputs: samplingParams = { + sampleCount: sampleCount, + xyPointLength: outputXYPoints, + }; let [expression, setExpression] = React.useState(initialSquiggleString); - let squiggleResult = runPartial(expression, bindings); + let squiggleResult = runPartial( + expression, + bindings, + samplingInputs, + imports + ); if (squiggleResult.tag == "Ok") { if (onChange) onChange(squiggleResult.value); } diff --git a/packages/squiggle-lang/__tests__/TS/JS_test.ts b/packages/squiggle-lang/__tests__/TS/JS_test.ts index 004d715e..76871fc8 100644 --- a/packages/squiggle-lang/__tests__/TS/JS_test.ts +++ b/packages/squiggle-lang/__tests__/TS/JS_test.ts @@ -68,13 +68,13 @@ describe("Partials", () => { }); }); -describe("Parameters", () => { +describe("JS Imports", () => { test("Can pass parameters into partials and cells", () => { let bindings = testRunPartial(`y = $x + 2`, defaultBindings, { x: 1 }); let bindings2 = testRunPartial(`z = y + $a`, bindings, { a: 3 }); expect(testRun(`z`, bindings2)).toEqual({ tag: "number", - value: 17, + value: 6, }); }); test("Complicated deep parameters", () => { diff --git a/packages/squiggle-lang/__tests__/TS/TestHelpers.ts b/packages/squiggle-lang/__tests__/TS/TestHelpers.ts index 3bbf42d8..d9d8444f 100644 --- a/packages/squiggle-lang/__tests__/TS/TestHelpers.ts +++ b/packages/squiggle-lang/__tests__/TS/TestHelpers.ts @@ -4,12 +4,15 @@ import { bindings, squiggleExpression, errorValueToString, + defaultImports, + defaultBindings, + jsImports, } from "../../src/js/index"; export function testRun( x: string, - bindings = {}, - parameters = {} + bindings: bindings = defaultBindings, + imports: jsImports = defaultImports ): squiggleExpression { let squiggleResult = run( x, @@ -18,9 +21,8 @@ export function testRun( sampleCount: 1000, xyPointLength: 100, }, - parameters + imports ); - // return squiggleResult.value if (squiggleResult.tag === "Ok") { return squiggleResult.value; } else { @@ -34,8 +36,8 @@ export function testRun( export function testRunPartial( x: string, - bindings: bindings = {}, - parameters = {} + bindings: bindings = defaultBindings, + imports: jsImports = defaultImports ): bindings { let squiggleResult = runPartial( x, @@ -44,7 +46,7 @@ export function testRunPartial( sampleCount: 1000, xyPointLength: 100, }, - parameters + imports ); if (squiggleResult.tag === "Ok") { return squiggleResult.value; diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 04d6050a..ce4d9428 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -16,7 +16,7 @@ export type { samplingParams, errorValue, externalBindings as bindings, - parameters, + jsImports, }; import { jsValueToBinding, @@ -28,7 +28,7 @@ import { import { result, resultMap, tag, tagged } from "./types"; import { Distribution } from "./distribution"; -export { Distribution, squiggleExpression, result }; +export { Distribution, squiggleExpression, result, resultMap }; export let defaultSamplingInputs: samplingParams = { sampleCount: 10000, @@ -39,16 +39,16 @@ export function run( squiggleString: string, bindings?: externalBindings, samplingInputs?: samplingParams, - parameters?: parameters + imports?: jsImports ): result { let b = bindings ? bindings : defaultBindings; - let p = parameters ? parameters : defaultParameters; + let i = imports ? imports : defaultImports; let si: samplingParams = samplingInputs ? samplingInputs : defaultSamplingInputs; let result: result = - evaluateUsingExternalBindings(squiggleString, mergeParameters(b, p)); + evaluateUsingExternalBindings(squiggleString, mergeImports(b, i)); return resultMap(result, (x) => createTsExport(x, si)); } @@ -57,33 +57,33 @@ export function runPartial( squiggleString: string, bindings?: externalBindings, _samplingInputs?: samplingParams, - parameters?: parameters + imports?: jsImports ): result { let b = bindings ? bindings : defaultBindings; - let p = parameters ? parameters : defaultParameters; + let i = imports ? imports : defaultImports; return evaluatePartialUsingExternalBindings( squiggleString, - mergeParameters(b, p) + mergeImports(b, i) ); } -function mergeParameters( +function mergeImports( bindings: externalBindings, - parameters: parameters + imports: jsImports ): externalBindings { - let transformedParameters = Object.fromEntries( - Object.entries(parameters).map(([key, value]) => [ + let transformedImports = Object.fromEntries( + Object.entries(imports).map(([key, value]) => [ "$" + key, jsValueToBinding(value), ]) ); - return _.merge(bindings, transformedParameters); + return _.merge(bindings, transformedImports); } -type parameters = { [key: string]: jsValue }; +type jsImports = { [key: string]: jsValue }; -export let defaultParameters: parameters = {}; +export let defaultImports: jsImports = {}; export let defaultBindings: externalBindings = {}; function createTsExport( @@ -146,4 +146,3 @@ function createTsExport( return tag("symbol", x.value); } } - From 2131e4eac165ce0fb6bf6bf1a87abe29b96b9491 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 29 Apr 2022 20:58:06 +0000 Subject: [PATCH 068/146] Rename imports to jsImports in components --- packages/components/src/components/SquiggleChart.tsx | 6 +++--- .../components/src/components/SquiggleEditor.tsx | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index be65d425..c0c5121d 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -154,7 +154,7 @@ export interface SquiggleChartProps { /** Bindings of previous variables declared */ bindings?: bindings; /** JS imported parameters */ - imports?: jsImports; + jsImports?: jsImports; } const ChartWrapper = styled.div` @@ -170,14 +170,14 @@ export const SquiggleChart: React.FC = ({ onChange = () => {}, height = 60, bindings = defaultBindings, - imports = defaultImports, + jsImports = defaultImports, width = NaN, }: SquiggleChartProps) => { let samplingInputs: samplingParams = { sampleCount: sampleCount, xyPointLength: outputXYPoints, }; - let expressionResult = run(squiggleString, bindings, samplingInputs, imports); + let expressionResult = run(squiggleString, bindings, samplingInputs, jsImports); let internal: JSX.Element; if (expressionResult.tag === "Ok") { let expression = expressionResult.value; diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index 697e9426..2c01f72f 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -41,7 +41,7 @@ export interface SquiggleEditorProps { /** Previous variable declarations */ bindings: bindings; /** JS Imports */ - imports: jsImports; + jsImports: jsImports; } const Input = styled.div` @@ -63,7 +63,7 @@ export let SquiggleEditor: React.FC = ({ onChange, environment, bindings = defaultBindings, - imports = defaultImports, + jsImports = defaultImports, }: SquiggleEditorProps) => { let [expression, setExpression] = React.useState(initialSquiggleString); return ( @@ -90,7 +90,7 @@ export let SquiggleEditor: React.FC = ({ environment={environment} onChange={onChange} bindings={bindings} - imports={imports} + jsImports={jsImports} /> ); @@ -150,7 +150,7 @@ export interface SquigglePartialProps { /** Previously declared variables */ bindings?: bindings; /** Variables imported from js */ - imports?: jsImports; + jsImports?: jsImports; } export let SquigglePartial: React.FC = ({ @@ -159,7 +159,7 @@ export let SquigglePartial: React.FC = ({ bindings = defaultBindings, sampleCount = 1000, outputXYPoints = 1000, - imports = defaultImports, + jsImports = defaultImports, }: SquigglePartialProps) => { let samplingInputs: samplingParams = { sampleCount: sampleCount, @@ -170,7 +170,7 @@ export let SquigglePartial: React.FC = ({ expression, bindings, samplingInputs, - imports + jsImports ); if (squiggleResult.tag == "Ok") { if (onChange) onChange(squiggleResult.value); From d09dbeb812f6609e9c4605bdabbd120ea4c70581 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 29 Apr 2022 20:59:37 +0000 Subject: [PATCH 069/146] Format components code --- packages/components/src/components/SquiggleChart.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index c0c5121d..31cd9787 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -177,7 +177,12 @@ export const SquiggleChart: React.FC = ({ sampleCount: sampleCount, xyPointLength: outputXYPoints, }; - let expressionResult = run(squiggleString, bindings, samplingInputs, jsImports); + let expressionResult = run( + squiggleString, + bindings, + samplingInputs, + jsImports + ); let internal: JSX.Element; if (expressionResult.tag === "Ok") { let expression = expressionResult.value; From 3117dd81d60955d72eed7aa75ad5a4aa6116d6d2 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 29 Apr 2022 21:16:22 +0000 Subject: [PATCH 070/146] Remove si prefix from chart axis --- packages/components/src/vega-specs/spec-distributions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/vega-specs/spec-distributions.json b/packages/components/src/vega-specs/spec-distributions.json index 129183a5..5b6ed261 100644 --- a/packages/components/src/vega-specs/spec-distributions.json +++ b/packages/components/src/vega-specs/spec-distributions.json @@ -88,7 +88,7 @@ "tickOpacity": 0.0, "domainColor": "#fff", "domainOpacity": 0.0, - "format": "~s", + "format": "~g", "tickCount": 10 } ], From 8217801de33c74b5c7e83eebe635c779c8f118b3 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Fri, 29 Apr 2022 18:38:55 -0400 Subject: [PATCH 071/146] magic numbers in bandwidth; `fromSamples` implementation Value: [1e-3 to 4e-2] --- .../__tests__/TS/SampleSet_test.ts | 16 +++++++++++++++- packages/squiggle-lang/src/js/index.ts | 5 +++++ .../DistributionOperation.res | 7 +++++++ .../DistributionOperation.resi | 2 ++ .../Distributions/DistributionTypes.res | 13 +++++++------ .../SampleSetDist/SampleSetDist.res | 3 ++- .../SampleSetDist/SampleSetDist_Bandwidth.res | 19 +++++++++++-------- .../src/rescript/MagicNumbers.res | 13 +++++++++++++ .../ReducerInterface_GenericDistribution.res | 11 +++++++++++ .../squiggle-lang/src/rescript/Utility/E.res | 2 ++ 10 files changed, 75 insertions(+), 16 deletions(-) diff --git a/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts b/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts index a617010b..356f19a4 100644 --- a/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts +++ b/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts @@ -1,5 +1,5 @@ import { Distribution } from "../../src/js/index"; -import { expectErrorToBeBounded, failDefault } from "./TestHelpers"; +import { expectErrorToBeBounded, failDefault, testRun } from "./TestHelpers"; import * as fc from "fast-check"; // Beware: float64Array makes it appear in an infinite loop. @@ -212,3 +212,17 @@ describe("mean is mean", () => { ); }); }); + +describe("fromSamples function", () => { + test("gives a mean near the mean of the input", () => { + fc.assert( + fc.property(arrayGen(), (xs_) => { + let xs = Array.from(xs_); + let squiggleString = `x = fromSamples($xs); mean(x)`; + let squiggleResult = testRun(squiggleString, {}, { xs: xs }); + let mean = xs.reduce((a, b) => a + b, 0.0) / xs.length; + expect(squiggleResult.value).toBeCloseTo(mean, 3); + }) + ); + }); +}); diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index fb67e47a..d72eb5c7 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -31,6 +31,7 @@ import { Constructors_isNormalized, Constructors_toPointSet, Constructors_toSampleSet, + Constructors_fromSamples, Constructors_truncate, Constructors_inspect, Constructors_toString, @@ -404,6 +405,10 @@ export class Distribution { ); } + fromSamples(n: Array): result { + return this.mapResultDist(Constructors_fromSamples({ env: this.env }, n)); + } + truncate( left: number, right: number diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res index 18ee2d6a..22376589 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res @@ -189,6 +189,12 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => { ->GenericDist.mixture(~scaleMultiplyFn=scaleMultiply, ~pointwiseAddFn=pointwiseAdd) ->E.R2.fmap(r => Dist(r)) ->OutputLocal.fromResult + | FromArray(xs) => + xs + ->SampleSetDist.make + ->E.R2.fmap2(x => DistributionTypes.SampleSetError(x)) + ->E.R2.fmap(x => x->DistributionTypes.SampleSet->Dist) + ->OutputLocal.fromResult } } @@ -229,6 +235,7 @@ module Constructors = { let isNormalized = (~env, dist) => C.isNormalized(dist)->run(~env)->toBoolR let toPointSet = (~env, dist) => C.toPointSet(dist)->run(~env)->toDistR let toSampleSet = (~env, dist, n) => C.toSampleSet(dist, n)->run(~env)->toDistR + let fromSamples = (~env, xs) => C.fromSamples(xs)->run(~env)->toDistR let truncate = (~env, dist, leftCutoff, rightCutoff) => C.truncate(dist, leftCutoff, rightCutoff)->run(~env)->toDistR let inspect = (~env, dist) => C.inspect(dist)->run(~env)->toDistR diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi index 5ad34354..fcaeb5e4 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi @@ -61,6 +61,8 @@ module Constructors: { @genType let toSampleSet: (~env: env, genericDist, int) => result @genType + let fromSamples: (~env: env, SampleSetDist.t) => result + @genType let truncate: (~env: env, genericDist, option, option) => result @genType let inspect: (~env: env, genericDist) => result diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res index 93f86798..a1725c88 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res @@ -11,7 +11,7 @@ type error = | NotYetImplemented | Unreachable | DistributionVerticalShiftIsInvalid - | TooFewSamples + | SampleSetError(SampleSetDist.sampleSetError) | ArgumentError(string) | OperationError(Operation.Error.t) | PointSetConversionError(SampleSetDist.pointsetConversionError) @@ -35,7 +35,8 @@ module Error = { | DistributionVerticalShiftIsInvalid => "Distribution Vertical Shift is Invalid" | ArgumentError(s) => `Argument Error ${s}` | LogarithmOfDistributionError(s) => `Logarithm of input error: ${s}` - | TooFewSamples => "Too Few Samples" + | SampleSetError(TooFewSamples) => "Too Few Samples" + | SampleSetError(NonNumericInput(err)) => `Found a non-number in input: ${err}` | OperationError(err) => Operation.Error.toString(err) | PointSetConversionError(err) => SampleSetDist.pointsetConversionErrorToString(err) | SparklineError(err) => PointSetTypes.sparklineErrorToString(err) @@ -47,10 +48,7 @@ module Error = { let resultStringToResultError: result<'a, string> => result<'a, error> = n => n->E.R2.errMap(r => r->fromString) - let sampleErrorToDistErr = (err: SampleSetDist.sampleSetError): error => - switch err { - | TooFewSamples => TooFewSamples - } + let sampleErrorToDistErr = (err: SampleSetDist.sampleSetError): error => SampleSetError(err) } @genType @@ -100,6 +98,7 @@ module DistributionOperation = { | FromDist(fromDist, genericDist) | FromFloat(fromDist, float) | Mixture(array<(genericDist, float)>) + | FromArray(SampleSetDist.t) let distCallToString = (distFunction: fromDist): string => switch distFunction { @@ -124,6 +123,7 @@ module DistributionOperation = { switch d { | FromDist(f, _) | FromFloat(f, _) => distCallToString(f) | Mixture(_) => `mixture` + | FromArray(_) => `samples` } } module Constructors = { @@ -140,6 +140,7 @@ module Constructors = { let isNormalized = (dist): t => FromDist(ToBool(IsNormalized), dist) let toPointSet = (dist): t => FromDist(ToDist(ToPointSet), dist) let toSampleSet = (dist, r): t => FromDist(ToDist(ToSampleSet(r)), dist) + let fromSamples = (xs): t => FromArray(xs) let truncate = (dist, left, right): t => FromDist(ToDist(Truncate(left, right)), dist) let inspect = (dist): t => FromDist(ToDist(Inspect), dist) let toString = (dist): t => FromDist(ToString(ToString), dist) diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res index 14c66812..55b334c5 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res @@ -1,11 +1,12 @@ @genType module Error = { @genType - type sampleSetError = TooFewSamples + type sampleSetError = TooFewSamples | NonNumericInput(string) let sampleSetErrorToString = (err: sampleSetError): string => switch err { | TooFewSamples => "Too few samples when constructing sample set" + | NonNumericInput(err) => `Found a non-number in input: ${err}` } @genType diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res index aef659d1..29d48ad3 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res @@ -1,27 +1,30 @@ //The math here was taken from https://github.com/jasondavies/science.js/blob/master/src/stats/SampleSetDist_Bandwidth.js - +let {iqr_percentile, nrd0_lo_denominator, one, nrd0_coef, nrd_coef, nrd_fractionalPower} = module( + MagicNumbers.SampleSetBandwidth +) let len = x => E.A.length(x) |> float_of_int -let iqr = x => Jstat.percentile(x, 0.75, true) -. Jstat.percentile(x, 0.25, true) +let iqr = x => + Jstat.percentile(x, iqr_percentile, true) -. Jstat.percentile(x, 1.0 -. iqr_percentile, true) // Silverman, B. W. (1986) Density Estimation. London: Chapman and Hall. let nrd0 = x => { let hi = Js_math.sqrt(Jstat.variance(x)) - let lo = Js_math.minMany_float([hi, iqr(x) /. 1.34]) + let lo = Js_math.minMany_float([hi, iqr(x) /. nrd0_lo_denominator]) let e = Js_math.abs_float(x[1]) let lo' = switch (lo, hi, e) { | (lo, _, _) if !Js.Float.isNaN(lo) => lo | (_, hi, _) if !Js.Float.isNaN(hi) => hi | (_, _, e) if !Js.Float.isNaN(e) => e - | _ => 1.0 + | _ => one } - 0.9 *. lo' *. Js.Math.pow_float(~base=len(x), ~exp=-0.2) + nrd0_coef *. lo' *. Js.Math.pow_float(~base=len(x), ~exp=nrd_fractionalPower) } // Scott, D. W. (1992) Multivariate Density Estimation: Theory, Practice, and Visualization. Wiley. let nrd = x => { - let h = iqr(x) /. 1.34 - 1.06 *. + let h = iqr(x) /. nrd0_lo_denominator + nrd_coef *. Js.Math.min_float(Js.Math.sqrt(Jstat.variance(x)), h) *. - Js.Math.pow_float(~base=len(x), ~exp=-1.0 /. 5.0) + Js.Math.pow_float(~base=len(x), ~exp=nrd_fractionalPower) } diff --git a/packages/squiggle-lang/src/rescript/MagicNumbers.res b/packages/squiggle-lang/src/rescript/MagicNumbers.res index 124a44f4..0f059c03 100644 --- a/packages/squiggle-lang/src/rescript/MagicNumbers.res +++ b/packages/squiggle-lang/src/rescript/MagicNumbers.res @@ -35,3 +35,16 @@ module ToPointSet = { */ let minDiscreteToKeep = samples => max(20, E.A.length(samples) / 50) } + +module SampleSetBandwidth = { + // Silverman, B. W. (1986) Density Estimation. London: Chapman and Hall. + // Scott, D. W. (1992) Multivariate Density Estimation: Theory, Practice, and Visualization. Wiley. + let iqr_percentile = 0.75 + let iqr_percentile_complement = 1.0 -. iqr_percentile + let nrd0_lo_denominator = 1.34 + let one = 1.0 + let nrd0_coef = 0.9 + + let nrd_coef = 1.06 + let nrd_fractionalPower = -0.2 +} diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index ab76f469..49165f0f 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -218,6 +218,17 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option< Helpers.toDistFn(ToSampleSet(Belt.Int.fromFloat(float)), dist) | ("toSampleSet", [EvDistribution(dist)]) => Helpers.toDistFn(ToSampleSet(MagicNumbers.Environment.defaultSampleCount), dist) + | ("fromSamples", [EvArray(arr)]) => + Helpers.toDistFn( + ToSampleSet(MagicNumbers.Environment.defaultSampleCount), + arr + ->Helpers.parseNumberArray + ->E.R2.fmap2(x => SampleSetDist.NonNumericInput(x)) + ->E.R.bind(SampleSetDist.make) + ->E.R2.fmap(x => DistributionTypes.SampleSet(x)) + // Raising here isn't ideal. This: GenDistError(SampleSetError(NonNumericInput("Something wasn't a number"))) would be proper. + ->E.R2.toExn("Something in the input wasn't a number"), + ) | ("inspect", [EvDistribution(dist)]) => Helpers.toDistFn(Inspect, dist) | ("truncateLeft", [EvDistribution(dist), EvNumber(float)]) => Helpers.toDistFn(Truncate(Some(float), None), dist) diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index e0bcaf5c..5b3280d8 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -307,6 +307,8 @@ module R2 = { | Ok(x) => x->Ok | Error(x) => x->f->Error } + + let toExn = (a, b) => R.toExn(b, a) } let safe_fn_of_string = (fn, s: string): option<'a> => From ba0baf31c67cc0664d1df3ce55ace32afd73d63d Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Fri, 29 Apr 2022 18:45:12 -0400 Subject: [PATCH 072/146] Fixed a (now skipped) test [1e-5 to 1e-4] --- packages/squiggle-lang/__tests__/TS/SampleSet_test.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts b/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts index 356f19a4..2c77e210 100644 --- a/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts +++ b/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts @@ -214,14 +214,15 @@ describe("mean is mean", () => { }); describe("fromSamples function", () => { - test("gives a mean near the mean of the input", () => { + test.skip("gives a mean near the mean of the input", () => { fc.assert( fc.property(arrayGen(), (xs_) => { let xs = Array.from(xs_); - let squiggleString = `x = fromSamples($xs); mean(x)`; - let squiggleResult = testRun(squiggleString, {}, { xs: xs }); + let xsString = xs.toString(); + let squiggleString = `x = fromSamples([${xsString}]); mean(x)`; + let squiggleResult = testRun(squiggleString); let mean = xs.reduce((a, b) => a + b, 0.0) / xs.length; - expect(squiggleResult.value).toBeCloseTo(mean, 3); + expect(squiggleResult.value).toBeCloseTo(mean, 4); }) ); }); From 3249f6915522ff963b842a38cb008d1dc284b837 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Fri, 29 Apr 2022 21:41:09 -0400 Subject: [PATCH 073/146] Small cleanup to fromSamples --- .../DistributionOperation.res | 5 ++--- .../Distributions/DistributionTypes.res | 6 +++--- .../ReducerInterface_GenericDistribution.res | 19 ++++++++----------- .../squiggle-lang/src/rescript/Utility/E.res | 7 +++++++ 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res index 22376589..f323cdcb 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res @@ -189,10 +189,9 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => { ->GenericDist.mixture(~scaleMultiplyFn=scaleMultiply, ~pointwiseAddFn=pointwiseAdd) ->E.R2.fmap(r => Dist(r)) ->OutputLocal.fromResult - | FromArray(xs) => - xs + | FromSamples(xs) => xs ->SampleSetDist.make - ->E.R2.fmap2(x => DistributionTypes.SampleSetError(x)) + ->E.R2.errMap(x => DistributionTypes.SampleSetError(x)) ->E.R2.fmap(x => x->DistributionTypes.SampleSet->Dist) ->OutputLocal.fromResult } diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res index a1725c88..c5b9a4ef 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res @@ -97,8 +97,8 @@ module DistributionOperation = { type genericFunctionCallInfo = | FromDist(fromDist, genericDist) | FromFloat(fromDist, float) + | FromSamples(array) | Mixture(array<(genericDist, float)>) - | FromArray(SampleSetDist.t) let distCallToString = (distFunction: fromDist): string => switch distFunction { @@ -123,7 +123,7 @@ module DistributionOperation = { switch d { | FromDist(f, _) | FromFloat(f, _) => distCallToString(f) | Mixture(_) => `mixture` - | FromArray(_) => `samples` + | FromSamples(_) => `fromSamples` } } module Constructors = { @@ -140,7 +140,7 @@ module Constructors = { let isNormalized = (dist): t => FromDist(ToBool(IsNormalized), dist) let toPointSet = (dist): t => FromDist(ToDist(ToPointSet), dist) let toSampleSet = (dist, r): t => FromDist(ToDist(ToSampleSet(r)), dist) - let fromSamples = (xs): t => FromArray(xs) + let fromSamples = (xs): t => FromSamples(xs) let truncate = (dist, left, right): t => FromDist(ToDist(Truncate(left, right)), dist) let inspect = (dist): t => FromDist(ToDist(Inspect), dist) let toString = (dist): t => FromDist(ToString(ToString), dist) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index 49165f0f..5277ae1c 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -218,17 +218,14 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option< Helpers.toDistFn(ToSampleSet(Belt.Int.fromFloat(float)), dist) | ("toSampleSet", [EvDistribution(dist)]) => Helpers.toDistFn(ToSampleSet(MagicNumbers.Environment.defaultSampleCount), dist) - | ("fromSamples", [EvArray(arr)]) => - Helpers.toDistFn( - ToSampleSet(MagicNumbers.Environment.defaultSampleCount), - arr - ->Helpers.parseNumberArray - ->E.R2.fmap2(x => SampleSetDist.NonNumericInput(x)) - ->E.R.bind(SampleSetDist.make) - ->E.R2.fmap(x => DistributionTypes.SampleSet(x)) - // Raising here isn't ideal. This: GenDistError(SampleSetError(NonNumericInput("Something wasn't a number"))) would be proper. - ->E.R2.toExn("Something in the input wasn't a number"), - ) + | ("fromSamples", [EvArray(inputArray)]) => { + let _wrapInputErrors = x => SampleSetDist.NonNumericInput(x) + let parsedArray = Helpers.parseNumberArray(inputArray)->E.R2.errMap(_wrapInputErrors) + switch parsedArray { + | Ok(array) => runGenericOperation(FromSamples(array)) + | Error(e) => GenDistError(SampleSetError(e)) + }->Some + } | ("inspect", [EvDistribution(dist)]) => Helpers.toDistFn(Inspect, dist) | ("truncateLeft", [EvDistribution(dist), EvNumber(float)]) => Helpers.toDistFn(Truncate(Some(float), None), dist) diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index 5b3280d8..9edeae1b 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -289,6 +289,13 @@ module R = { | Ok(r) => r->Ok | Error(x) => x->f->Error } + + //I'm not sure what to call this. + let unify = (a: result<'a, 'b>, c: 'b => 'a): 'a => + switch a { + | Ok(x) => x + | Error(x) => c(x) + } } module R2 = { From e724f43b9d9bafc7cf8220b6a6f9f41b77040a00 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Sat, 30 Apr 2022 10:01:55 -0400 Subject: [PATCH 074/146] Documented `fromSamples` Value: [1e-4 to 1e-3] --- packages/website/docs/Features/Functions.mdx | 32 ++++++++++++-------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/packages/website/docs/Features/Functions.mdx b/packages/website/docs/Features/Functions.mdx index e37ea315..8282b11c 100644 --- a/packages/website/docs/Features/Functions.mdx +++ b/packages/website/docs/Features/Functions.mdx @@ -315,6 +315,26 @@ Or `PointSet` format +### `toSampleSet` has two signatures + +Above, we saw the unary `toSampleSet`, which uses an internal hardcoded number of samples. If you'd like to provide the number of samples, it has a binary signature as well (floored) + + + +#### Validity + +- Second argument to `toSampleSet` must be a number. + +## `fromSamples` + + +#### Validity + +For `fromSamples(xs)`, + +- `xs.length > 5` +- Strictly every element of `xs` must be a number. + ## Normalization Some distribution operations (like horizontal shift) return an unnormalized distriibution. @@ -333,18 +353,6 @@ We provide a predicate `isNormalized`, for when we have simple control flow - Input to `isNormalized` must be a dist -## Convert any distribution to a sample set distribution - -`toSampleSet` has two signatures - -It is unary when you use an internal hardcoded number of samples - - - -And binary when you provide a number of samples (floored) - - - ## `inspect` You may like to debug by right clicking your browser and using the _inspect_ functionality on the webpage, and viewing the _console_ tab. Then, wrap your squiggle output with `inspect` to log an internal representation. From f3561317fdd12c5104715739b93fb08f85364fc1 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Sat, 30 Apr 2022 10:10:09 -0400 Subject: [PATCH 075/146] Moved `fromSamples` to `Inventory` section Value: [1e-7 to 1e-5] --- packages/website/docs/Features/Functions.mdx | 23 +++++++++++--------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/website/docs/Features/Functions.mdx b/packages/website/docs/Features/Functions.mdx index 8282b11c..1de7514b 100644 --- a/packages/website/docs/Features/Functions.mdx +++ b/packages/website/docs/Features/Functions.mdx @@ -98,6 +98,19 @@ bound `a`, mode `b` and upper bound `c`. Squiggle, when the context is right, automatically casts a float to a constant distribution. +## `fromSamples` + +The last distribution constructor takes an array of samples and constructs a sample set distribution. + + + +#### Validity + +For `fromSamples(xs)`, + +- `xs.length > 5` +- Strictly every element of `xs` must be a number. + ## Operating on distributions Here are the ways we combine distributions. @@ -325,16 +338,6 @@ Above, we saw the unary `toSampleSet`, which uses an internal hardcoded number o - Second argument to `toSampleSet` must be a number. -## `fromSamples` - - -#### Validity - -For `fromSamples(xs)`, - -- `xs.length > 5` -- Strictly every element of `xs` must be a number. - ## Normalization Some distribution operations (like horizontal shift) return an unnormalized distriibution. From 9fe7034c518b6d6ecc42aa2cb21bdd9185acbc0c Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Sat, 30 Apr 2022 11:33:03 -0400 Subject: [PATCH 076/146] v0.2.8: `fromSamples` and jsImports --- packages/squiggle-lang/README.md | 15 +++++++++++++++ packages/squiggle-lang/package.json | 6 ++++-- .../DistributionOperation.res | 3 ++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/squiggle-lang/README.md b/packages/squiggle-lang/README.md index 05bb969c..4513ee76 100644 --- a/packages/squiggle-lang/README.md +++ b/packages/squiggle-lang/README.md @@ -3,6 +3,21 @@ # Squiggle language +## Use the `npm` package + +For instance, in a fresh `create-react-app`, you can + +```sh +yarn add @quri/squiggle-lang +``` + +```js +import {run} from '@quri/squiggle-lang'; +run("normal(0, 1) * fromSamples([-3,-2,-1,1,2,3,3,3,4,9]").value.value.toSparkline().value) +``` + +**However, for most use cases you'll prefer to use our [library of react components](https://www.npmjs.com/package/@quri/squiggle-components)**, and let your app transitively depend on `@quri/squiggle-lang`. + ## Build for development We assume that you ran `yarn` at the monorepo level. diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 4d146ef8..34930989 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -1,6 +1,6 @@ { "name": "@quri/squiggle-lang", - "version": "0.2.7", + "version": "0.2.8", "homepage": "https://squiggle-language.com", "license": "MIT", "scripts": { @@ -24,6 +24,7 @@ "format:rescript": "rescript format -all", "format:prettier": "prettier --write .", "format": "yarn format:rescript && yarn format:prettier", + "prepack": "yarn build && yarn test && yarn bundle", "all": "yarn build && yarn bundle && yarn test" }, "keywords": [ @@ -35,7 +36,7 @@ "rescript": "^9.1.4", "jstat": "^1.9.5", "pdfast": "^0.2.0", - "mathjs": "10.5.0" + "mathjs": "^10.5.0" }, "devDependencies": { "bisect_ppx": "^2.7.1", @@ -61,6 +62,7 @@ "webpack-cli": "^4.9.2" }, "source": "./src/js/index.ts", + "browser": "./dist/bundle.js", "main": "./dist/src/js/index.js", "types": "./dist/src/js/index.d.ts" } diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res index f323cdcb..db6656b2 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res @@ -189,7 +189,8 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => { ->GenericDist.mixture(~scaleMultiplyFn=scaleMultiply, ~pointwiseAddFn=pointwiseAdd) ->E.R2.fmap(r => Dist(r)) ->OutputLocal.fromResult - | FromSamples(xs) => xs + | FromSamples(xs) => + xs ->SampleSetDist.make ->E.R2.errMap(x => DistributionTypes.SampleSetError(x)) ->E.R2.fmap(x => x->DistributionTypes.SampleSet->Dist) From 93ef7c76a01ac39e6afbfc4d8f1b6b56485c21c7 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Sat, 30 Apr 2022 12:04:03 -0400 Subject: [PATCH 077/146] v0.2.16: jsImports prop and incremented minimal squiggle-lang Value: [1e-5 to 1e-3] --- packages/components/README.md | 12 +++--------- packages/components/package.json | 14 +++++++------- packages/squiggle-lang/README.md | 16 ++++++++++------ 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/packages/components/README.md b/packages/components/README.md index ad35c67f..4d073a14 100644 --- a/packages/components/README.md +++ b/packages/components/README.md @@ -1,9 +1,9 @@ [![npm version](https://badge.fury.io/js/@quri%2Fsquiggle-components.svg)](https://www.npmjs.com/package/@quri/squiggle-components) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/quantified-uncertainty/squiggle/blob/develop/LICENSE) -# Squiggle Components +# Squiggle components -This package contains all the components for squiggle. These can be used either as a library or hosted as a [storybook](https://storybook.js.org/). +This package contains the react components for squiggle. These can be used either as a library or hosted as a [storybook](https://storybook.js.org/). # Usage in a `react` project @@ -17,7 +17,7 @@ Add to `App.js`: ```jsx import { SquiggleEditor } from "@quri/squiggle-components"; -; +; ``` # Build storybook for development @@ -38,9 +38,3 @@ Run a development server ```sh yarn start ``` - -And build artefacts for production, - -```sh -yarn build # builds storybook app -``` diff --git a/packages/components/package.json b/packages/components/package.json index 3b50afbf..fbdd476a 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,9 +1,9 @@ { "name": "@quri/squiggle-components", - "version": "0.2.15", + "version": "0.2.16", "license": "MIT", "dependencies": { - "@quri/squiggle-lang": "^0.2.7", + "@quri/squiggle-lang": "^0.2.8", "@react-hook/size": "^2.1.2", "lodash": "^4.17.21", "react": "^18.1.0", @@ -49,11 +49,11 @@ "scripts": { "start": "cross-env REACT_APP_FAST_REFRESH=false && start-storybook -p 6006 -s public", "build": "tsc -b && build-storybook -s public", - "build:package": "tsc -b", "bundle": "webpack", "all": "yarn bundle && yarn build", "lint": "prettier --check .", - "format": "prettier --write ." + "format": "prettier --write .", + "prepack": "yarn bundle && tsc -b" }, "eslintConfig": { "extends": [ @@ -87,7 +87,7 @@ "@types/react": "17.0.43" }, "source": "./src/index.ts", - "browser": "dist/bundle.js", - "main": "dist/src/index.js", - "types": "dist/src/index.d.ts" + "browser": "./dist/bundle.js", + "main": "./dist/src/index.js", + "types": "./dist/src/index.d.ts" } diff --git a/packages/squiggle-lang/README.md b/packages/squiggle-lang/README.md index 4513ee76..f6735454 100644 --- a/packages/squiggle-lang/README.md +++ b/packages/squiggle-lang/README.md @@ -3,22 +3,26 @@ # Squiggle language -## Use the `npm` package +_An estimation language_ -For instance, in a fresh `create-react-app`, you can +# Use the `npm` package + +For instance, in a javascript project, you can ```sh yarn add @quri/squiggle-lang ``` ```js -import {run} from '@quri/squiggle-lang'; -run("normal(0, 1) * fromSamples([-3,-2,-1,1,2,3,3,3,4,9]").value.value.toSparkline().value) +import { run } from "@quri/squiggle-lang"; +run( + "normal(0, 1) * fromSamples([-3,-2,-1,1,2,3,3,3,4,9]" +).value.value.toSparkline().value; ``` **However, for most use cases you'll prefer to use our [library of react components](https://www.npmjs.com/package/@quri/squiggle-components)**, and let your app transitively depend on `@quri/squiggle-lang`. -## Build for development +# Build for development We assume that you ran `yarn` at the monorepo level. @@ -38,7 +42,7 @@ yarn test yarn coverage:rescript; o _coverage/index.html # produces coverage report and opens it in browser ``` -## Distributing this package or using this package from other monorepo packages +# Distributing this package or using this package from other monorepo packages As it says in the other `packages/*/README.md`s, building this package is an essential step of building other packages. From 1aea9b6c0830ea69899cd7a78c0e98d5d939e477 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Sat, 30 Apr 2022 12:16:47 -0400 Subject: [PATCH 078/146] fixed dead material in `yarn.lock` Value: [1e-9 to 1e-6] --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 3597fea6..ec55f879 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11751,7 +11751,7 @@ markdown-to-jsx@^7.1.3: resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.1.7.tgz#a5f22102fb12241c8cea1ca6a4050bb76b23a25d" integrity sha512-VI3TyyHlGkO8uFle0IOibzpO1c1iJDcXcS/zBrQrXQQvJ2tpdwVzVZ7XdKsyRz1NdRmre4dqQkMZzUHaKIG/1w== -mathjs@10.5.0: +mathjs@^10.5.0: version "10.5.0" resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-10.5.0.tgz#f81d0518fe7b4b2a0b85e1125b8ecfc364fb0292" integrity sha512-gRnSY9psN9zgiB2QV9F4XbuX5hwjxY5Ou7qoTFWDbn2vZ3UEs+sjfK/SRg2WP30TNfZWpwlGdp8H1knFJnpFdA== From a3057789b0957516d84a91e666a516e8dc29d92b Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Sat, 30 Apr 2022 12:52:13 -0400 Subject: [PATCH 079/146] `^`-version everything Value: [1e-9 to 1e-6] --- packages/components/package.json | 4 ++-- packages/squiggle-lang/package.json | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index fbdd476a..fbddaf2c 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -7,7 +7,7 @@ "@react-hook/size": "^2.1.2", "lodash": "^4.17.21", "react": "^18.1.0", - "react-ace": "10.1.0", + "react-ace": "^10.1.0", "react-dom": "^18.1.0", "react-vega": "^7.5.0", "styled-components": "^5.3.5", @@ -36,7 +36,7 @@ "@types/styled-components": "^5.1.24", "@types/webpack": "^5.28.0", "cross-env": "^7.0.3", - "react-scripts": "5.0.1", + "react-scripts": "^5.0.1", "style-loader": "^3.3.1", "ts-loader": "^9.2.9", "tsconfig-paths-webpack-plugin": "^3.5.2", diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 34930989..ab3e0b72 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -40,18 +40,18 @@ }, "devDependencies": { "bisect_ppx": "^2.7.1", - "lodash": "4.17.21", + "lodash": "^4.17.21", "rescript-fast-check": "^1.1.1", "@glennsl/rescript-jest": "^0.9.0", "@istanbuljs/nyc-config-typescript": "^1.0.2", "@types/jest": "^27.4.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", "chalk": "^5.0.1", - "codecov": "3.8.3", - "fast-check": "2.25.0", + "codecov": "^3.8.3", + "fast-check": "^2.25.0", "gentype": "^4.3.0", "jest": "^27.5.1", - "moduleserve": "0.9.1", + "moduleserve": "^0.9.1", "nyc": "^15.1.0", "reanalyze": "^2.19.0", "ts-jest": "^27.1.4", From 05ec19b2a43a0f9d96e24a800000271c26d6f9df Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Sat, 30 Apr 2022 12:56:45 -0400 Subject: [PATCH 080/146] `^`-version everything: `yarn.lock` update Value: [1e-10 to 1e-6] --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index ec55f879..89928253 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6498,7 +6498,7 @@ coa@^2.0.2: chalk "^2.4.1" q "^1.1.2" -codecov@3.8.3: +codecov@^3.8.3: version "3.8.3" resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.8.3.tgz#9c3e364b8a700c597346ae98418d09880a3fdbe7" integrity sha512-Y8Hw+V3HgR7V71xWH2vQ9lyS358CbGCldWlJFR0JirqoGtOoas3R3/OclRTvgUYFK29mmJICDPauVKmpqbwhOA== @@ -8607,7 +8607,7 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -fast-check@2.25.0, fast-check@^2.17.0: +fast-check@^2.17.0, fast-check@^2.25.0: version "2.25.0" resolved "https://registry.yarnpkg.com/fast-check/-/fast-check-2.25.0.tgz#5146601851bf3be0953bd17eb2b7d547936c6561" integrity sha512-wRUT2KD2lAmT75WNIJIHECawoUUMHM0I5jrlLXGtGeqmPL8jl/EldUDjY1VCp6fDY8yflyfUeIOsOBrIbIiArg== @@ -11627,7 +11627,7 @@ lodash.uniq@4.5.0, lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0: +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -12120,7 +12120,7 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -moduleserve@0.9.1: +moduleserve@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/moduleserve/-/moduleserve-0.9.1.tgz#11bad4337ea248d7eaf10d2c7f8649a8c3b9c1f8" integrity sha512-WF2BeGnM2Ko7bdICgJO+Ibu+ZD33ExJHzOzTDsCUzfZnvnFfheEIYBTWyIqSRU0tXh4UTQ1krDOCglFTJPBMow== @@ -14439,7 +14439,7 @@ react-ace@10.0.0: lodash.isequal "^4.5.0" prop-types "^15.7.2" -react-ace@10.1.0: +react-ace@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/react-ace/-/react-ace-10.1.0.tgz#d348eac2b16475231779070b6cd16768deed565f" integrity sha512-VkvUjZNhdYTuKOKQpMIZi7uzZZVgzCjM7cLYu6F64V0mejY8a2XTyPUIMszC6A4trbeMIHbK5fYFcT/wkP/8VA== @@ -14693,7 +14693,7 @@ react-router@6.3.0, react-router@^6.0.0: dependencies: history "^5.2.0" -react-scripts@5.0.1: +react-scripts@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-5.0.1.tgz#6285dbd65a8ba6e49ca8d651ce30645a6d980003" integrity sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ== From fd957ef40136a708c61940d8b4dd4bacf363d4fb Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 30 Apr 2022 13:43:46 -0400 Subject: [PATCH 081/146] Mixture last argument can be float --- .../ReducerInterface/ReducerInterface_GenericDistribution.res | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index 7f5ad1eb..30585395 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -131,6 +131,7 @@ module Helpers = { | Error(err) => GenDistError(ArgumentError(err)) } } + | Some(EvNumber(_)) | Some(EvDistribution(_)) => switch parseDistributionArray(args) { | Ok(distributions) => mixtureWithDefaultWeights(distributions) From f8f6a1ecc624934c581c4c3dcc35b110fd4566a9 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Sat, 30 Apr 2022 13:57:41 -0400 Subject: [PATCH 082/146] hotfix: deleted `browser` field of `package.json`s Value: [1e-9 to 1e-5] --- packages/components/package.json | 1 - packages/squiggle-lang/package.json | 1 - .../DistributionOperation/DistributionOperation.res | 4 ++-- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index fbddaf2c..29c158fc 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -87,7 +87,6 @@ "@types/react": "17.0.43" }, "source": "./src/index.ts", - "browser": "./dist/bundle.js", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts" } diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index ab3e0b72..40f7e7c7 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -62,7 +62,6 @@ "webpack-cli": "^4.9.2" }, "source": "./src/js/index.ts", - "browser": "./dist/bundle.js", "main": "./dist/src/js/index.js", "types": "./dist/src/js/index.d.ts" } diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res index 9952c6da..5f07c6a8 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res @@ -154,12 +154,12 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => { ->GenericDist.toPointSet(~xyPointLength, ~sampleCount, ()) ->E.R2.fmap(r => Dist(PointSet(r))) ->OutputLocal.fromResult - | ToDist(Scale(#Logarithm, f)) => + | ToDist(Scale(#Logarithm, f)) => dist ->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~algebraicCombination=#Logarithm, ~f) ->E.R2.fmap(r => Dist(r)) ->OutputLocal.fromResult - | ToDist(Scale(#Power, f)) => + | ToDist(Scale(#Power, f)) => dist ->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~algebraicCombination=#Power, ~f) ->E.R2.fmap(r => Dist(r)) From adb3b335ce837630f3b21a1776383f72276a9c45 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Sat, 30 Apr 2022 13:58:32 -0400 Subject: [PATCH 083/146] 17 increment Value: [1e-10 to 1e-7] --- packages/components/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/package.json b/packages/components/package.json index 29c158fc..4888a0a5 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@quri/squiggle-components", - "version": "0.2.16", + "version": "0.2.17", "license": "MIT", "dependencies": { "@quri/squiggle-lang": "^0.2.8", From 615051d1c61fd45fcbe8df41d49704d9eb726451 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Sat, 30 Apr 2022 14:10:01 -0400 Subject: [PATCH 084/146] hotfix: brackets in `components/README.md` --- packages/components/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/README.md b/packages/components/README.md index 4d073a14..12cd87a9 100644 --- a/packages/components/README.md +++ b/packages/components/README.md @@ -17,7 +17,7 @@ Add to `App.js`: ```jsx import { SquiggleEditor } from "@quri/squiggle-components"; -; +; ``` # Build storybook for development From 2776a4369302c81b7b4fe8b454971b991afc5e25 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Sat, 30 Apr 2022 14:10:54 -0400 Subject: [PATCH 085/146] lint --- packages/components/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/components/README.md b/packages/components/README.md index 12cd87a9..03eb5750 100644 --- a/packages/components/README.md +++ b/packages/components/README.md @@ -17,7 +17,10 @@ Add to `App.js`: ```jsx import { SquiggleEditor } from "@quri/squiggle-components"; -; +; ``` # Build storybook for development From c0ec3b02b7943371473d8bd561654081acfe68f3 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 30 Apr 2022 14:34:00 -0400 Subject: [PATCH 086/146] Minor documentation improvements --- packages/website/docs/Features/Functions.mdx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/website/docs/Features/Functions.mdx b/packages/website/docs/Features/Functions.mdx index 1de7514b..936d8b93 100644 --- a/packages/website/docs/Features/Functions.mdx +++ b/packages/website/docs/Features/Functions.mdx @@ -5,8 +5,6 @@ sidebar_position: 7 import { SquiggleEditor } from "../../src/components/SquiggleEditor"; -_The source of truth for this document is [this file of code](https://github.com/quantified-uncertainty/squiggle/blob/develop/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res)_ - ## Inventory distributions We provide starter distributions, computed symbolically. @@ -255,8 +253,8 @@ dist1 .* dist2`} ### Pointwise division From d6cec6886cd1effd80e6a80111ab7d89c66600b7 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Sat, 30 Apr 2022 18:40:18 +0000 Subject: [PATCH 087/146] Clean up the props, removing unused and making some optional --- packages/components/src/components/SquiggleChart.tsx | 2 -- .../components/src/components/SquiggleEditor.tsx | 12 +++--------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 31cd9787..699a7e28 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -144,8 +144,6 @@ export interface SquiggleChartProps { diagramStop?: number; /** If the result is a function, how many points along the function it samples */ diagramCount?: number; - /** variables declared before this expression */ - environment?: unknown; /** When the environment changes */ onChange?(expr: squiggleExpression): void; /** CSS width of the element */ diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index 2c01f72f..23686a4f 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -32,16 +32,14 @@ export interface SquiggleEditorProps { diagramStop?: number; /** If the result is a function, how many points along the function it samples */ diagramCount?: number; - /** The environment, other variables that were already declared */ - environment?: unknown; /** when the environment changes. Used again for notebook magic*/ onChange?(expr: squiggleExpression): void; /** The width of the element */ - width: number; + width?: number; /** Previous variable declarations */ - bindings: bindings; + bindings?: bindings; /** JS Imports */ - jsImports: jsImports; + jsImports?: jsImports; } const Input = styled.div` @@ -61,7 +59,6 @@ export let SquiggleEditor: React.FC = ({ diagramStop, diagramCount, onChange, - environment, bindings = defaultBindings, jsImports = defaultImports, }: SquiggleEditorProps) => { @@ -87,7 +84,6 @@ export let SquiggleEditor: React.FC = ({ diagramStart={diagramStart} diagramStop={diagramStop} diagramCount={diagramCount} - environment={environment} onChange={onChange} bindings={bindings} jsImports={jsImports} @@ -145,8 +141,6 @@ export interface SquigglePartialProps { diagramCount?: number; /** when the environment changes. Used again for notebook magic*/ onChange?(expr: bindings): void; - /** The width of the element */ - width: number; /** Previously declared variables */ bindings?: bindings; /** Variables imported from js */ From 37047ac9ffcaf224ea9c217df90cdfd1a44a82f9 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 30 Apr 2022 21:47:54 -0400 Subject: [PATCH 088/146] Starting to pull out distributions functionality --- .../website/docs/Features/Distributions.mdx | 258 ++++++++++++++++++ packages/website/docs/Features/Functions.mdx | 25 -- 2 files changed, 258 insertions(+), 25 deletions(-) create mode 100644 packages/website/docs/Features/Distributions.mdx diff --git a/packages/website/docs/Features/Distributions.mdx b/packages/website/docs/Features/Distributions.mdx new file mode 100644 index 00000000..81d8737e --- /dev/null +++ b/packages/website/docs/Features/Distributions.mdx @@ -0,0 +1,258 @@ +--- +title: "Creating Distributions" +sidebar_position: 8 +--- + +import TOCInline from "@theme/TOCInline"; +import { SquiggleEditor } from "../../src/components/SquiggleEditor"; +import Admonition from "@theme/Admonition"; +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + + + +## To + +`(5thPercentile: float) to (95thPercentile: float)` +`to(5thPercentile: float, 95thPercentile: float)` + +The `to` function is an easy way to generate simple distributions using predicted _5th_ and _95th_ percentiles. + +If both values are above zero, a `lognormal` distribution is used. If not, a `normal` distribution is used. + + + + When `5 to 10` is entered, both numbers are positive, so it generates a + lognormal distribution with 5th and 95th percentiles at 5 and 10. + + + + `5 to 10` does the same thing as `to(5,10)`. + + + + When `-5 to 5` is entered, there's negative values, so it generates a normal + distribution. This has 5th and 95th percentiles at 5 and 10. + + + + It's very easy to generate distributions with very long tails. If this + happens, you can click the "log x scale" box to view this using a log scale. + + + + +### Arguments + +- `5thPercentile`: Float +- `95thPercentile`: Float + + +

+ "To" is a great way to generate probability distributions very + quickly from your intuitions. It's easy to write and easy to read. It's + often a good place to begin an estimate. +

+
+ + +

+ If you haven't tried{" "} + + calibration training + + , you're likely to be overconfident. We recommend doing calibration training + to get a feel for what a 90 percent confident interval feels like. +

+
+ +## Mixture + +`mixture(...distributions: Distribution[], weights?: float[])` +`mx(...distributions: Distribution[], weights?: float[])` + +The `mixture` mixes combines multiple distributions to create a mixture. You can optionally pass in a list of proportional weights. + + + + + + + + + + + + + +### Arguments + +- `distributions`: A set of distributions or floats, each passed as a paramater. Floats will be converted into Delta distributions. +- `weights`: An optional array of floats, each representing the weight of its corresponding distribution. The weights will be re-scaled to add to `1.0`. If a weights array is provided, it must be the same length as the distribution paramaters. + +### Aliases + +- `mx` + +### Special Use Cases of Mixtures + +
+ 🕐 Zero or Continuous +

+ One common reason to have mixtures of continous and discrete distributions is to handle the special case of 0. + Say I want to model the time I will spend on some upcoming assignment. I think I have an 80% chance of doing it. +

+ +

+ In this case, I have a 20% chance of spending 0 time with it. I might estimate my hours with, +

+ +
+ +
+ 🔒 Model Uncertainty Safeguarding +

+ One technique several Foretold.io users used is to combine their main guess, with a + "just-in-case distribution". This latter distribution would have very low weight, but would be + very wide, just in case they were dramatically off for some weird reason. +

+

+ One common reason to have mixtures of continous and discrete distributions is to handle the special case of 0. + Say I want to model the time I will spend on some upcoming assignment. I think I have an 80% chance of doing it. +

+ + +
+ +## Normal + +`normal(mean:float, standardDeviation:float)` + + + + + + + + + + +### Arguments + +- `mean`: Float +- `standard deviation`: Float greater than zero + +[Wikipedia entry](https://en.wikipedia.org/wiki/Normal_distribution) + +## Log-normal + +The log of `lognormal(mu, sigma)` is a normal distribution with mean `mu` and standard deviation `sigma`. + +`lognormal(mu: float, sigma: float)` + + + +### Arguments + +- `mu`: Float +- `sigma`: Float greater than zero + +[Wikipedia](https://en.wikipedia.org/wiki/Log-normal_distribution) + +An alternative format is also available. The `to` notation creates a lognormal +distribution with a 90% confidence interval between the two numbers. We add +this convenience as lognormal distributions are commonly used in practice. + + + +#### Future feature: + +Furthermore, it's also possible to create a lognormal from it's actual mean +and standard deviation, using `lognormalFromMeanAndStdDev`. + +TODO: interpreter/parser doesn't provide this in current `develop` branch + + + +#### Validity + +- `sigma > 0` +- In `x to y` notation, `x < y` + +## Uniform + +`normal(low:float, high:float)` + + + + + + + + + + +### Arguments + +- `low`: Float +- `high`: Float greater than `low` + +## Beta + +The `beta(a, b)` function creates a beta distribution with parameters `a` and `b`: + + + +#### Validity + +- `a > 0` +- `b > 0` +- Empirically, we have noticed that numerical instability arises when `a < 1` or `b < 1` + +## Exponential + +The `exponential(rate)` function creates an exponential distribution with the given +rate. + + + +#### Validity + +- `rate > 0` + +## Triangular distribution + +The `triangular(a,b,c)` function creates a triangular distribution with lower +bound `a`, mode `b` and upper bound `c`. + +#### Validity + +- `a < b < c` + + + +### Scalar (constant dist) + +Squiggle, when the context is right, automatically casts a float to a constant distribution. + +## `fromSamples` + +The last distribution constructor takes an array of samples and constructs a sample set distribution. + + + +#### Validity + +For `fromSamples(xs)`, + +- `xs.length > 5` +- Strictly every element of `xs` must be a number. diff --git a/packages/website/docs/Features/Functions.mdx b/packages/website/docs/Features/Functions.mdx index 936d8b93..ae07e189 100644 --- a/packages/website/docs/Features/Functions.mdx +++ b/packages/website/docs/Features/Functions.mdx @@ -113,31 +113,6 @@ For `fromSamples(xs)`, Here are the ways we combine distributions. -### Mixture of distributions - -The `mixture` function combines 2 or more other distributions to create a weighted -combination of the two. The first positional arguments represent the distributions -to be combined, and the last argument is how much to weigh every distribution in the -combination. - - - -It's possible to create discrete distributions using this method. - - - -As well as mixed distributions: - - - -An alias of `mixture` is `mx` - -#### Validity - -Using javascript's variable arguments notation, consider `mx(...dists, weights)`: - -- `dists.length == weights.length` - ### Addition A horizontal right shift From 92f606b09b6b7f89602be3c28e92e0887cc670df Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 30 Apr 2022 22:48:57 -0400 Subject: [PATCH 089/146] Starting to pull out distributions for more specialized documentation --- .../website/docs/Features/Distributions.mdx | 150 +++++++++++------- packages/website/docs/Features/Functions.mdx | 104 ------------ 2 files changed, 95 insertions(+), 159 deletions(-) diff --git a/packages/website/docs/Features/Distributions.mdx b/packages/website/docs/Features/Distributions.mdx index 81d8737e..0331ece1 100644 --- a/packages/website/docs/Features/Distributions.mdx +++ b/packages/website/docs/Features/Distributions.mdx @@ -26,7 +26,7 @@ If both values are above zero, a `lognormal` distribution is used. If not, a `no lognormal distribution with 5th and 95th percentiles at 5 and 10. - + `5 to 10` does the same thing as `to(5,10)`. @@ -45,7 +45,7 @@ If both values are above zero, a `lognormal` distribution is used. If not, a `no ### Arguments - `5thPercentile`: Float -- `95thPercentile`: Float +- `95thPercentile`: Float, greater than `5thPercentile`

@@ -77,10 +77,10 @@ The `mixture` mixes combines multiple distributions to create a mixture. You can - + - + @@ -137,11 +137,12 @@ mx(forecast, forecast_if_completely_wrong, [1-chance_completely_wrong, chance_co `normal(mean:float, standardDeviation:float)` +Creates a [normal distribution](https://en.wikipedia.org/wiki/Normal_distribution) with the given mean and standard deviation. - + @@ -151,13 +152,13 @@ mx(forecast, forecast_if_completely_wrong, [1-chance_completely_wrong, chance_co - `mean`: Float - `standard deviation`: Float greater than zero -[Wikipedia entry](https://en.wikipedia.org/wiki/Normal_distribution) +[Wikipedia](https://en.wikipedia.org/wiki/Normal_distribution) ## Log-normal -The log of `lognormal(mu, sigma)` is a normal distribution with mean `mu` and standard deviation `sigma`. +`lognormal(mu: float, sigma: float)` -`lognormal(mu: float, sigma: float)` +Creates a [log-normal distribution](https://en.wikipedia.org/wiki/Log-normal_distribution) with the given mu and sigma. @@ -168,85 +169,124 @@ The log of `lognormal(mu, sigma)` is a normal distribution with mean `mu` and st [Wikipedia](https://en.wikipedia.org/wiki/Log-normal_distribution) -An alternative format is also available. The `to` notation creates a lognormal -distribution with a 90% confidence interval between the two numbers. We add -this convenience as lognormal distributions are commonly used in practice. +### Argument Alternatives +`Mu` and `sigma` can be difficult to directly reason about. Because of this complexity, we recommend typically using the to syntax. - - -#### Future feature: - -Furthermore, it's also possible to create a lognormal from it's actual mean -and standard deviation, using `lognormalFromMeanAndStdDev`. - -TODO: interpreter/parser doesn't provide this in current `develop` branch - - - -#### Validity - -- `sigma > 0` -- In `x to y` notation, `x < y` +

+ ❓ Understanding mu and sigma +

+ The log of `lognormal(mu, sigma)` is a normal distribution with mean `mu` and standard deviation `sigma`. For example, these two distributions are identical: +

+ +
## Uniform -`normal(low:float, high:float)` +`uniform(low:float, high:float)` - - - - - - - - +Creates a [uniform distribution](https://en.wikipedia.org/wiki/Uniform_distribution_(continuous)) with the given low and high values. + ### Arguments - `low`: Float - `high`: Float greater than `low` + +

+ While uniform distributions are very simple to understand, we find it rare to find uncertainties that actually look like this. Before using a uniform distribution, think hard about if you are really 100% confident that the paramater will not wind up being just outside the stated boundaries. +

+ +

+ One good example of a uniform distribution uncertainty would be clear physical limitations. You might have complete complete uncertainty on what time of day an event will occur, but can say with 100% confidence it will happen between the hours of 0:00 and 24:00. +

+
+ ## Beta +``beta(alpha:float, beta:float)`` -The `beta(a, b)` function creates a beta distribution with parameters `a` and `b`: +Creates a [beta distribution](https://en.wikipedia.org/wiki/Beta_distribution) with the given `alpha` and `beta` values. For a good summary of the beta distribution, see [this explanation](https://stats.stackexchange.com/a/47782) on Stack Overflow. - + + + + + + + + + + + + + + + + + -#### Validity +### Arguments -- `a > 0` -- `b > 0` -- Empirically, we have noticed that numerical instability arises when `a < 1` or `b < 1` +- `alpha`: Float greater than zero +- `beta`: Float greater than zero + + +

+ Squiggle struggles to show beta distributions when either alpha or beta are below 1.0. This is because the tails at ~0.0 and ~1.0 are very high. Using a log scale for the y-axis helps here. +

+
+ Examples + + + + + + + + + + + + + + +
+
## Exponential -The `exponential(rate)` function creates an exponential distribution with the given -rate. +``exponential(rate:float)`` - +Creates an [exponential distribution](https://en.wikipedia.org/wiki/Exponential_distribution) with the given rate. -#### Validity + -- `rate > 0` +### Arguments +- `rate`: Float greater than zero ## Triangular distribution -The `triangular(a,b,c)` function creates a triangular distribution with lower -bound `a`, mode `b` and upper bound `c`. +``triangular(low:float, mode:float, high:float)`` + +Creates a [triangular distribution](https://en.wikipedia.org/wiki/Triangular_distribution) with the given low, mode, and high values. #### Validity -- `a < b < c` +### Arguments +- `low`: Float +- `mode`: Float greater than `low` +- `high`: Float greater than `mode` -### Scalar (constant dist) +## FromSamples -Squiggle, when the context is right, automatically casts a float to a constant distribution. - -## `fromSamples` - -The last distribution constructor takes an array of samples and constructs a sample set distribution. +Creates a sample set distribution using an array of samples. diff --git a/packages/website/docs/Features/Functions.mdx b/packages/website/docs/Features/Functions.mdx index ae07e189..38872db3 100644 --- a/packages/website/docs/Features/Functions.mdx +++ b/packages/website/docs/Features/Functions.mdx @@ -5,110 +5,6 @@ sidebar_position: 7 import { SquiggleEditor } from "../../src/components/SquiggleEditor"; -## Inventory distributions - -We provide starter distributions, computed symbolically. - -### Normal distribution - -The `normal(mean, sd)` function creates a normal distribution with the given mean -and standard deviation. - - - -#### Validity - -- `sd > 0` - -### Uniform distribution - -The `uniform(low, high)` function creates a uniform distribution between the -two given numbers. - - - -#### Validity - -- `low < high` - -### Lognormal distribution - -The `lognormal(mu, sigma)` returns the log of a normal distribution with parameters -`mu` and `sigma`. The log of `lognormal(mu, sigma)` is a normal distribution with mean `mu` and standard deviation `sigma`. - - - -An alternative format is also available. The `to` notation creates a lognormal -distribution with a 90% confidence interval between the two numbers. We add -this convenience as lognormal distributions are commonly used in practice. - - - -#### Future feature: - -Furthermore, it's also possible to create a lognormal from it's actual mean -and standard deviation, using `lognormalFromMeanAndStdDev`. - -TODO: interpreter/parser doesn't provide this in current `develop` branch - - - -#### Validity - -- `sigma > 0` -- In `x to y` notation, `x < y` - -### Beta distribution - -The `beta(a, b)` function creates a beta distribution with parameters `a` and `b`: - - - -#### Validity - -- `a > 0` -- `b > 0` -- Empirically, we have noticed that numerical instability arises when `a < 1` or `b < 1` - -### Exponential distribution - -The `exponential(rate)` function creates an exponential distribution with the given -rate. - - - -#### Validity - -- `rate > 0` - -### Triangular distribution - -The `triangular(a,b,c)` function creates a triangular distribution with lower -bound `a`, mode `b` and upper bound `c`. - -#### Validity - -- `a < b < c` - - - -### Scalar (constant dist) - -Squiggle, when the context is right, automatically casts a float to a constant distribution. - -## `fromSamples` - -The last distribution constructor takes an array of samples and constructs a sample set distribution. - - - -#### Validity - -For `fromSamples(xs)`, - -- `xs.length > 5` -- Strictly every element of `xs` must be a number. - ## Operating on distributions Here are the ways we combine distributions. From ed5b7e63f281f3c8d1b054aa55f26da00ce45f8d Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 1 May 2022 08:09:34 -0400 Subject: [PATCH 090/146] Minor cleanup --- .../website/docs/Features/Distributions.mdx | 75 +++++++++---------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/packages/website/docs/Features/Distributions.mdx b/packages/website/docs/Features/Distributions.mdx index 0331ece1..5f6a85a5 100644 --- a/packages/website/docs/Features/Distributions.mdx +++ b/packages/website/docs/Features/Distributions.mdx @@ -1,5 +1,5 @@ --- -title: "Creating Distributions" +title: "Distribution Creation" sidebar_position: 8 --- @@ -13,8 +13,8 @@ import TabItem from "@theme/TabItem"; ## To -`(5thPercentile: float) to (95thPercentile: float)` -`to(5thPercentile: float, 95thPercentile: float)` +`(5thPercentile: number) to (95thPercentile: number)` +`to(5thPercentile: number, 95thPercentile: number)` The `to` function is an easy way to generate simple distributions using predicted _5th_ and _95th_ percentiles. @@ -44,8 +44,8 @@ If both values are above zero, a `lognormal` distribution is used. If not, a `no ### Arguments -- `5thPercentile`: Float -- `95thPercentile`: Float, greater than `5thPercentile` +- `5thPercentile`: number +- `95thPercentile`: number, greater than `5thPercentile`

@@ -68,8 +68,8 @@ If both values are above zero, a `lognormal` distribution is used. If not, a `no ## Mixture -`mixture(...distributions: Distribution[], weights?: float[])` -`mx(...distributions: Distribution[], weights?: float[])` +`mixture(...distributions: Distribution[], weights?: number[])` +`mx(...distributions: Distribution[], weights?: number[])` The `mixture` mixes combines multiple distributions to create a mixture. You can optionally pass in a list of proportional weights. @@ -87,8 +87,8 @@ The `mixture` mixes combines multiple distributions to create a mixture. You can ### Arguments -- `distributions`: A set of distributions or floats, each passed as a paramater. Floats will be converted into Delta distributions. -- `weights`: An optional array of floats, each representing the weight of its corresponding distribution. The weights will be re-scaled to add to `1.0`. If a weights array is provided, it must be the same length as the distribution paramaters. +- `distributions`: A set of distributions or numbers, each passed as a paramater. Numbers will be converted into Delta distributions. +- `weights`: An optional array of numbers, each representing the weight of its corresponding distribution. The weights will be re-scaled to add to `1.0`. If a weights array is provided, it must be the same length as the distribution paramaters. ### Aliases @@ -100,7 +100,7 @@ The `mixture` mixes combines multiple distributions to create a mixture. You can

🕐 Zero or Continuous

One common reason to have mixtures of continous and discrete distributions is to handle the special case of 0. - Say I want to model the time I will spend on some upcoming assignment. I think I have an 80% chance of doing it. + Say I want to model the time I will spend on some upcoming project. I think I have an 80% chance of doing it.

@@ -120,10 +120,6 @@ mx(hours_the_project_will_take, 0, [chance_of_doing_anything, 1 - chance_of_doin "just-in-case distribution". This latter distribution would have very low weight, but would be very wide, just in case they were dramatically off for some weird reason.

-

- One common reason to have mixtures of continous and discrete distributions is to handle the special case of 0. - Say I want to model the time I will spend on some upcoming assignment. I think I have an 80% chance of doing it. -

@@ -149,29 +145,28 @@ Creates a [normal distribution](https://en.wikipedia.org/wiki/Normal_distributio ### Arguments -- `mean`: Float -- `standard deviation`: Float greater than zero +- `mean`: Number +- `standard deviation`: Number greater than zero [Wikipedia](https://en.wikipedia.org/wiki/Normal_distribution) ## Log-normal -`lognormal(mu: float, sigma: float)` +`lognormal(mu: number, sigma: number)` Creates a [log-normal distribution](https://en.wikipedia.org/wiki/Log-normal_distribution) with the given mu and sigma. +`Mu` and `sigma` can be difficult to directly reason about. Because of this complexity, we recommend typically using the to syntax instead of estimating `mu` and `sigma` directly. + ### Arguments -- `mu`: Float -- `sigma`: Float greater than zero +- `mu`: Number +- `sigma`: Number greater than zero [Wikipedia](https://en.wikipedia.org/wiki/Log-normal_distribution) -### Argument Alternatives -`Mu` and `sigma` can be difficult to directly reason about. Because of this complexity, we recommend typically using the to syntax. -
❓ Understanding mu and sigma

@@ -187,15 +182,15 @@ logOfLognormal = log(lognormal(normalMean, normalStdDev)) ## Uniform -`uniform(low:float, high:float)` +`uniform(low:number, high:number)` Creates a [uniform distribution](https://en.wikipedia.org/wiki/Uniform_distribution_(continuous)) with the given low and high values. ### Arguments -- `low`: Float -- `high`: Float greater than `low` +- `low`: Number +- `high`: Number greater than `low`

@@ -208,7 +203,7 @@ Creates a [uniform distribution](https://en.wikipedia.org/wiki/Uniform_distribut ## Beta -``beta(alpha:float, beta:float)`` +``beta(alpha:number, beta:number)`` Creates a [beta distribution](https://en.wikipedia.org/wiki/Beta_distribution) with the given `alpha` and `beta` values. For a good summary of the beta distribution, see [this explanation](https://stats.stackexchange.com/a/47782) on Stack Overflow. @@ -232,8 +227,8 @@ Creates a [beta distribution](https://en.wikipedia.org/wiki/Beta_distribution) w ### Arguments -- `alpha`: Float greater than zero -- `beta`: Float greater than zero +- `alpha`: Number greater than zero +- `beta`: Number greater than zero

@@ -260,39 +255,37 @@ Creates a [beta distribution](https://en.wikipedia.org/wiki/Beta_distribution) w ## Exponential -``exponential(rate:float)`` +``exponential(rate:number)`` Creates an [exponential distribution](https://en.wikipedia.org/wiki/Exponential_distribution) with the given rate. ### Arguments -- `rate`: Float greater than zero +- `rate`: Number greater than zero ## Triangular distribution -``triangular(low:float, mode:float, high:float)`` +``triangular(low:number, mode:number, high:number)`` Creates a [triangular distribution](https://en.wikipedia.org/wiki/Triangular_distribution) with the given low, mode, and high values. #### Validity ### Arguments -- `low`: Float -- `mode`: Float greater than `low` -- `high`: Float greater than `mode` +- `low`: Number +- `mode`: Number greater than `low` +- `high`: Number greater than `mode` ## FromSamples +``fromSamples(samples:number[])`` + Creates a sample set distribution using an array of samples. -#### Validity - -For `fromSamples(xs)`, - -- `xs.length > 5` -- Strictly every element of `xs` must be a number. +### Arguments +- `samples`: An array of at least 5 numbers. \ No newline at end of file From 18af09ab0482ef1efbdd9083417524a5cd537c55 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 1 May 2022 09:00:56 -0400 Subject: [PATCH 091/146] Added delta function to produce delta distributions --- .../rescript/Distributions/SymbolicDist/SymbolicDist.res | 6 ++++++ .../ReducerInterface_GenericDistribution.res | 6 ++++-- packages/squiggle-lang/src/rescript/Utility/E.res | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res index 997506d9..94fd42ca 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res @@ -219,6 +219,12 @@ module Uniform = { module Float = { type t = float let make = t => #Float(t) + let makeSafe = t => + if E.Float.isFinite(t) { + Ok(#Float(t)) + } else { + Error("Float must be finite") + } let pdf = (x, t: t) => x == t ? 1.0 : 0.0 let cdf = (x, t: t) => x >= t ? 1.0 : 0.0 let inv = (p, t: t) => p < t ? 0.0 : 1.0 diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index 7f5ad1eb..8092786f 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -179,10 +179,12 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option< > => { let (fnName, args) = call switch (fnName, args) { - | ("exponential" as fnName, [EvNumber(f1)]) => + | ("exponential" as fnName, [EvNumber(f)]) => SymbolicConstructors.oneFloat(fnName) - ->E.R.bind(r => r(f1)) + ->E.R.bind(r => r(f)) ->SymbolicConstructors.symbolicResultToOutput + | ("delta", [EvNumber(f)]) => + SymbolicDist.Float.makeSafe(f)->SymbolicConstructors.symbolicResultToOutput | ( ("normal" | "uniform" | "beta" | "lognormal" | "cauchy" | "to") as fnName, [EvNumber(f1), EvNumber(f2)], diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index 472c32f7..1445a80c 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -198,6 +198,7 @@ module Float = { let with3DigitsPrecision = Js.Float.toPrecisionWithPrecision(_, ~digits=3) let toFixed = Js.Float.toFixed let toString = Js.Float.toString + let isFinite = Js.Float.isFinite } module I = { From 8147c5ad60fd63e82f537eb146f951fdec0faf49 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 1 May 2022 15:04:00 -0400 Subject: [PATCH 092/146] Minor additions of delta distribution --- .../website/docs/Features/Distributions.mdx | 121 ++++++++++++------ 1 file changed, 84 insertions(+), 37 deletions(-) diff --git a/packages/website/docs/Features/Distributions.mdx b/packages/website/docs/Features/Distributions.mdx index 5f6a85a5..5d840ee0 100644 --- a/packages/website/docs/Features/Distributions.mdx +++ b/packages/website/docs/Features/Distributions.mdx @@ -134,6 +134,7 @@ mx(forecast, forecast_if_completely_wrong, [1-chance_completely_wrong, chance_co `normal(mean:number, standardDeviation:number)` Creates a [normal distribution](https://en.wikipedia.org/wiki/Normal_distribution) with the given mean and standard deviation. + @@ -152,7 +153,7 @@ Creates a [normal distribution](https://en.wikipedia.org/wiki/Normal_distributio ## Log-normal -`lognormal(mu: number, sigma: number)` +`lognormal(mu: number, sigma: number)` Creates a [log-normal distribution](https://en.wikipedia.org/wiki/Log-normal_distribution) with the given mu and sigma. @@ -168,23 +169,28 @@ Creates a [log-normal distribution](https://en.wikipedia.org/wiki/Log-normal_dis [Wikipedia](https://en.wikipedia.org/wiki/Log-normal_distribution)

- ❓ Understanding mu and sigma + + ❓ Understanding mu and sigma +

- The log of `lognormal(mu, sigma)` is a normal distribution with mean `mu` and standard deviation `sigma`. For example, these two distributions are identical: + The log of `lognormal(mu, sigma)` is a normal distribution with mean `mu` + and standard deviation `sigma`. For example, these two distributions are + identical:

- + />
## Uniform `uniform(low:number, high:number)` -Creates a [uniform distribution](https://en.wikipedia.org/wiki/Uniform_distribution_(continuous)) with the given low and high values. +Creates a [uniform distribution]() with the given low and high values. + ### Arguments @@ -194,16 +200,52 @@ Creates a [uniform distribution](https://en.wikipedia.org/wiki/Uniform_distribut

- While uniform distributions are very simple to understand, we find it rare to find uncertainties that actually look like this. Before using a uniform distribution, think hard about if you are really 100% confident that the paramater will not wind up being just outside the stated boundaries. + While uniform distributions are very simple to understand, we find it rare + to find uncertainties that actually look like this. Before using a uniform + distribution, think hard about if you are really 100% confident that the + paramater will not wind up being just outside the stated boundaries.

- +

- One good example of a uniform distribution uncertainty would be clear physical limitations. You might have complete complete uncertainty on what time of day an event will occur, but can say with 100% confidence it will happen between the hours of 0:00 and 24:00. + One good example of a uniform distribution uncertainty would be clear + physical limitations. You might have complete complete uncertainty on what + time of day an event will occur, but can say with 100% confidence it will + happen between the hours of 0:00 and 24:00.

+## Delta + +`delta(value:number)` + +Creates a discrete distribution with all of its probability mass at point `value`. + +Numbers are often cast into delta distributions automatically. For example, in the function, +`mixture(1,2,normal(5,2))`, the first two arguments will get converted into delta distributions +with values at 1 and 2. Therefore, `mixture(1,2,normal(5,2))` is the same as `mixture(delta(1), delta(2),normal(5,2))` + + + + + + + + + + + + + + + + +### Arguments + +- `value`: Number + ## Beta -``beta(alpha:number, beta:number)`` + +`beta(alpha:number, beta:number)` Creates a [beta distribution](https://en.wikipedia.org/wiki/Beta_distribution) with the given `alpha` and `beta` values. For a good summary of the beta distribution, see [this explanation](https://stats.stackexchange.com/a/47782) on Stack Overflow. @@ -211,16 +253,16 @@ Creates a [beta distribution](https://en.wikipedia.org/wiki/Beta_distribution) w - + - + - + - + @@ -232,47 +274,51 @@ Creates a [beta distribution](https://en.wikipedia.org/wiki/Beta_distribution) w

- Squiggle struggles to show beta distributions when either alpha or beta are below 1.0. This is because the tails at ~0.0 and ~1.0 are very high. Using a log scale for the y-axis helps here. + Squiggle struggles to show beta distributions when either alpha or beta are + below 1.0. This is because the tails at ~0.0 and ~1.0 are very high. Using a + log scale for the y-axis helps here.

-
- Examples - - - - - - - - - - - - - - -
+
+ Examples + + + + + + + + + + + + + + +
## Exponential -``exponential(rate:number)`` +`exponential(rate:number)` Creates an [exponential distribution](https://en.wikipedia.org/wiki/Exponential_distribution) with the given rate. ### Arguments + - `rate`: Number greater than zero ## Triangular distribution -``triangular(low:number, mode:number, high:number)`` +`triangular(low:number, mode:number, high:number)` Creates a [triangular distribution](https://en.wikipedia.org/wiki/Triangular_distribution) with the given low, mode, and high values. #### Validity ### Arguments + - `low`: Number - `mode`: Number greater than `low` - `high`: Number greater than `mode` @@ -281,11 +327,12 @@ Creates a [triangular distribution](https://en.wikipedia.org/wiki/Triangular_dis ## FromSamples -``fromSamples(samples:number[])`` +`fromSamples(samples:number[])` Creates a sample set distribution using an array of samples. ### Arguments -- `samples`: An array of at least 5 numbers. \ No newline at end of file + +- `samples`: An array of at least 5 numbers. From 76b3adddc4a511a00982b467c1cc7a9e586814de Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 11:12:12 +0200 Subject: [PATCH 093/146] rename to exampleStatementY --- .../Reducer_Dispatch_BuiltInMacros_test.res | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) 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 eb6e6c0d..f0393103 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 @@ -7,7 +7,7 @@ module ExpressionT = Reducer_Expression_T let exampleExpression = eNumber(1.) let exampleExpressionY = eSymbol("y") -let exampleStatement = eLetStatement("y", eNumber(1.)) +let exampleStatementY = eLetStatement("y", eNumber(1.)) let exampleStatementX = eLetStatement("y", eSymbol("x")) let exampleStatementZ = eLetStatement("z", eSymbol("y")) @@ -16,9 +16,9 @@ testMacro([], exampleExpression, "Ok(1)") describe("bindStatement", () => { // A statement is bound by the bindings created by the previous statement - testMacro([], eBindStatement(eBindings([]), exampleStatement), "Ok((:$setBindings {} :y 1))") + testMacro([], eBindStatement(eBindings([]), exampleStatementY), "Ok((:$setBindings {} :y 1))") // Then it answers the bindings for the next statement when reduced - testMacroEval([], eBindStatement(eBindings([]), exampleStatement), "Ok({y: 1})") + testMacroEval([], eBindStatement(eBindings([]), exampleStatementY), "Ok({y: 1})") // Now let's feed a binding to see what happens testMacro( [], @@ -30,7 +30,7 @@ describe("bindStatement", () => { // When bindings from previous statement are missing the context is injected. This must be the first statement of a block testMacro( [("z", EvNumber(99.))], - eBindStatementDefault(exampleStatement), + eBindStatementDefault(exampleStatementY), "Ok((:$setBindings {z: 99} :y 1))", ) }) @@ -41,19 +41,19 @@ describe("bindExpression", () => { // When an let statement is the end expression then bindings are returned testMacro( [], - eBindExpression(eBindings([("x", EvNumber(2.))]), exampleStatement), + eBindExpression(eBindings([("x", EvNumber(2.))]), exampleStatementY), "Ok((:$exportBindings (:$setBindings {x: 2} :y 1)))", ) // Now let's reduce that expression testMacroEval( [], - eBindExpression(eBindings([("x", EvNumber(2.))]), exampleStatement), + eBindExpression(eBindings([("x", EvNumber(2.))]), exampleStatementY), "Ok({x: 2,y: 1})", ) // When bindings are missing the context is injected. This must be the first and last statement of a block testMacroEval( [("z", EvNumber(99.))], - eBindExpressionDefault(exampleStatement), + eBindExpressionDefault(exampleStatementY), "Ok({y: 1,z: 99})", ) }) @@ -63,22 +63,22 @@ describe("block", () => { testMacro([], eBlock(list{exampleExpression}), "Ok((:$$bindExpression 1))") testMacroEval([], eBlock(list{exampleExpression}), "Ok(1)") // Block with a single statement - testMacro([], eBlock(list{exampleStatement}), "Ok((:$$bindExpression (:$let :y 1)))") - testMacroEval([], eBlock(list{exampleStatement}), "Ok({y: 1})") + testMacro([], eBlock(list{exampleStatementY}), "Ok((:$$bindExpression (:$let :y 1)))") + testMacroEval([], eBlock(list{exampleStatementY}), "Ok({y: 1})") // Block with a statement and an expression testMacro( [], - eBlock(list{exampleStatement, exampleExpressionY}), + eBlock(list{exampleStatementY, exampleExpressionY}), "Ok((:$$bindExpression (:$$bindStatement (:$let :y 1)) :y))", ) - testMacroEval([], eBlock(list{exampleStatement, exampleExpressionY}), "Ok(1)") + testMacroEval([], eBlock(list{exampleStatementY, exampleExpressionY}), "Ok(1)") // Block with a statement and another statement testMacro( [], - eBlock(list{exampleStatement, exampleStatementZ}), + eBlock(list{exampleStatementY, exampleStatementZ}), "Ok((:$$bindExpression (:$$bindStatement (:$let :y 1)) (:$let :z :y)))", ) - testMacroEval([], eBlock(list{exampleStatement, exampleStatementZ}), "Ok({y: 1,z: 1})") + testMacroEval([], eBlock(list{exampleStatementY, exampleStatementZ}), "Ok({y: 1,z: 1})") // Block inside a block testMacro( [], From e262f76d9852715290284cc611b37c3fdf4c4a60 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 11:20:08 +0200 Subject: [PATCH 094/146] spelling --- .../Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 f0393103..7bbc43dd 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 @@ -11,7 +11,7 @@ let exampleStatementY = eLetStatement("y", eNumber(1.)) let exampleStatementX = eLetStatement("y", eSymbol("x")) let exampleStatementZ = eLetStatement("z", eSymbol("y")) -// If it is not a mactro then it is not expanded +// If it is not a macro then it is not expanded testMacro([], exampleExpression, "Ok(1)") describe("bindStatement", () => { From 6796db82b4d7e7507e228bf2bd416176e1ad6380 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 11:38:32 +0200 Subject: [PATCH 095/146] note weird distribution test --- .../ReducerInterface/ReducerInterface_Distribution_test.res | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res index 2c0cc3e6..bb330479 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res @@ -132,7 +132,8 @@ describe("parse on distribution functions", () => { testParse( ~skip=true, "normal(5,2) .- normal(5,1)", - "Ok((:$$block (:dotPow (:normal 5 2) (:normal 5 1))))", + "Ok((:$$block (:dotSubtract (:normal 5 2) (:normal 5 1))))", + // TODO: !!! returns "Ok((:$$block (:dotPow (:normal 5 2) (:normal 5 1))))" ) testParse( "normal(5,2) .* normal(5,1)", From 087596ec432570bf446117552b000de7ea9d1701 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 11:43:09 +0200 Subject: [PATCH 096/146] function trics --- .../__tests__/Reducer/Reducer_functionTricks_test.res | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res new file mode 100644 index 00000000..7b6b7097 --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -0,0 +1,6 @@ +open Jest +open Reducer_TestHelpers + +describe("function trics", () => { + testEvalToBe("1", "Ok(1)") +}) \ No newline at end of file From c0fad8c668705ab112b07dc9dd622ef8a366f3d5 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 12:10:31 +0200 Subject: [PATCH 097/146] define lambdaValue record as payload --- .../Reducer_Expression_ExpressionBuilder.res | 8 ++++---- .../Reducer_Expression_Lambda.res | 4 ++-- .../ReducerInterface_ExpressionValue.res | 16 ++++++++++------ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res index ec3a0214..989d2810 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res @@ -26,10 +26,10 @@ let eFunction = (fName: string, lispArgs: list): expression => { } let eLambda = (parameters: array, context, expr) => - BExpressionValue.EvLambda( - parameters, - context, - expr->castExpressionToInternalCode, + BExpressionValue.EvLambda({ + parameters: parameters, + context: context, + body: expr->castExpressionToInternalCode} )->BExpressionT.EValue let eNumber = aNumber => aNumber->BExpressionValue.EvNumber->BExpressionT.EValue 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 a2d795c0..675e3bc3 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 @@ -30,6 +30,6 @@ let applyParametersToLambda = ( reducer(newExpression, bindings, environment) } -let doLambdaCall = ((parameters, context, internal), args, environment, reducer) => { - applyParametersToLambda(internal, parameters, args, context, environment, reducer) +let doLambdaCall = (lambdaValue: ExpressionValue.lambdaValue, args, environment, reducer) => { + applyParametersToLambda(lambdaValue.body, lambdaValue.parameters, args, lambdaValue.context, environment, reducer) } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res index 31168425..ddf2cd48 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res @@ -15,15 +15,19 @@ type rec expressionValue = | EvBool(bool) | EvCall(string) // External function call | EvDistribution(DistributionTypes.genericDist) - | EvLambda((array, record, internalCode)) + | EvLambda(lambdaValue) | EvNumber(float) | EvRecord(record) | EvString(string) | EvSymbol(string) and record = Js.Dict.t +and externalBindings = record +and lambdaValue = { + parameters: array, + context: externalBindings, + body: internalCode, +} -@genType -type externalBindings = record @genType let defaultExternalBindings: externalBindings = Js.Dict.empty() @@ -41,8 +45,8 @@ let rec toString = aValue => } | EvBool(aBool) => Js.String.make(aBool) | EvCall(fName) => `:${fName}` - | EvLambda((parameters, _context, _internalCode)) => - `lambda(${Js.Array2.toString(parameters)}=>internal)` + | EvLambda(lambdaValue) => + `lambda(${Js.Array2.toString(lambdaValue.parameters)}=>internal code)` | EvNumber(aNumber) => Js.String.make(aNumber) | EvString(aString) => `'${aString}'` | EvSymbol(aString) => `:${aString}` @@ -65,7 +69,7 @@ let toStringWithType = aValue => | EvBool(_) => `Bool::${toString(aValue)}` | EvCall(_) => `Call::${toString(aValue)}` | EvDistribution(_) => `Distribution::${toString(aValue)}` - | EvLambda((_parameters, _context, _internalCode)) => `Lambda::${toString(aValue)}` + | EvLambda(_) => `Lambda::${toString(aValue)}` | EvNumber(_) => `Number::${toString(aValue)}` | EvRecord(_) => `Record::${toString(aValue)}` | EvString(_) => `String::${toString(aValue)}` From 1e673e54c33d078beb695de40a4e45dfcffec180 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 12:23:37 +0200 Subject: [PATCH 098/146] function tricks test defined (Sam's trials) --- .../Reducer/Reducer_functionTricks_test.res | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index 7b6b7097..69e20067 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -1,6 +1,17 @@ open Jest open Reducer_TestHelpers -describe("function trics", () => { - testEvalToBe("1", "Ok(1)") +Skip.describe("function trics", () => { + testEvalToBe("f(x,y)=x(y); f(f)", "????") + testEvalToBe("f(x)=x(y); f(f)", "????") + testEvalToBe("f(x)=x; f(f)", "????") + + testEvalToBe("f(x,y)=x(y); f(z)", "????") + testEvalToBe("f(x,y)=x(y); f(2)", "????") //prevent js error + testEvalToBe("f(x)=f(y)=2; f(2)", "????") //prevent multiple assignment + testEvalToBe("f(x)=x+1; g(x)=f(x)+1;g(2)", "????") //TODO: f is not found + testEvalToBe("y=2;g(x)=y+1;g(2)", "????") //TODO : y is not found + testEvalToBe("y=2;g(x)=inspect(y)+1", "????") //TODO : 666 + testEvalToBe("f(x,y)=x+y; f(1,2,3,4)", "????") //TODO : arity)) + testEvalToBe("f(x,y)=x+y; f(1)", "????") //TODO : arity)) }) \ No newline at end of file From c68138e5f6f8d8c8f061d6b467bf23a44a568a45 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 12:55:28 +0200 Subject: [PATCH 099/146] arity error --- .../Reducer/Reducer_functionTricks_test.res | 51 +++++++++++++----- .../rescript/Reducer/Reducer_ErrorValue.res | 7 ++- .../Reducer_Expression_ExpressionBuilder.res | 4 +- .../Reducer_Expression_Lambda.res | 53 ++++++++++++++----- .../ReducerInterface_ExpressionValue.res | 3 +- 5 files changed, 86 insertions(+), 32 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index 69e20067..23b4eaba 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -1,17 +1,42 @@ open Jest open Reducer_TestHelpers -Skip.describe("function trics", () => { - testEvalToBe("f(x,y)=x(y); f(f)", "????") - testEvalToBe("f(x)=x(y); f(f)", "????") - testEvalToBe("f(x)=x; f(f)", "????") +describe("Arity check", () => { + testEvalToBe("f(x,y) = x + y; f(1,2)", "Ok(3)") + testEvalToBe( + "f(x,y) = x + y; f(1)", + "Error(2 arguments expected. Instead 1 argument(s) were passed.)", + ) + testEvalToBe( + "f(x,y) = x + y; f(1,2,3)", + "Error(2 arguments expected. Instead 3 argument(s) were passed.)", + ) + testEvalToBe( + "f(x,y)=x+y; f(1,2,3,4)", + "Error(2 arguments expected. Instead 4 argument(s) were passed.)", + ) + testEvalToBe( + "f(x,y)=x+y; f(1)", + "Error(2 arguments expected. Instead 1 argument(s) were passed.)", + ) + testEvalToBe( + "f(x,y)=x(y); f(f)", + "Error(2 arguments expected. Instead 1 argument(s) were passed.)", + ) + testEvalToBe("f(x)=x; f(f)", "Ok(lambda(x=>internal code))") + testEvalToBe( + "f(x,y)=x(y); f(z)", + "Error(2 arguments expected. Instead 1 argument(s) were passed.)", + ) +}) - testEvalToBe("f(x,y)=x(y); f(z)", "????") - testEvalToBe("f(x,y)=x(y); f(2)", "????") //prevent js error - testEvalToBe("f(x)=f(y)=2; f(2)", "????") //prevent multiple assignment - testEvalToBe("f(x)=x+1; g(x)=f(x)+1;g(2)", "????") //TODO: f is not found - testEvalToBe("y=2;g(x)=y+1;g(2)", "????") //TODO : y is not found - testEvalToBe("y=2;g(x)=inspect(y)+1", "????") //TODO : 666 - testEvalToBe("f(x,y)=x+y; f(1,2,3,4)", "????") //TODO : arity)) - testEvalToBe("f(x,y)=x+y; f(1)", "????") //TODO : arity)) -}) \ No newline at end of file +describe("function trics", () => { + testEvalToBe("f(x)=x(y); f(f)", "Error(y is not defined)") + testEvalToBe("f(x)=x; f(f)", "Ok(lambda(x=>internal code))") + testEvalToBe("f(x)=x(y); f(z)", "Error(y is not defined)") + MySkip.testEvalToBe("f(x)=x(y); f(2)", "????") //prevent js error + MySkip.testEvalToBe("f(x)=f(y)=2; f(2)", "????") //prevent multiple assignment + MySkip.testEvalToBe("f(x)=x+1; g(x)=f(x)+1;g(2)", "????") //TODO: f is not found + MySkip.testEvalToBe("y=2;g(x)=y+1;g(2)", "????") //TODO : y is not found + MySkip.testEvalToBe("y=2;g(x)=inspect(y)+1", "????") //TODO : 666 +}) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res index 96b73fd2..b9eabe28 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res @@ -1,7 +1,9 @@ @genType type errorValue = + | REArityError(option, int, int) //TODO: Binding a lambda to a variable should record the variable name in lambda for error reporting | REArrayIndexNotFound(string, int) | REAssignmentExpected + | REDistributionError(DistributionTypes.error) | REExpressionExpected | REFunctionExpected(string) | REJavaScriptExn(option, option) // Javascript Exception @@ -9,7 +11,6 @@ type errorValue = | RERecordPropertyNotFound(string, string) | RESymbolNotFound(string) | RESyntaxError(string) - | REDistributionError(DistributionTypes.error) | RETodo(string) // To do type t = errorValue @@ -17,6 +18,10 @@ type t = errorValue @genType let errorToString = err => switch err { + | REArityError(_oFnName, arity, usedArity) => + `${Js.String.make(arity)} arguments expected. Instead ${Js.String.make( + usedArity, + )} argument(s) were passed.` | REArrayIndexNotFound(msg, index) => `${msg}: ${Js.String.make(index)}` | REAssignmentExpected => "Assignment expected" | REExpressionExpected => "Expression expected" diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res index 989d2810..3aa0fcba 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res @@ -29,8 +29,8 @@ let eLambda = (parameters: array, context, expr) => BExpressionValue.EvLambda({ parameters: parameters, context: context, - body: expr->castExpressionToInternalCode} - )->BExpressionT.EValue + body: expr->castExpressionToInternalCode, + })->BExpressionT.EValue let eNumber = aNumber => aNumber->BExpressionValue.EvNumber->BExpressionT.EValue 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 675e3bc3..55931cc7 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 @@ -1,7 +1,9 @@ module Bindings = Reducer_Expression_Bindings +module ErrorValue = Reducer_ErrorValue module ExpressionBuilder = Reducer_Expression_ExpressionBuilder module ExpressionT = Reducer_Expression_T module ExpressionValue = ReducerInterface.ExpressionValue +module Result = Belt.Result type environment = ReducerInterface_ExpressionValue.environment type expression = ExpressionT.expression @@ -11,25 +13,48 @@ type internalCode = ReducerInterface_ExpressionValue.internalCode external castInternalCodeToExpression: internalCode => expression = "%identity" +let checkArity = (lambdaValue: ExpressionValue.lambdaValue, args: list) => { + let argsLength = Belt.List.length(args) + let parametersLength = Js.Array2.length(lambdaValue.parameters) + if argsLength !== parametersLength { + ErrorValue.REArityError(None, parametersLength, argsLength)->Error + } else { + args->Ok + } +} + +let checkIfReduced = (args: list) => + args->Belt.List.reduceReverse(Ok(list{}), (rAcc, arg) => + rAcc->Result.flatMap(acc => + switch arg { + | EvSymbol(symbol) => ErrorValue.RESymbolNotFound(symbol)->Error + | _ => list{arg, ...acc}->Ok + } + ) + ) + let applyParametersToLambda = ( - internal: internalCode, - parameters: array, - args: list, - context: externalBindings, + lambdaValue: ExpressionValue.lambdaValue, + args, environment, reducer: ExpressionT.reducerFn, ): result => { - let expr = castInternalCodeToExpression(internal) - let parameterList = parameters->Belt.List.fromArray - let zippedParameterList = parameterList->Belt.List.zip(args) - let bindings = Belt.List.reduce(zippedParameterList, context->Bindings.fromExternalBindings, ( - acc, - (variable, variableValue), - ) => acc->Belt.Map.String.set(variable, variableValue)) - let newExpression = ExpressionBuilder.eBlock(list{expr}) - reducer(newExpression, bindings, environment) + checkArity(lambdaValue, args)->Result.flatMap(args => + checkIfReduced(args)->Result.flatMap(args => { + let expr = castInternalCodeToExpression(lambdaValue.body) + let parameterList = lambdaValue.parameters->Belt.List.fromArray + let zippedParameterList = parameterList->Belt.List.zip(args) + let bindings = Belt.List.reduce( + zippedParameterList, + lambdaValue.context->Bindings.fromExternalBindings, + (acc, (variable, variableValue)) => acc->Belt.Map.String.set(variable, variableValue), + ) + let newExpression = ExpressionBuilder.eBlock(list{expr}) + reducer(newExpression, bindings, environment) + }) + ) } let doLambdaCall = (lambdaValue: ExpressionValue.lambdaValue, args, environment, reducer) => { - applyParametersToLambda(lambdaValue.body, lambdaValue.parameters, args, lambdaValue.context, environment, reducer) + applyParametersToLambda(lambdaValue, args, environment, reducer) } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res index 4d6911af..5c9ee4b7 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res @@ -45,8 +45,7 @@ let rec toString = aValue => } | EvBool(aBool) => Js.String.make(aBool) | EvCall(fName) => `:${fName}` - | EvLambda(lambdaValue) => - `lambda(${Js.Array2.toString(lambdaValue.parameters)}=>internal code)` + | EvLambda(lambdaValue) => `lambda(${Js.Array2.toString(lambdaValue.parameters)}=>internal code)` | EvNumber(aNumber) => Js.String.make(aNumber) | EvString(aString) => `'${aString}'` | EvSymbol(aString) => `:${aString}` From ba104e4dfea682094ddfcfdd8e5cbb9587198d19 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 15:22:01 +0200 Subject: [PATCH 100/146] Catching unreduced values. This is not a lazy language --- .../__tests__/Reducer/Reducer_functionTricks_test.res | 5 +++-- .../Reducer/Reducer_Expression/Reducer_Expression.res | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index 23b4eaba..9e3e25c2 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -33,8 +33,9 @@ describe("Arity check", () => { describe("function trics", () => { testEvalToBe("f(x)=x(y); f(f)", "Error(y is not defined)") testEvalToBe("f(x)=x; f(f)", "Ok(lambda(x=>internal code))") - testEvalToBe("f(x)=x(y); f(z)", "Error(y is not defined)") - MySkip.testEvalToBe("f(x)=x(y); f(2)", "????") //prevent js error + testEvalToBe("f(x)=x(y); f(z)", "Error(z is not defined)") + testEvalToBe("f(x)=x(y); f(2)", "Error(y is not defined)") + MySkip.testEvalToBe("f(x)=x(1); f(2)", "????") MySkip.testEvalToBe("f(x)=f(y)=2; f(2)", "????") //prevent multiple assignment MySkip.testEvalToBe("f(x)=x+1; g(x)=f(x)+1;g(2)", "????") //TODO: f is not found MySkip.testEvalToBe("y=2;g(x)=y+1;g(2)", "????") //TODO : y is not found 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 5eeb51c7..bb201985 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 @@ -79,7 +79,12 @@ and reduceValueList = (valueList: list, environment): result< | list{EvLambda(lamdaCall), ...args} => Lambda.doLambdaCall(lamdaCall, args, environment, reduceExpression) - | _ => valueList->Belt.List.toArray->ExpressionValue.EvArray->Ok + | _ => + valueList + ->Lambda.checkIfReduced + ->Result.flatMap(reducedValueList => + reducedValueList->Belt.List.toArray->ExpressionValue.EvArray->Ok + ) } let evalUsingBindingsExpression_ = (aExpression, bindings, environment): result< From 9e41f0399f32670de196468ec17659aa73cd47e7 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 15:47:35 +0200 Subject: [PATCH 101/146] RENotAFunction --- .../__tests__/Reducer/Reducer_functionTricks_test.res | 4 ++-- .../src/rescript/Reducer/Reducer_ErrorValue.res | 2 ++ .../Reducer_Expression/Reducer_Expression_Bindings.res | 10 +++++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index 9e3e25c2..b21b14cd 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -34,8 +34,8 @@ describe("function trics", () => { testEvalToBe("f(x)=x(y); f(f)", "Error(y is not defined)") testEvalToBe("f(x)=x; f(f)", "Ok(lambda(x=>internal code))") testEvalToBe("f(x)=x(y); f(z)", "Error(z is not defined)") - testEvalToBe("f(x)=x(y); f(2)", "Error(y is not defined)") - MySkip.testEvalToBe("f(x)=x(1); f(2)", "????") + testEvalToBe("f(x)=x(y); f(2)", "Error(2 is not a function)") + testEvalToBe("f(x)=x(1); f(2)", "Error(2 is not a function)") MySkip.testEvalToBe("f(x)=f(y)=2; f(2)", "????") //prevent multiple assignment MySkip.testEvalToBe("f(x)=x+1; g(x)=f(x)+1;g(2)", "????") //TODO: f is not found MySkip.testEvalToBe("y=2;g(x)=y+1;g(2)", "????") //TODO : y is not found diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res index b9eabe28..7964c3a4 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res @@ -8,6 +8,7 @@ type errorValue = | REFunctionExpected(string) | REJavaScriptExn(option, option) // Javascript Exception | REMacroNotFound(string) + | RENotAFunction(string) | RERecordPropertyNotFound(string, string) | RESymbolNotFound(string) | RESyntaxError(string) @@ -40,6 +41,7 @@ let errorToString = err => answer } | REMacroNotFound(macro) => `Macro not found: ${macro}` + | RENotAFunction(valueString) => `${valueString} is not a function` | RERecordPropertyNotFound(msg, index) => `${msg}: ${index}` | RESymbolNotFound(symbolName) => `${symbolName} is not defined` | RESyntaxError(desc) => `Syntax Error: ${desc}` diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res index add7f614..830e93ba 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res @@ -1,3 +1,4 @@ +module ErrorValue = Reducer_ErrorValue module ExpressionT = Reducer_Expression_T module ExpressionValue = ReducerInterface.ExpressionValue module Result = Belt.Result @@ -67,7 +68,14 @@ and replaceSymbolsOnExpressionList = (bindings, list) => { } and replaceSymbolOnValue = (bindings, evValue: expressionValue) => switch evValue { - | EvSymbol(symbol) | EvCall(symbol) => + | EvSymbol(symbol) => Belt.Map.String.getWithDefault(bindings, symbol, evValue)->Ok + | EvCall(symbol) => + Belt.Map.String.getWithDefault(bindings, symbol, evValue)->checkIfCallable | _ => evValue->Ok } +and checkIfCallable = (evValue: expressionValue) => + switch evValue { + | EvCall(_) | EvLambda(_) => evValue->Ok + | _ => ErrorValue.RENotAFunction(ExpressionValue.toString(evValue))->Error + } From f5d3da4c735c63c6e761f4f2c528b1cab51afea8 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 15:54:16 +0200 Subject: [PATCH 102/146] tests --- .../__tests__/Reducer/Reducer_functionTricks_test.res | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index b21b14cd..1f5b6968 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -36,8 +36,9 @@ describe("function trics", () => { testEvalToBe("f(x)=x(y); f(z)", "Error(z is not defined)") testEvalToBe("f(x)=x(y); f(2)", "Error(2 is not a function)") testEvalToBe("f(x)=x(1); f(2)", "Error(2 is not a function)") + MySkip.testParseToBe("f(x)=f(y)=2; f(2)", "????") MySkip.testEvalToBe("f(x)=f(y)=2; f(2)", "????") //prevent multiple assignment - MySkip.testEvalToBe("f(x)=x+1; g(x)=f(x)+1;g(2)", "????") //TODO: f is not found + testEvalToBe("f(x)=x+1; g(x)=f(x)+1;g(2)", "????") //TODO: f is not found MySkip.testEvalToBe("y=2;g(x)=y+1;g(2)", "????") //TODO : y is not found MySkip.testEvalToBe("y=2;g(x)=inspect(y)+1", "????") //TODO : 666 }) From 99f5c54b781c962c97398259d094d46069e47a3e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 May 2022 14:39:48 +0000 Subject: [PATCH 103/146] :arrow_up: Bump @types/node from 17.0.30 to 17.0.31 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 17.0.30 to 17.0.31. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 4888a0a5..de0f8dea 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -30,7 +30,7 @@ "@testing-library/user-event": "^14.1.1", "@types/jest": "^27.4.0", "@types/lodash": "^4.14.182", - "@types/node": "^17.0.29", + "@types/node": "^17.0.31", "@types/react": "^18.0.3", "@types/react-dom": "^18.0.2", "@types/styled-components": "^5.1.24", diff --git a/yarn.lock b/yarn.lock index 89928253..58a6f2c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4070,10 +4070,10 @@ "@types/node" "*" form-data "^3.0.0" -"@types/node@*", "@types/node@^17.0.29", "@types/node@^17.0.5": - version "17.0.30" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.30.tgz#2c6e8512acac70815e8176aa30c38025067880ef" - integrity sha512-oNBIZjIqyHYP8VCNAV9uEytXVeXG2oR0w9lgAXro20eugRQfY002qr3CUl6BAe+Yf/z3CRjPdz27Pu6WWtuSRw== +"@types/node@*", "@types/node@^17.0.31", "@types/node@^17.0.5": + version "17.0.31" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.31.tgz#a5bb84ecfa27eec5e1c802c6bbf8139bdb163a5d" + integrity sha512-AR0x5HbXGqkEx9CadRH3EBYx/VkiUgZIhP4wvPn/+5KIsgpNoyFaRlVe0Zlx9gRtg8fA06a9tskE2MSN7TcG4Q== "@types/node@^14.0.10": version "14.18.16" From c8e50472ffaf902c24f61b723f6514f642bb2909 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 May 2022 14:40:06 +0000 Subject: [PATCH 104/146] :arrow_up: Bump ts-loader from 9.2.9 to 9.3.0 Bumps [ts-loader](https://github.com/TypeStrong/ts-loader) from 9.2.9 to 9.3.0. - [Release notes](https://github.com/TypeStrong/ts-loader/releases) - [Changelog](https://github.com/TypeStrong/ts-loader/blob/main/CHANGELOG.md) - [Commits](https://github.com/TypeStrong/ts-loader/compare/v9.2.9...v9.3.0) --- updated-dependencies: - dependency-name: ts-loader dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- packages/squiggle-lang/package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 4888a0a5..1df114cc 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -38,7 +38,7 @@ "cross-env": "^7.0.3", "react-scripts": "^5.0.1", "style-loader": "^3.3.1", - "ts-loader": "^9.2.9", + "ts-loader": "^9.3.0", "tsconfig-paths-webpack-plugin": "^3.5.2", "typescript": "^4.6.3", "web-vitals": "^2.1.4", diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 40f7e7c7..fa77db19 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -55,7 +55,7 @@ "nyc": "^15.1.0", "reanalyze": "^2.19.0", "ts-jest": "^27.1.4", - "ts-loader": "^9.2.8", + "ts-loader": "^9.3.0", "ts-node": "^10.7.0", "typescript": "^4.6.3", "webpack": "^5.72.0", diff --git a/yarn.lock b/yarn.lock index 89928253..806c746a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16806,10 +16806,10 @@ ts-jest@^27.1.4: semver "7.x" yargs-parser "20.x" -ts-loader@^9.2.8, ts-loader@^9.2.9: - version "9.2.9" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.9.tgz#0653e07fa1b4f225d0ca57a84fddbfd43d930f9e" - integrity sha512-b0+vUY2/enb0qYtDQuNlDnJ9900NTiPiJcDJ6sY7ax1CCCwXfYIqPOMm/BwW7jsF1km+Oz8W9s31HLuD+FLIMg== +ts-loader@^9.3.0: + version "9.3.0" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.3.0.tgz#980f4dbfb60e517179e15e10ed98e454b132159f" + integrity sha512-2kLLAdAD+FCKijvGKi9sS0OzoqxLCF3CxHpok7rVgCZ5UldRzH0TkbwG9XECKjBzHsAewntC5oDaI/FwKzEUog== dependencies: chalk "^4.1.0" enhanced-resolve "^5.0.0" From 946b38fa2731101585f77689f24070eaaf54a271 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 14:53:16 +0000 Subject: [PATCH 105/146] Fix Typescript build errors --- packages/squiggle-lang/package.json | 4 +- packages/squiggle-lang/src/js/index.ts | 51 ------------------- .../squiggle-lang/src/js/rescript_interop.ts | 7 ++- .../Distributions/DistributionTypes.res | 1 + .../src/rescript/TypescriptInterface.res | 2 +- 5 files changed, 8 insertions(+), 57 deletions(-) diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 40f7e7c7..67dfed03 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -4,7 +4,9 @@ "homepage": "https://squiggle-language.com", "license": "MIT", "scripts": { - "build": "rescript build -with-deps && tsc", + "build": "yarn build:rescript && yarn build:typescript", + "build:rescript": "rescript build -with-deps", + "build:typescript": "tsc", "bundle": "webpack", "start": "rescript build -w -with-deps", "clean": "rescript clean && rm -r dist", diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index abb563ed..c4c9b0d3 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -8,15 +8,6 @@ import { externalBindings, expressionValue, errorValue, - distributionError, - toPointSet, - continuousShape, - discreteShape, - distributionErrorToString, - internalCode, - mixedShape, - sampleSetDist, - symbolicDist, } from "../rescript/TypescriptInterface.gen"; export { makeSampleSetDist, @@ -46,48 +37,6 @@ export let defaultSamplingInputs: samplingParams = { xyPointLength: 10000, }; -export type result = - | { - tag: "Ok"; - value: a; - } - | { - tag: "Error"; - value: b; - }; - -export function resultMap( - r: result, - mapFn: (x: a) => b -): result { - if (r.tag === "Ok") { - return { tag: "Ok", value: mapFn(r.value) }; - } else { - return r; - } -} - -function Ok(x: a): result { - return { tag: "Ok", value: x }; -} - -type tagged = { tag: a; value: b }; - -function tag(x: a, y: b): tagged { - return { tag: x, value: y }; -} - -export type squiggleExpression = - | tagged<"symbol", string> - | tagged<"string", string> - | tagged<"call", string> - | tagged<"lambda", [string[], internalCode]> - | tagged<"array", squiggleExpression[]> - | tagged<"boolean", boolean> - | tagged<"distribution", Distribution> - | tagged<"number", number> - | tagged<"record", { [key: string]: squiggleExpression }>; - export function run( squiggleString: string, bindings?: externalBindings, diff --git a/packages/squiggle-lang/src/js/rescript_interop.ts b/packages/squiggle-lang/src/js/rescript_interop.ts index 75c6e733..45f4124b 100644 --- a/packages/squiggle-lang/src/js/rescript_interop.ts +++ b/packages/squiggle-lang/src/js/rescript_interop.ts @@ -5,10 +5,9 @@ import { genericDist, environment, symbolicDist, - recordEV, - internalCode, discreteShape, continuousShape, + lambdaValue, } from "../rescript/TypescriptInterface.gen"; import { Distribution } from "./distribution"; import { tagged, tag } from "./types"; @@ -38,7 +37,7 @@ export type rescriptExport = } | { TAG: 5; // EvLambda - _0: [string[], recordEV, internalCode]; + _0: lambdaValue; } | { TAG: 6; // EvNumber @@ -80,7 +79,7 @@ export type squiggleExpression = | tagged<"symbol", string> | tagged<"string", string> | tagged<"call", string> - | tagged<"lambda", [string[], recordEV, internalCode]> + | tagged<"lambda", lambdaValue> | tagged<"array", squiggleExpression[]> | tagged<"arraystring", string[]> | tagged<"boolean", boolean> diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res index 0d413bf4..a9151a8f 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res @@ -114,6 +114,7 @@ module DistributionOperation = { | ToFloat(#Mean) => `mean` | ToFloat(#Pdf(r)) => `pdf(${E.Float.toFixed(r)})` | ToFloat(#Sample) => `sample` + | ToFloat(#IntegralSum) => `integralSum` | ToDist(Normalize) => `normalize` | ToDist(ToPointSet) => `toPointSet` | ToDist(ToSampleSet(r)) => `toSampleSet(${E.I.toString(r)})` diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index 114dc4e6..6ebb8377 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -74,7 +74,7 @@ let errorValueToString = Reducer_ErrorValue.errorToString let distributionErrorToString = DistributionTypes.Error.toString @genType -type internalCode = ReducerInterface_ExpressionValue.internalCode +type lambdaValue = ReducerInterface_ExpressionValue.lambdaValue @genType let defaultSamplingEnv = ReducerInterface_GenericDistribution.defaultEnv From 0bc016632f396173bba84f0c3e6fea629bacdf68 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 15:36:20 +0000 Subject: [PATCH 106/146] Mobile support --- .../src/components/DistributionChart.tsx | 25 +++++++++++++++---- .../src/components/SquiggleChart.tsx | 18 ++++++++----- .../src/components/SquiggleEditor.tsx | 10 +++----- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 6bef36c7..8aaba9cb 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -6,7 +6,6 @@ import { distributionErrorToString } from "@quri/squiggle-lang"; import { createClassFromSpec } from "react-vega"; import * as chartSpecification from "../vega-specs/spec-distributions.json"; import { ErrorBox } from "./ErrorBox"; -import styled from "styled-components"; let SquiggleVegaChart = createClassFromSpec({ spec: chartSpecification as Spec, @@ -14,18 +13,34 @@ let SquiggleVegaChart = createClassFromSpec({ type DistributionChartProps = { distribution: Distribution; - width: number; + width?: number; height: number; }; export const DistributionChart: React.FC = ({ distribution, - width, height, + width, }: DistributionChartProps) => { + // This code with refs and effects is a bit messy, and it's because we were + // having a large amount of trouble getting vega charts to be responsive. This + // is the solution we ended up with + const ref = React.useRef(null); + const [actualWidth, setActualWidth] = React.useState(undefined); + + React.useEffect(() => { + // @ts-ignore + let getWidth = () => (ref.current ? ref.current.offsetWidth : 0); + + window.addEventListener("resize", () => setActualWidth(getWidth())); + + setActualWidth(getWidth()); + }, [ref.current]); + let shape = distribution.pointSet(); if (shape.tag === "Ok") { - let widthProp = width ? width - 20 : undefined; + let widthProp = width ? width - 20 : actualWidth; + console.log("widthProp", widthProp); var result = ( = ({ ); } - return result; + return
{result}
; }; diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 31cd9787..82997f44 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -52,7 +52,7 @@ let RecordKeyHeader = styled.h3``; export interface SquiggleItemProps { /** The input string for squiggle */ expression: squiggleExpression; - width: number; + width?: number; height: number; } @@ -105,7 +105,11 @@ const SquiggleItem: React.FC = ({ return ( {expression.value.map((r) => ( - + ))} ); @@ -115,7 +119,11 @@ const SquiggleItem: React.FC = ({ {Object.entries(expression.value).map(([key, r]) => ( <> {key} - + ))} @@ -144,8 +152,6 @@ export interface SquiggleChartProps { diagramStop?: number; /** If the result is a function, how many points along the function it samples */ diagramCount?: number; - /** variables declared before this expression */ - environment?: unknown; /** When the environment changes */ onChange?(expr: squiggleExpression): void; /** CSS width of the element */ @@ -171,7 +177,7 @@ export const SquiggleChart: React.FC = ({ height = 60, bindings = defaultBindings, jsImports = defaultImports, - width = NaN, + width, }: SquiggleChartProps) => { let samplingInputs: samplingParams = { sampleCount: sampleCount, diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index 2c01f72f..2997867d 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -32,16 +32,14 @@ export interface SquiggleEditorProps { diagramStop?: number; /** If the result is a function, how many points along the function it samples */ diagramCount?: number; - /** The environment, other variables that were already declared */ - environment?: unknown; /** when the environment changes. Used again for notebook magic*/ onChange?(expr: squiggleExpression): void; /** The width of the element */ width: number; /** Previous variable declarations */ - bindings: bindings; + bindings?: bindings; /** JS Imports */ - jsImports: jsImports; + jsImports?: jsImports; } const Input = styled.div` @@ -52,7 +50,7 @@ const Input = styled.div` export let SquiggleEditor: React.FC = ({ initialSquiggleString = "", - width = 500, + width, sampleCount, outputXYPoints, kernelWidth, @@ -61,7 +59,6 @@ export let SquiggleEditor: React.FC = ({ diagramStop, diagramCount, onChange, - environment, bindings = defaultBindings, jsImports = defaultImports, }: SquiggleEditorProps) => { @@ -87,7 +84,6 @@ export let SquiggleEditor: React.FC = ({ diagramStart={diagramStart} diagramStop={diagramStop} diagramCount={diagramCount} - environment={environment} onChange={onChange} bindings={bindings} jsImports={jsImports} From a542325f31ca6a40a83b0a057cf11541fda9e9ca Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 15:59:37 +0000 Subject: [PATCH 107/146] A simple showTypes prop --- .../src/components/SquiggleChart.tsx | 82 +++++++++++++------ .../src/components/SquiggleEditor.tsx | 4 + 2 files changed, 60 insertions(+), 26 deletions(-) diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 699a7e28..4297f032 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -33,18 +33,29 @@ const variableBox = { `, }; -export const VariableBox: React.FC<{ +interface VariableBoxProps { heading: string; children: React.ReactNode; -}> = ({ heading = "Error", children }) => { - return ( - - -

{heading}

-
- {children} -
- ); + showTypes?: boolean; +} + +export const VariableBox: React.FC = ({ + heading = "Error", + children, + showTypes = false, +}: VariableBoxProps) => { + if (showTypes) { + return ( + + +

{heading}

+
+ {children} +
+ ); + } else { + return <>{children}; + } }; let RecordKeyHeader = styled.h3``; @@ -54,25 +65,31 @@ export interface SquiggleItemProps { expression: squiggleExpression; width: number; height: number; + /** Whether to show type information */ + showTypes?: boolean; } const SquiggleItem: React.FC = ({ expression, width, height, + showTypes = false, }: SquiggleItemProps) => { switch (expression.tag) { case "number": return ( - + ); case "distribution": { let distType = expression.value.type(); return ( - - {distType === "Symbolic" ? ( + + {distType === "Symbolic" && showTypes ? ( <>
{expression.value.toString()}
@@ -89,21 +106,32 @@ const SquiggleItem: React.FC = ({ } case "string": return ( - {`"${expression.value}"`} + {`"${expression.value}"`} ); case "boolean": return ( - + {expression.value.toString()} ); case "symbol": - return {expression.value}; + return ( + + {expression.value} + + ); case "call": - return {expression.value}; + return ( + + {expression.value} + + ); case "array": return ( - + {expression.value.map((r) => ( ))} @@ -111,7 +139,7 @@ const SquiggleItem: React.FC = ({ ); case "record": return ( - + {Object.entries(expression.value).map(([key, r]) => ( <> {key} @@ -120,12 +148,6 @@ const SquiggleItem: React.FC = ({ ))} ); - default: - return ( - - {"We don't currently have a working viewer for record types."} - - ); } }; @@ -153,6 +175,8 @@ export interface SquiggleChartProps { bindings?: bindings; /** JS imported parameters */ jsImports?: jsImports; + /** Whether to show type information about returns, default false */ + showTypes?: boolean; } const ChartWrapper = styled.div` @@ -170,6 +194,7 @@ export const SquiggleChart: React.FC = ({ bindings = defaultBindings, jsImports = defaultImports, width = NaN, + showTypes = false, }: SquiggleChartProps) => { let samplingInputs: samplingParams = { sampleCount: sampleCount, @@ -186,7 +211,12 @@ export const SquiggleChart: React.FC = ({ let expression = expressionResult.value; onChange(expression); internal = ( - + ); } else { internal = ( diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index 23686a4f..2b546574 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -40,6 +40,8 @@ export interface SquiggleEditorProps { bindings?: bindings; /** JS Imports */ jsImports?: jsImports; + /** Whether to show detail about types of the returns, default false */ + showTypes?: boolean; } const Input = styled.div` @@ -61,6 +63,7 @@ export let SquiggleEditor: React.FC = ({ onChange, bindings = defaultBindings, jsImports = defaultImports, + showTypes = false, }: SquiggleEditorProps) => { let [expression, setExpression] = React.useState(initialSquiggleString); return ( @@ -87,6 +90,7 @@ export let SquiggleEditor: React.FC = ({ onChange={onChange} bindings={bindings} jsImports={jsImports} + showTypes={showTypes} /> ); From 5a0b436932b68673181d73d8373e229d04e97c1c Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 17:52:59 +0200 Subject: [PATCH 108/146] No 666 --- .../Reducer/Reducer_functionTricks_test.res | 22 +++++++++++++++---- .../Reducer_Dispatch_BuiltInMacros.res | 7 +----- .../Reducer_Expression/Reducer_Expression.res | 6 +++-- .../Reducer_Expression_Bindings.res | 3 +++ 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index 1f5b6968..e5808701 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -30,15 +30,29 @@ describe("Arity check", () => { ) }) -describe("function trics", () => { +describe("symbol not defined", () => { testEvalToBe("f(x)=x(y); f(f)", "Error(y is not defined)") testEvalToBe("f(x)=x; f(f)", "Ok(lambda(x=>internal code))") testEvalToBe("f(x)=x(y); f(z)", "Error(z is not defined)") testEvalToBe("f(x)=x(y); f(2)", "Error(2 is not a function)") testEvalToBe("f(x)=x(1); f(2)", "Error(2 is not a function)") - MySkip.testParseToBe("f(x)=f(y)=2; f(2)", "????") - MySkip.testEvalToBe("f(x)=f(y)=2; f(2)", "????") //prevent multiple assignment - testEvalToBe("f(x)=x+1; g(x)=f(x)+1;g(2)", "????") //TODO: f is not found +}) + +Only.describe("call and bindings", () => { + testEvalToBe("f(x)=x+1", "Ok({f: lambda(x=>internal code)})") + testEvalToBe("f(x)=x+1; f(1)", "Ok(2)") + testEvalToBe("f=1;y=2", "Ok({f: 1,y: 2})") + testEvalToBe("f(x)=x+1; y=f(1)", "Ok({f: lambda(x=>internal code),y: 2})") + testEvalToBe("f(x)=x+1; y=f(1); f(1)", "Ok(2)") + testEvalToBe("f(x)=x+1; y=f(1); z=f(1)", "Ok({f: lambda(x=>internal code),y: 2,z: 2})") + testEvalToBe("f(x)=x+1; g(x)=f(x)+1", "Ok({f: lambda(x=>internal code),g: lambda(x=>internal code)})") //TODO: f is not found + MyOnly.testEvalToBe("f(x)=x+1; g(x)=f(x)+1; y=g(2)", "????") //TODO: f is not found + MySkip.testEvalToBe("f(x)=x+1; g(x)=f(x)+1; g(2)", "????") //TODO: f is not found +}) + +Skip.describe("function trics", () => { + MySkip.testParseToBe("f(x)=f(y)=2; f(2)", "????") // TODO: No multiple assignment + MySkip.testEvalToBe("f(x)=f(y)=2; f(2)", "????") // TODO: No multiple assignment MySkip.testEvalToBe("y=2;g(x)=y+1;g(2)", "????") //TODO : y is not found MySkip.testEvalToBe("y=2;g(x)=inspect(y)+1", "????") //TODO : 666 }) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index f3f6d8c3..2b6ef13f 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -41,12 +41,7 @@ let dispatchMacroCall = ( let doBindExpression = (bindingExpr: expression, statement: expression, environment) => switch statement { | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), symbolExpr, statement}) => { - let rExternalBindingsValue = reduceExpression( - bindingExpr, - Belt.Map.String.fromArray([("x", ExpressionValue.EvNumber(666.))]), - // bindingsToHandDown, - environment, - ) + let rExternalBindingsValue = reduceExpression(bindingExpr, bindings, environment) rExternalBindingsValue->Result.flatMap(externalBindingsValue => { let newBindings = Bindings.fromValue(externalBindingsValue) 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 bb201985..c98da3a8 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 @@ -33,7 +33,9 @@ let rec reduceExpression = (expression: t, bindings: T.bindings, environment: en expressionValue, 'e, > => - switch expression { + { + Js.log(`reduce: ${T.toString(expression)} bindings: ${bindings->Bindings.toString}`) + switch expression { | T.EValue(value) => value->Ok | T.EList(list) => switch list { @@ -45,7 +47,7 @@ let rec reduceExpression = (expression: t, bindings: T.bindings, environment: en } | _ => reduceExpressionList(list, bindings, environment) } - } + }} and reduceExpressionList = ( expressions: list, diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res index 830e93ba..18d17af2 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res @@ -79,3 +79,6 @@ and checkIfCallable = (evValue: expressionValue) => | EvCall(_) | EvLambda(_) => evValue->Ok | _ => ErrorValue.RENotAFunction(ExpressionValue.toString(evValue))->Error } + +let toString = (bindings: ExpressionT.bindings) => + bindings->toExternalBindings->ExpressionValue.EvRecord->ExpressionValue.toString From 213808d3aa6ebb1e825470a2a027256b44f97a43 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 16:59:54 +0000 Subject: [PATCH 109/146] Using useSize size to size charts to make them usable --- packages/components/package.json | 1 + .../src/components/DistributionChart.tsx | 40 ++--- .../src/components/SquiggleChart.tsx | 4 +- yarn.lock | 150 +++++++++++++++++- 4 files changed, 163 insertions(+), 32 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 4888a0a5..f3ce1c3f 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -9,6 +9,7 @@ "react": "^18.1.0", "react-ace": "^10.1.0", "react-dom": "^18.1.0", + "react-use": "^17.3.2", "react-vega": "^7.5.0", "styled-components": "^5.3.5", "vega": "^5.22.1", diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 8aaba9cb..e2e92591 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -6,6 +6,7 @@ import { distributionErrorToString } from "@quri/squiggle-lang"; import { createClassFromSpec } from "react-vega"; import * as chartSpecification from "../vega-specs/spec-distributions.json"; import { ErrorBox } from "./ErrorBox"; +import { useSize } from 'react-use'; let SquiggleVegaChart = createClassFromSpec({ spec: chartSpecification as Spec, @@ -22,39 +23,28 @@ export const DistributionChart: React.FC = ({ height, width, }: DistributionChartProps) => { - // This code with refs and effects is a bit messy, and it's because we were - // having a large amount of trouble getting vega charts to be responsive. This - // is the solution we ended up with - const ref = React.useRef(null); - const [actualWidth, setActualWidth] = React.useState(undefined); - React.useEffect(() => { - // @ts-ignore - let getWidth = () => (ref.current ? ref.current.offsetWidth : 0); - - window.addEventListener("resize", () => setActualWidth(getWidth())); - - setActualWidth(getWidth()); - }, [ref.current]); - - let shape = distribution.pointSet(); + const [sized, _] = useSize((size) => { + let shape = distribution.pointSet(); + let widthProp = width !== undefined ? width - 20 : size.width - 10; if (shape.tag === "Ok") { - let widthProp = width ? width - 20 : actualWidth; - console.log("widthProp", widthProp); - var result = ( + return (
- ); +
+ ); } else { - var result = ( - - {distributionErrorToString(shape.value)} - - ); + return (
+ + {distributionErrorToString(shape.value)} + +
+ ) } - return
{result}
; + }) + return sized; }; diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 82997f44..652db5cb 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -107,7 +107,7 @@ const SquiggleItem: React.FC = ({ {expression.value.map((r) => ( ))} @@ -121,7 +121,7 @@ const SquiggleItem: React.FC = ({ {key} diff --git a/yarn.lock b/yarn.lock index 89928253..5361a2f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4025,6 +4025,11 @@ jest-matcher-utils "^27.0.0" pretty-format "^27.0.0" +"@types/js-cookie@^2.2.6": + version "2.2.7" + resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.7.tgz#226a9e31680835a6188e887f3988e60c04d3f6a3" + integrity sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA== + "@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" @@ -4180,10 +4185,10 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^16.9.19", "@types/react@^18.0.1", "@types/react@^18.0.3": - version "18.0.8" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.8.tgz#a051eb380a9fbcaa404550543c58e1cf5ce4ab87" - integrity sha512-+j2hk9BzCOrrOSJASi5XiOyBbERk9jG5O73Ya4M0env5Ixi6vUNli4qy994AINcEF+1IEHISYFfIT4zwr++LKw== +"@types/react@*", "@types/react@17.0.43", "@types/react@^16.9.19", "@types/react@^18.0.3": + version "17.0.43" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.43.tgz#4adc142887dd4a2601ce730bc56c3436fdb07a55" + integrity sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -4721,6 +4726,11 @@ resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.1.tgz#0de2875ac31b46b6c5bb1ae0a7d7f0ba5678dffe" integrity sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw== +"@xobotyi/scrollbar-width@^1.9.5": + version "1.9.5" + resolved "https://registry.yarnpkg.com/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz#80224a6919272f405b87913ca13b92929bdf3c4d" + integrity sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ== + "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -6991,6 +7001,14 @@ css-has-pseudo@^3.0.4: dependencies: postcss-selector-parser "^6.0.9" +css-in-js-utils@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz#3b472b398787291b47cfe3e44fecfdd9e914ba99" + integrity sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA== + dependencies: + hyphenate-style-name "^1.0.2" + isobject "^3.0.1" + css-loader@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" @@ -7247,7 +7265,7 @@ csstype@^2.5.7: resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.20.tgz#9229c65ea0b260cf4d3d997cb06288e36a8d6dda" integrity sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA== -csstype@^3.0.2: +csstype@^3.0.2, csstype@^3.0.6: version "3.0.11" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33" integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw== @@ -8662,6 +8680,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fast-shallow-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz#d4dcaf6472440dcefa6f88b98e3251e27f25628b" + integrity sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw== + fast-url-parser@1.1.3, fast-url-parser@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" @@ -8674,6 +8697,11 @@ fastest-levenshtein@^1.0.12: resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== +fastest-stable-stringify@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz#3757a6774f6ec8de40c4e86ec28ea02417214c76" + integrity sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q== + fastq@^1.6.0: version "1.13.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" @@ -9881,6 +9909,11 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +hyphenate-style-name@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d" + integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ== + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -10037,6 +10070,13 @@ inline-style-parser@0.1.1: resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== +inline-style-prefixer@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-6.0.1.tgz#c5c0e43ba8831707afc5f5bbfd97edf45c1fa7ae" + integrity sha512-AsqazZ8KcRzJ9YPN1wMH2aNM7lkWQ8tSPrW5uDk1ziYwiAPWSZnUsC7lfZq+BDqLqz0B4Pho5wscWcJzVvRzDQ== + dependencies: + css-in-js-utils "^2.0.0" + internal-slot@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" @@ -11163,6 +11203,11 @@ joi@^17.6.0: "@sideway/formula" "^3.0.0" "@sideway/pinpoint" "^2.0.0" +js-cookie@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" + integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== + js-string-escape@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" @@ -12183,6 +12228,20 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== +nano-css@^5.3.1: + version "5.3.4" + resolved "https://registry.yarnpkg.com/nano-css/-/nano-css-5.3.4.tgz#40af6a83a76f84204f346e8ccaa9169cdae9167b" + integrity sha512-wfcviJB6NOxDIDfr7RFn/GlaN7I/Bhe4d39ZRCJ3xvZX60LVe2qZ+rDqM49nm4YT81gAjzS+ZklhKP/Gnfnubg== + dependencies: + css-tree "^1.1.2" + csstype "^3.0.6" + fastest-stable-stringify "^2.0.2" + inline-style-prefixer "^6.0.0" + rtl-css-js "^1.14.0" + sourcemap-codec "^1.4.8" + stacktrace-js "^2.0.2" + stylis "^4.0.6" + nanoid@^3.1.23, nanoid@^3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" @@ -14778,6 +14837,31 @@ react-textarea-autosize@^8.3.0, react-textarea-autosize@^8.3.2: use-composed-ref "^1.0.0" use-latest "^1.0.0" +react-universal-interface@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/react-universal-interface/-/react-universal-interface-0.6.2.tgz#5e8d438a01729a4dbbcbeeceb0b86be146fe2b3b" + integrity sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw== + +react-use@^17.3.2: + version "17.3.2" + resolved "https://registry.yarnpkg.com/react-use/-/react-use-17.3.2.tgz#448abf515f47c41c32455024db28167cb6e53be8" + integrity sha512-bj7OD0/1wL03KyWmzFXAFe425zziuTf7q8olwCYBfOeFHY1qfO1FAMjROQLsLZYwG4Rx63xAfb7XAbBrJsZmEw== + dependencies: + "@types/js-cookie" "^2.2.6" + "@xobotyi/scrollbar-width" "^1.9.5" + copy-to-clipboard "^3.3.1" + fast-deep-equal "^3.1.3" + fast-shallow-equal "^1.0.0" + js-cookie "^2.2.1" + nano-css "^5.3.1" + react-universal-interface "^0.6.2" + resize-observer-polyfill "^1.5.1" + screenfull "^5.1.0" + set-harmonic-interval "^1.0.1" + throttle-debounce "^3.0.1" + ts-easing "^0.2.0" + tslib "^2.1.0" + react-vega@^7.5.0: version "7.5.0" resolved "https://registry.yarnpkg.com/react-vega/-/react-vega-7.5.0.tgz#b9726d4fd7f35299d417d340935e093bf4bed558" @@ -15335,6 +15419,13 @@ rsvp@^4.8.4: resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== +rtl-css-js@^1.14.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/rtl-css-js/-/rtl-css-js-1.15.0.tgz#680ed816e570a9ebccba9e1cd0f202c6a8bb2dc0" + integrity sha512-99Cu4wNNIhrI10xxUaABHsdDqzalrSRTie4GeCmbGVuehm4oj+fIy8fTzB+16pmKe8Bv9rl+hxIBez6KxExTew== + dependencies: + "@babel/runtime" "^7.1.2" + rtl-detect@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/rtl-detect/-/rtl-detect-1.0.4.tgz#40ae0ea7302a150b96bc75af7d749607392ecac6" @@ -15496,6 +15587,11 @@ schema-utils@^4.0.0: ajv-formats "^2.1.1" ajv-keywords "^5.0.0" +screenfull@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.2.0.tgz#6533d524d30621fc1283b9692146f3f13a93d1ba" + integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA== + scroll-into-view-if-needed@^2.2.25: version "2.2.29" resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.29.tgz#551791a84b7e2287706511f8c68161e4990ab885" @@ -15669,6 +15765,11 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= +set-harmonic-interval@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz#e1773705539cdfb80ce1c3d99e7f298bb3995249" + integrity sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g== + set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" @@ -15900,6 +16001,11 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== +source-map@0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= + source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" @@ -16024,6 +16130,13 @@ stable@^0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== +stack-generator@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36" + integrity sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q== + dependencies: + stackframe "^1.1.1" + stack-utils@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" @@ -16036,6 +16149,23 @@ stackframe@^1.1.1: resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.1.tgz#1033a3473ee67f08e2f2fc8eba6aef4f845124e1" integrity sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg== +stacktrace-gps@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz#7688dc2fc09ffb3a13165ebe0dbcaf41bcf0c69a" + integrity sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg== + dependencies: + source-map "0.5.6" + stackframe "^1.1.1" + +stacktrace-js@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.2.tgz#4ca93ea9f494752d55709a081d400fdaebee897b" + integrity sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg== + dependencies: + error-stack-parser "^2.0.6" + stack-generator "^2.0.5" + stacktrace-gps "^3.0.4" + state-toggle@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" @@ -16348,6 +16478,11 @@ stylehacks@^5.1.0: browserslist "^4.16.6" postcss-selector-parser "^6.0.4" +stylis@^4.0.6: + version "4.1.1" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.1.tgz#e46c6a9bbf7c58db1e65bb730be157311ae1fe12" + integrity sha512-lVrM/bNdhVX2OgBFNa2YJ9Lxj7kPzylieHd3TNjuGE0Re9JB7joL5VUKOVH1kdNNJTgGPpT8hmwIAPLaSyEVFQ== + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -16792,6 +16927,11 @@ ts-dedent@^2.0.0: resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== +ts-easing@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ts-easing/-/ts-easing-0.2.0.tgz#c8a8a35025105566588d87dbda05dd7fbfa5a4ec" + integrity sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ== + ts-jest@^27.1.4: version "27.1.4" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.4.tgz#84d42cf0f4e7157a52e7c64b1492c46330943e00" From 8452995c31ef0c34600cdfb7efe990dd2cbb615c Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 17:01:09 +0000 Subject: [PATCH 110/146] Lint components --- .../src/components/DistributionChart.tsx | 47 ++++++++++--------- .../src/components/SquiggleChart.tsx | 2 +- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index e2e92591..4ff4d9fd 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -6,7 +6,7 @@ import { distributionErrorToString } from "@quri/squiggle-lang"; import { createClassFromSpec } from "react-vega"; import * as chartSpecification from "../vega-specs/spec-distributions.json"; import { ErrorBox } from "./ErrorBox"; -import { useSize } from 'react-use'; +import { useSize } from "react-use"; let SquiggleVegaChart = createClassFromSpec({ spec: chartSpecification as Spec, @@ -23,28 +23,29 @@ export const DistributionChart: React.FC = ({ height, width, }: DistributionChartProps) => { - const [sized, _] = useSize((size) => { - let shape = distribution.pointSet(); - let widthProp = width !== undefined ? width - 20 : size.width - 10; - if (shape.tag === "Ok") { - return (
- -
+ let shape = distribution.pointSet(); + let widthProp = width !== undefined ? width - 20 : size.width - 10; + if (shape.tag === "Ok") { + return ( +
+ +
); - } else { - return (
- - {distributionErrorToString(shape.value)} - -
- ) - } - }) - return sized; + } else { + return ( +
+ + {distributionErrorToString(shape.value)} + +
+ ); + } + }); + return sized; }; diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 652db5cb..db8e12c2 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -121,7 +121,7 @@ const SquiggleItem: React.FC = ({ {key} From c5c65f5bc7d18f768588ff265efdf2bbc00dcb24 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 17:14:16 +0000 Subject: [PATCH 111/146] Update yarn.lock --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9b59e400..11bb1227 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4185,10 +4185,10 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@17.0.43", "@types/react@^16.9.19", "@types/react@^18.0.3": - version "17.0.43" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.43.tgz#4adc142887dd4a2601ce730bc56c3436fdb07a55" - integrity sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A== +"@types/react@*", "@types/react@^16.9.19", "@types/react@^18.0.1", "@types/react@^18.0.3": + version "18.0.8" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.8.tgz#a051eb380a9fbcaa404550543c58e1cf5ce4ab87" + integrity sha512-+j2hk9BzCOrrOSJASi5XiOyBbERk9jG5O73Ya4M0env5Ixi6vUNli4qy994AINcEF+1IEHISYFfIT4zwr++LKw== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" From f4085e93ad52a34cda43d50c0b6499c16bd1246a Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 18:29:59 +0000 Subject: [PATCH 112/146] Real log scales --- .../src/components/DistributionChart.tsx | 99 +++++++++++++++---- .../src/components/DistributionVegaScales.ts | 80 +++++++++++++++ .../src/vega-specs/spec-distributions.json | 69 +------------ packages/squiggle-lang/src/js/index.ts | 5 +- 4 files changed, 166 insertions(+), 87 deletions(-) create mode 100644 packages/components/src/components/DistributionVegaScales.ts diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 6bef36c7..4fe063a5 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -1,16 +1,16 @@ import * as React from "react"; import _ from "lodash"; -import type { Spec } from "vega"; import type { Distribution } from "@quri/squiggle-lang"; -import { distributionErrorToString } from "@quri/squiggle-lang"; -import { createClassFromSpec } from "react-vega"; +import { distributionErrorToString, result, shape } from "@quri/squiggle-lang"; +import { Vega, VisualizationSpec } from "react-vega"; import * as chartSpecification from "../vega-specs/spec-distributions.json"; import { ErrorBox } from "./ErrorBox"; -import styled from "styled-components"; - -let SquiggleVegaChart = createClassFromSpec({ - spec: chartSpecification as Spec, -}); +import { + linearXScale, + logXScale, + linearYScale, + expYScale, +} from "./DistributionVegaScales"; type DistributionChartProps = { distribution: Distribution; @@ -23,17 +23,30 @@ export const DistributionChart: React.FC = ({ width, height, }: DistributionChartProps) => { + let [isLogX, setLogX] = React.useState(false); + let [isExpY, setExpY] = React.useState(false); let shape = distribution.pointSet(); if (shape.tag === "Ok") { - let widthProp = width ? width - 20 : undefined; - var result = ( - - ); + let spec = buildSpec(isLogX, isExpY, shape.value); + if (spec.tag == "Ok") { + let widthProp = width ? width - 20 : undefined; + var result = ( +
+ +
+ ); + } else { + // Log scales don't work when you have points below 0 + var result = ( + {spec.value.error} + ); + } } else { var result = ( @@ -41,5 +54,55 @@ export const DistributionChart: React.FC = ({ ); } - return result; + return ( + <> + {result} +
+ + +
+ + ); +}; + +type ViewError = { heading: string; error: string }; + +function buildSpec( + isLogX: boolean, + isExpY: boolean, + shape: shape +): result { + let someBelow0 = + shape.continuous.some((x) => x.x <= 0) || + shape.discrete.some((x) => x.x <= 0); + if (!(isLogX && someBelow0)) { + return { + tag: "Ok", + value: { + ...chartSpecification, + scales: [ + isLogX ? logXScale : linearXScale, + isExpY ? expYScale : linearYScale, + ], + } as VisualizationSpec, + }; + } else { + return { + tag: "Error", + value: { + heading: "Log Viewing error", + error: + "Distribution contains values lower than or equal to 0. Cannot view", + }, + }; + } +} + +export const CheckBox = ({ label, onChange, value }) => { + return ( + + onChange(!value)} /> + + + ); }; diff --git a/packages/components/src/components/DistributionVegaScales.ts b/packages/components/src/components/DistributionVegaScales.ts new file mode 100644 index 00000000..f0c5c8f6 --- /dev/null +++ b/packages/components/src/components/DistributionVegaScales.ts @@ -0,0 +1,80 @@ +import type { LogScale, LinearScale, PowScale } from "vega"; +export let linearXScale: LinearScale = { + name: "xscale", + type: "linear", + range: "width", + zero: false, + nice: false, + domain: { + fields: [ + { + data: "con", + field: "x", + }, + { + data: "dis", + field: "x", + }, + ], + }, +}; +export let linearYScale: LinearScale = { + name: "yscale", + type: "linear", + range: "height", + zero: true, + domain: { + fields: [ + { + data: "con", + field: "y", + }, + { + data: "dis", + field: "y", + }, + ], + }, +}; + +export let logXScale: LogScale = { + name: "xscale", + type: "log", + range: "width", + zero: false, + base: 10, + nice: false, + domain: { + fields: [ + { + data: "con", + field: "x", + }, + { + data: "dis", + field: "x", + }, + ], + }, +}; + +export let expYScale: PowScale = { + name: "yscale", + type: "pow", + exponent: 0.1, + range: "height", + zero: true, + nice: false, + domain: { + fields: [ + { + data: "con", + field: "y", + }, + { + data: "dis", + field: "y", + }, + ], + }, +}; diff --git a/packages/components/src/vega-specs/spec-distributions.json b/packages/components/src/vega-specs/spec-distributions.json index 5b6ed261..5ca9576f 100644 --- a/packages/components/src/vega-specs/spec-distributions.json +++ b/packages/components/src/vega-specs/spec-distributions.json @@ -3,7 +3,6 @@ "description": "A basic area chart example", "width": 500, "height": 100, - "autosize": "fit", "padding": 5, "data": [ { @@ -13,72 +12,8 @@ "name": "dis" } ], - "signals": [ - { - "name": "xscale", - "description": "The transform of the x scale", - "value": false, - "bind": { - "input": "checkbox", - "name": "log x scale" - } - }, - { - "name": "yscale", - "description": "The transform of the y scale", - "value": false, - "bind": { - "input": "checkbox", - "name": "log y scale" - } - } - ], - "scales": [ - { - "name": "xscale", - "type": "pow", - "exponent": { - "signal": "xscale ? 0.1 : 1" - }, - "range": "width", - "zero": false, - "nice": false, - "domain": { - "fields": [ - { - "data": "con", - "field": "x" - }, - { - "data": "dis", - "field": "x" - } - ] - } - }, - { - "name": "yscale", - "type": "pow", - "exponent": { - "signal": "yscale ? 0.1 : 1" - }, - "range": "height", - "nice": true, - "zero": true, - "domain": { - "fields": [ - { - "data": "con", - "field": "y" - }, - { - "data": "dis", - "field": "y" - } - ] - } - } - ], + "signals": [], + "scales": [], "axes": [ { "orient": "bottom", diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index ce4d9428..7140cbc7 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -11,6 +11,7 @@ export { makeSampleSetDist, errorValueToString, distributionErrorToString, + distributionError } from "../rescript/TypescriptInterface.gen"; export type { samplingParams, @@ -26,9 +27,9 @@ import { convertRawToTypescript, } from "./rescript_interop"; import { result, resultMap, tag, tagged } from "./types"; -import { Distribution } from "./distribution"; +import { Distribution, shape } from "./distribution"; -export { Distribution, squiggleExpression, result, resultMap }; +export { Distribution, squiggleExpression, result, resultMap, shape }; export let defaultSamplingInputs: samplingParams = { sampleCount: 10000, From 71fc3149301736aae2945f1a3d80f21508959477 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 18:54:41 +0000 Subject: [PATCH 113/146] Hotfix playground chart Value: [0.001 to 0.01] --- packages/components/src/components/SquigglePlayground.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/components/SquigglePlayground.tsx b/packages/components/src/components/SquigglePlayground.tsx index a8ad84d5..93e1d963 100644 --- a/packages/components/src/components/SquigglePlayground.tsx +++ b/packages/components/src/components/SquigglePlayground.tsx @@ -74,7 +74,7 @@ const Display = styled.div` const Row = styled.div` display: grid; - grid-template-columns: 1fr 1fr; + grid-template-columns: 50% 50%; `; const Col = styled.div``; From 17a5f948fe1c0c9543993ea4d54286917581613a Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 18:59:52 +0000 Subject: [PATCH 114/146] Format and fix CI bugs --- packages/components/src/components/DistributionChart.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 9ba4d898..47c105c8 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -24,9 +24,9 @@ export const DistributionChart: React.FC = ({ height, width, }: DistributionChartProps) => { + let [isLogX, setLogX] = React.useState(false); + let [isExpY, setExpY] = React.useState(false); const [sized, _] = useSize((size) => { - let [isLogX, setLogX] = React.useState(false); - let [isExpY, setExpY] = React.useState(false); let shape = distribution.pointSet(); if (shape.tag === "Ok") { let spec = buildSpec(isLogX, isExpY, shape.value); From cc7004790489da2f51815174c98c98b30168348a Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 19:04:16 +0000 Subject: [PATCH 115/146] Lint js --- packages/squiggle-lang/src/js/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 7140cbc7..c884164a 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -11,7 +11,7 @@ export { makeSampleSetDist, errorValueToString, distributionErrorToString, - distributionError + distributionError, } from "../rescript/TypescriptInterface.gen"; export type { samplingParams, From 47b67a9efbab60657df787781d0cd7a3772dbe01 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 19:58:24 +0000 Subject: [PATCH 116/146] Add Patrial storybook and update partial bindings async --- .../src/components/SquiggleEditor.tsx | 44 +++++++++------- .../src/stories/SquigglePartial.stories.mdx | 51 +++++++++++++++++++ packages/squiggle-lang/src/js/index.ts | 1 + 3 files changed, 79 insertions(+), 17 deletions(-) create mode 100644 packages/components/src/stories/SquigglePartial.stories.mdx diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index 2b6cbf96..2bb5c2ac 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -164,33 +164,43 @@ export let SquigglePartial: React.FC = ({ xyPointLength: outputXYPoints, }; let [expression, setExpression] = React.useState(initialSquiggleString); - let squiggleResult = runPartial( - expression, - bindings, - samplingInputs, - jsImports - ); - if (squiggleResult.tag == "Ok") { - if (onChange) onChange(squiggleResult.value); - } + let [error, setError] = React.useState(null); + + // Runs squiggle and updates state/calls props apprropriately + let runSquiggle = (newExpression: string) => { + let squiggleResult = runPartial( + newExpression, + bindings, + samplingInputs, + jsImports + ); + if (squiggleResult.tag == "Ok") { + if (onChange) onChange(squiggleResult.value); + setError(null); + } else { + setError(errorValueToString(squiggleResult.value)); + } + }; + + // Run this once on mount, so that the next cells can get relevent values + React.useEffect(() => runSquiggle(expression), []); + return (
{ + // When the code changes, rerun squiggle and inform next cells + setExpression(x); + runSquiggle(x); + }} oneLine={true} showGutter={false} height={20} /> - {squiggleResult.tag == "Error" ? ( - - {errorValueToString(squiggleResult.value)} - - ) : ( - <> - )} + {error !== null ? {error} : <>}
); }; diff --git a/packages/components/src/stories/SquigglePartial.stories.mdx b/packages/components/src/stories/SquigglePartial.stories.mdx new file mode 100644 index 00000000..b4446402 --- /dev/null +++ b/packages/components/src/stories/SquigglePartial.stories.mdx @@ -0,0 +1,51 @@ +import { SquigglePartial, SquiggleEditor } from "../components/SquiggleEditor"; +import { useState } from "react"; +import { Canvas, Meta, Story, Props } from "@storybook/addon-docs"; + + + +export const Template = (props) => ; + +# Squiggle Partial + +A Squiggle Partial is an editor that does not return a graph to the user, but +instead returns bindings that can be used by further Squiggle Editors. + + + + {Template.bind({})} + + + + + + {(props) => { + let [bindings, setBindings] = useState({}); + return ( + <> + + + + ); + }} + + diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index ce4d9428..0b521079 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -11,6 +11,7 @@ export { makeSampleSetDist, errorValueToString, distributionErrorToString, + distributionError, } from "../rescript/TypescriptInterface.gen"; export type { samplingParams, From 7e05d6300926718d621b3ef1a7cea8fba721248b Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 20:40:15 +0000 Subject: [PATCH 117/146] Make a tooltip to restrict users from log scales --- .../src/components/DistributionChart.tsx | 126 ++++++++++-------- 1 file changed, 70 insertions(+), 56 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 47c105c8..38b96054 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import _ from "lodash"; import type { Distribution } from "@quri/squiggle-lang"; -import { distributionErrorToString, result, shape } from "@quri/squiggle-lang"; +import { distributionErrorToString } from "@quri/squiggle-lang"; import { Vega, VisualizationSpec } from "react-vega"; import * as chartSpecification from "../vega-specs/spec-distributions.json"; import { ErrorBox } from "./ErrorBox"; @@ -12,6 +12,7 @@ import { linearYScale, expYScale, } from "./DistributionVegaScales"; +import styled from "styled-components"; type DistributionChartProps = { distribution: Distribution; @@ -26,28 +27,29 @@ export const DistributionChart: React.FC = ({ }: DistributionChartProps) => { let [isLogX, setLogX] = React.useState(false); let [isExpY, setExpY] = React.useState(false); + let shape = distribution.pointSet(); const [sized, _] = useSize((size) => { - let shape = distribution.pointSet(); + var disableLog = false; if (shape.tag === "Ok") { - let spec = buildSpec(isLogX, isExpY, shape.value); - if (spec.tag == "Ok") { - let widthProp = width ? width - 20 : size.width - 10; - var result = ( -
- -
- ); - } else { - var result = ( - {spec.value.error} - ); + let massBelow0 = + shape.value.continuous.some((x) => x.x <= 0) || + shape.value.discrete.some((x) => x.x <= 0); + if (massBelow0) { + disableLog = true; } + let spec = buildVegaSpec(isLogX, isExpY); + let widthProp = width ? width - 20 : size.width - 10; + var result = ( +
+ +
+ ); } else { var result = ( @@ -59,7 +61,19 @@ export const DistributionChart: React.FC = ({ <> {result}
- + {disableLog ? ( + + ) : ( + + )}
@@ -68,44 +82,44 @@ export const DistributionChart: React.FC = ({ return sized; }; -type ViewError = { heading: string; error: string }; - -function buildSpec( - isLogX: boolean, - isExpY: boolean, - shape: shape -): result { - let someBelow0 = - shape.continuous.some((x) => x.x <= 0) || - shape.discrete.some((x) => x.x <= 0); - if (!(isLogX && someBelow0)) { - return { - tag: "Ok", - value: { - ...chartSpecification, - scales: [ - isLogX ? logXScale : linearXScale, - isExpY ? expYScale : linearYScale, - ], - } as VisualizationSpec, - }; - } else { - return { - tag: "Error", - value: { - heading: "Log Viewing error", - error: - "Distribution contains values lower than or equal to 0. Cannot view", - }, - }; - } +function buildVegaSpec(isLogX: boolean, isExpY: boolean): VisualizationSpec { + return { + ...chartSpecification, + scales: [ + isLogX ? logXScale : linearXScale, + isExpY ? expYScale : linearYScale, + ], + } as VisualizationSpec; } -export const CheckBox = ({ label, onChange, value }) => { +interface CheckBoxProps { + label: string; + onChange: (x: boolean) => void; + value: boolean; + disabled?: boolean; + tooltip?: string; +} + +const Label = styled.label<{ disabled: boolean }>` + ${(props) => props.disabled && "color: #999;"} +`; + +export const CheckBox = ({ + label, + onChange, + value, + disabled = false, + tooltip, +}: CheckBoxProps) => { return ( - - onChange(!value)} /> - + + onChange(!value)} + disabled={disabled} + /> + ); }; From 5fc829efc9f8493a5e47bc48c26209b2912d1cce Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 20:52:55 +0000 Subject: [PATCH 118/146] Refactor and shrink effect code --- .../components/src/components/SquiggleEditor.tsx | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index 2bb5c2ac..8ea70afa 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -166,10 +166,9 @@ export let SquigglePartial: React.FC = ({ let [expression, setExpression] = React.useState(initialSquiggleString); let [error, setError] = React.useState(null); - // Runs squiggle and updates state/calls props apprropriately - let runSquiggle = (newExpression: string) => { + React.useEffect(() => { let squiggleResult = runPartial( - newExpression, + expression, bindings, samplingInputs, jsImports @@ -180,21 +179,14 @@ export let SquigglePartial: React.FC = ({ } else { setError(errorValueToString(squiggleResult.value)); } - }; - - // Run this once on mount, so that the next cells can get relevent values - React.useEffect(() => runSquiggle(expression), []); + }, [expression]); return (
{ - // When the code changes, rerun squiggle and inform next cells - setExpression(x); - runSquiggle(x); - }} + onChange={setExpression} oneLine={true} showGutter={false} height={20} From 06c479b54769d46cc691ed2b1717f44786a75c21 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 20:54:33 +0000 Subject: [PATCH 119/146] Make error message more descriptive --- packages/components/src/components/DistributionChart.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 38b96054..f43b642c 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -68,7 +68,7 @@ export const DistributionChart: React.FC = ({ onChange={setLogX} disabled={true} tooltip={ - "Your distribution has mass lower than or equal to 0, cannot use log scale" + "Your distribution has mass lower than or equal to 0. Log only works on strictly positive values." } /> ) : ( From 0d14216e9feb89a448a2f4f788a221a4103a026f Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 21:05:59 +0000 Subject: [PATCH 120/146] Refactor and rename lambda in partial --- packages/components/src/components/SquiggleEditor.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index 8ea70afa..9a453ab8 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -166,7 +166,7 @@ export let SquigglePartial: React.FC = ({ let [expression, setExpression] = React.useState(initialSquiggleString); let [error, setError] = React.useState(null); - React.useEffect(() => { + let runSquiggleAndUpdateBindings = () => { let squiggleResult = runPartial( expression, bindings, @@ -179,7 +179,9 @@ export let SquigglePartial: React.FC = ({ } else { setError(errorValueToString(squiggleResult.value)); } - }, [expression]); + }; + + React.useEffect(runSquiggleAndUpdateBindings, [expression]); return (
From 6a3b35eb4aa366331a1fd6b413ca717b10a21cb2 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 18:44:35 +0200 Subject: [PATCH 121/146] fixed function f not bound --- .../Reducer/Reducer_TestMacroHelpers.res | 5 +- .../Reducer/Reducer_functionTricks_test.res | 26 ++++-- .../Reducer_Dispatch_BuiltInMacros.res | 85 ++++++++++++++----- .../Reducer_Expression/Reducer_Expression.res | 10 +-- .../Reducer_ExpressionWithContext.res | 45 ++++++++++ .../Reducer_Expression_Bindings.res | 11 +-- .../Reducer_Expression_ExpressionBuilder.res | 8 +- .../Reducer_Expression_Macro.res | 13 ++- 8 files changed, 158 insertions(+), 45 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res index af88cac4..330f7da0 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res @@ -1,10 +1,11 @@ open Jest open Expect -module Macro = Reducer_Expression_Macro module Bindings = Reducer_Expression_Bindings module Expression = Reducer_Expression module ExpressionValue = ReducerInterface_ExpressionValue +module ExpressionWithContext = Reducer_ExpressionWithContext +module Macro = Reducer_Expression_Macro module T = Reducer_Expression_T let testMacro_ = ( @@ -21,7 +22,7 @@ let testMacro_ = ( ExpressionValue.defaultEnvironment, Expression.reduceExpression, ) - ->T.toStringResult + ->ExpressionWithContext.toStringResult ->expect ->toEqual(expectedCode) ) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index e5808701..f134c309 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -39,15 +39,27 @@ describe("symbol not defined", () => { }) Only.describe("call and bindings", () => { - testEvalToBe("f(x)=x+1", "Ok({f: lambda(x=>internal code)})") - testEvalToBe("f(x)=x+1; f(1)", "Ok(2)") + testEvalToBe("f(x)=x+1", "Ok({f: lambda(x=>internal code)})") + testEvalToBe("f(x)=x+1; f(1)", "Ok(2)") testEvalToBe("f=1;y=2", "Ok({f: 1,y: 2})") - testEvalToBe("f(x)=x+1; y=f(1)", "Ok({f: lambda(x=>internal code),y: 2})") - testEvalToBe("f(x)=x+1; y=f(1); f(1)", "Ok(2)") + testEvalToBe("f(x)=x+1; y=f(1)", "Ok({f: lambda(x=>internal code),y: 2})") + testEvalToBe("f(x)=x+1; y=f(1); f(1)", "Ok(2)") testEvalToBe("f(x)=x+1; y=f(1); z=f(1)", "Ok({f: lambda(x=>internal code),y: 2,z: 2})") - testEvalToBe("f(x)=x+1; g(x)=f(x)+1", "Ok({f: lambda(x=>internal code),g: lambda(x=>internal code)})") //TODO: f is not found - MyOnly.testEvalToBe("f(x)=x+1; g(x)=f(x)+1; y=g(2)", "????") //TODO: f is not found - MySkip.testEvalToBe("f(x)=x+1; g(x)=f(x)+1; g(2)", "????") //TODO: f is not found + testEvalToBe( + "f(x)=x+1; g(x)=f(x)+1", + "Ok({f: lambda(x=>internal code),g: lambda(x=>internal code)})", + ) + testParseToBe( + "f=99; g(x)=f; g(2)", + "Ok((:$$block (:$$block (:$let :f 99) (:$let :g (:$$lambda [x] (:$$block :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)", + "Ok({f: lambda(x=>internal code),g: lambda(x=>internal code),y: 4})", + ) + testEvalToBe("f(x)=x+1; g(x)=f(x)+1; g(2)", "Ok(4)") }) Skip.describe("function trics", () => { diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index 2b6ef13f..c106c0ff 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -6,19 +6,22 @@ module Bindings = Reducer_Expression_Bindings module ExpressionT = Reducer_Expression_T module ExpressionValue = ReducerInterface.ExpressionValue +module ExpressionWithContext = Reducer_ExpressionWithContext module Result = Belt.Result open Reducer_Expression_ExpressionBuilder -type expression = ExpressionT.expression type environment = ExpressionValue.environment type errorValue = Reducer_ErrorValue.errorValue +type expression = ExpressionT.expression +type expressionValue = ExpressionValue.expressionValue +type expressionWithContext = ExpressionWithContext.expressionWithContext let dispatchMacroCall = ( macroExpression: expression, bindings: ExpressionT.bindings, environment, reduceExpression: ExpressionT.reducerFn, -): result => { +): result => { let doBindStatement = (bindingExpr: expression, statement: expression, environment) => switch statement { | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), symbolExpr, statement}) => { @@ -26,11 +29,23 @@ let dispatchMacroCall = ( rExternalBindingsValue->Result.flatMap(externalBindingsValue => { let newBindings = Bindings.fromValue(externalBindingsValue) + + // Js.log( + // `bindStatement ${Bindings.toString(newBindings)}<==${ExpressionT.toString( + // bindingExpr, + // )} statement: $let ${ExpressionT.toString(symbolExpr)}=${ExpressionT.toString( + // statement, + // )}`, + // ) + let rNewStatement = Bindings.replaceSymbols(newBindings, statement) rNewStatement->Result.map(newStatement => - eFunction( - "$setBindings", - list{newBindings->Bindings.toExternalBindings->eRecord, symbolExpr, newStatement}, + ExpressionWithContext.withContext( + eFunction( + "$setBindings", + list{newBindings->Bindings.toExternalBindings->eRecord, symbolExpr, newStatement}, + ), + newBindings, ) ) }) @@ -38,7 +53,10 @@ let dispatchMacroCall = ( | _ => REAssignmentExpected->Error } - let doBindExpression = (bindingExpr: expression, statement: expression, environment) => + let doBindExpression = (bindingExpr: expression, statement: expression, environment): result< + expressionWithContext, + errorValue, + > => switch statement { | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), symbolExpr, statement}) => { let rExternalBindingsValue = reduceExpression(bindingExpr, bindings, environment) @@ -47,35 +65,49 @@ let dispatchMacroCall = ( let newBindings = Bindings.fromValue(externalBindingsValue) let rNewStatement = Bindings.replaceSymbols(newBindings, statement) rNewStatement->Result.map(newStatement => - eFunction( - "$exportBindings", - list{ - eFunction( - "$setBindings", - list{newBindings->Bindings.toExternalBindings->eRecord, symbolExpr, newStatement}, - ), - }, + ExpressionWithContext.withContext( + eFunction( + "$exportBindings", + list{ + eFunction( + "$setBindings", + list{ + newBindings->Bindings.toExternalBindings->eRecord, + symbolExpr, + newStatement, + }, + ), + }, + ), + newBindings, ) ) }) } | _ => { - let rExternalBindingsValue = reduceExpression(bindingExpr, bindings, environment) + let rExternalBindingsValue: result = reduceExpression( + bindingExpr, + bindings, + environment, + ) + rExternalBindingsValue->Result.flatMap(externalBindingsValue => { let newBindings = Bindings.fromValue(externalBindingsValue) let rNewStatement = Bindings.replaceSymbols(newBindings, statement) - rNewStatement + rNewStatement->Result.map(newStatement => + ExpressionWithContext.withContext(newStatement, newBindings) + ) }) } } let doBlock = (exprs: list, _bindings: ExpressionT.bindings, _environment): result< - expression, + expressionWithContext, errorValue, > => { let exprsArray = Belt.List.toArray(exprs) let maxIndex = Js.Array2.length(exprsArray) - 1 - exprsArray->Js.Array2.reducei((acc, statement, index) => + let newStatement = exprsArray->Js.Array2.reducei((acc, statement, index) => if index == 0 { if index == maxIndex { eBindExpressionDefault(statement) @@ -87,16 +119,23 @@ let dispatchMacroCall = ( } else { eBindStatement(acc, statement) } - , eSymbol("undefined block"))->Ok + , eSymbol("undefined block")) + ExpressionWithContext.noContext(newStatement)->Ok } let doLambdaDefinition = ( bindings: ExpressionT.bindings, parameters: array, lambdaDefinition: ExpressionT.expression, - ) => eLambda(parameters, bindings->Bindings.toExternalBindings, lambdaDefinition)->Ok + ) => + ExpressionWithContext.noContext( + eLambda(parameters, bindings->Bindings.toExternalBindings, lambdaDefinition), + )->Ok - let expandExpressionList = (aList, bindings: ExpressionT.bindings, environment) => + let expandExpressionList = (aList, bindings: ExpressionT.bindings, environment): result< + expressionWithContext, + errorValue, + > => switch aList { | list{ ExpressionT.EValue(EvCall("$$bindStatement")), @@ -123,11 +162,11 @@ let dispatchMacroCall = ( lambdaDefinition, } => doLambdaDefinition(bindings, parameters, lambdaDefinition) - | _ => ExpressionT.EList(aList)->Ok + | _ => ExpressionWithContext.noContext(ExpressionT.EList(aList))->Ok } switch macroExpression { | EList(aList) => expandExpressionList(aList, bindings, environment) - | _ => macroExpression->Ok + | _ => ExpressionWithContext.noContext(macroExpression)->Ok } } 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 c98da3a8..e1df1418 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 @@ -32,10 +32,9 @@ let parse = (mathJsCode: string): result => let rec reduceExpression = (expression: t, bindings: T.bindings, environment: environment): result< expressionValue, 'e, -> => - { - Js.log(`reduce: ${T.toString(expression)} bindings: ${bindings->Bindings.toString}`) - switch expression { +> => { + // Js.log(`reduce: ${T.toString(expression)} bindings: ${bindings->Bindings.toString}`) + switch expression { | T.EValue(value) => value->Ok | T.EList(list) => switch list { @@ -47,7 +46,8 @@ let rec reduceExpression = (expression: t, bindings: T.bindings, environment: en } | _ => reduceExpressionList(list, bindings, environment) } - }} + } +} and reduceExpressionList = ( expressions: list, diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res new file mode 100644 index 00000000..dacd2462 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res @@ -0,0 +1,45 @@ +module Bindings = Reducer_Expression_Bindings +module ErrorValue = Reducer_ErrorValue +module ExpressionT = Reducer_Expression_T +module ExpressionValue = ReducerInterface.ExpressionValue +module Result = Belt.Result + +type bindings = ExpressionT.bindings +type context = bindings +type environment = ExpressionValue.environment +type errorValue = Reducer_ErrorValue.errorValue +type expression = ExpressionT.expression +type expressionValue = ExpressionValue.expressionValue +type externalBindings = ReducerInterface_ExpressionValue.externalBindings +type reducerFn = ExpressionT.reducerFn + +type expressionWithContext = + | ExpressionWithContext(expression, context) + | ExpressionNoContext(expression) + +let callReducer = ( + expressionWithContext: expressionWithContext, + bindings: bindings, + environment: environment, + reducer: reducerFn, +): result => + switch expressionWithContext { + | ExpressionNoContext(expr) => reducer(expr, bindings, environment) + | ExpressionWithContext(expr, context) => reducer(expr, context, environment) + } + +let withContext = (expression, context) => ExpressionWithContext(expression, context) +let noContext = expression => ExpressionNoContext(expression) + +let toString = expressionWithContext => + switch expressionWithContext { + | ExpressionNoContext(expr) => ExpressionT.toString(expr) + | ExpressionWithContext(expr, context) => + `${ExpressionT.toString(expr)} context: ${Bindings.toString(context)}` + } + +let toStringResult = rExpressionWithContext => + switch rExpressionWithContext { + | Ok(expressionWithContext) => `Ok(${toString(expressionWithContext)})` + | Error(errorValue) => ErrorValue.errorToString(errorValue) + } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res index 18d17af2..7c0c048a 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res @@ -68,10 +68,8 @@ and replaceSymbolsOnExpressionList = (bindings, list) => { } and replaceSymbolOnValue = (bindings, evValue: expressionValue) => switch evValue { - | EvSymbol(symbol) => - Belt.Map.String.getWithDefault(bindings, symbol, evValue)->Ok - | EvCall(symbol) => - Belt.Map.String.getWithDefault(bindings, symbol, evValue)->checkIfCallable + | EvSymbol(symbol) => Belt.Map.String.getWithDefault(bindings, symbol, evValue)->Ok + | EvCall(symbol) => Belt.Map.String.getWithDefault(bindings, symbol, evValue)->checkIfCallable | _ => evValue->Ok } and checkIfCallable = (evValue: expressionValue) => @@ -80,5 +78,8 @@ and checkIfCallable = (evValue: expressionValue) => | _ => ErrorValue.RENotAFunction(ExpressionValue.toString(evValue))->Error } -let toString = (bindings: ExpressionT.bindings) => +let toString = (bindings: ExpressionT.bindings) => bindings->toExternalBindings->ExpressionValue.EvRecord->ExpressionValue.toString + +let externalBindingsToString = (externalBindings: externalBindings) => + externalBindings->ExpressionValue.EvRecord->ExpressionValue.toString diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res index 3aa0fcba..9c9f922e 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res @@ -25,12 +25,18 @@ let eFunction = (fName: string, lispArgs: list): expression => { list{fn, ...lispArgs}->BExpressionT.EList } -let eLambda = (parameters: array, context, expr) => +let eLambda = ( + parameters: array, + context: BExpressionValue.externalBindings, + expr: expression, +) => { + // Js.log(`eLambda context ${BBindings.externalBindingsToString(context)}`) BExpressionValue.EvLambda({ parameters: parameters, context: context, body: expr->castExpressionToInternalCode, })->BExpressionT.EValue +} let eNumber = aNumber => aNumber->BExpressionValue.EvNumber->BExpressionT.EValue diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res index 5ac19502..23fb70f8 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res @@ -1,17 +1,19 @@ module ExpressionT = Reducer_Expression_T module ExpressionValue = ReducerInterface.ExpressionValue +module ExpressionWithContext = Reducer_ExpressionWithContext module Result = Belt.Result type environment = ExpressionValue.environment type expression = ExpressionT.expression type expressionValue = ExpressionValue.expressionValue +type expressionWithContext = ExpressionWithContext.expressionWithContext let expandMacroCall = ( macroExpression: expression, bindings: ExpressionT.bindings, environment: environment, reduceExpression: ExpressionT.reducerFn, -): result => +): result => Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( macroExpression, bindings, @@ -30,6 +32,13 @@ let doMacroCall = ( bindings, environment, reduceExpression, - )->Result.flatMap(expression => reduceExpression(expression, bindings, environment)) + )->Result.flatMap(expressionWithContext => + ExpressionWithContext.callReducer( + expressionWithContext, + bindings, + environment, + reduceExpression, + ) + ) let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") From 490e4908e171627a88ae752de7181685858a8bb4 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 23:18:36 +0200 Subject: [PATCH 122/146] sam's monkeying --- .../Reducer/Reducer_functionTricks_test.res | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index f134c309..b425c88e 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -38,7 +38,7 @@ describe("symbol not defined", () => { testEvalToBe("f(x)=x(1); f(2)", "Error(2 is not a function)") }) -Only.describe("call and bindings", () => { +describe("call and bindings", () => { testEvalToBe("f(x)=x+1", "Ok({f: lambda(x=>internal code)})") testEvalToBe("f(x)=x+1; f(1)", "Ok(2)") testEvalToBe("f=1;y=2", "Ok({f: 1,y: 2})") @@ -62,9 +62,11 @@ Only.describe("call and bindings", () => { testEvalToBe("f(x)=x+1; g(x)=f(x)+1; g(2)", "Ok(4)") }) -Skip.describe("function trics", () => { - MySkip.testParseToBe("f(x)=f(y)=2; f(2)", "????") // TODO: No multiple assignment - MySkip.testEvalToBe("f(x)=f(y)=2; f(2)", "????") // TODO: No multiple assignment - MySkip.testEvalToBe("y=2;g(x)=y+1;g(2)", "????") //TODO : y is not found - MySkip.testEvalToBe("y=2;g(x)=inspect(y)+1", "????") //TODO : 666 +describe("function trics", () => { + testParseToBe( + "f(x)=f(y)=2; f(2)", + "Ok((:$$block (:$$block (:$let :f (:$$lambda [x] (:$$block (:$let :f (:$$lambda [y] (:$$block 2)))))) (:f 2))))") + testEvalToBe("f(x)=f(y)=2; f(2)","Ok({f: lambda(y=>internal code),x: 2})") + testEvalToBe("y=2;g(x)=y+1;g(2)", "Ok(3)") + testEvalToBe("y=2;g(x)=inspect(y)+1", "Ok({g: lambda(x=>internal code),y: 2})") }) From da8a834b7e0e6fece063259385894f9c69dd811a Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 21:33:34 +0000 Subject: [PATCH 123/146] Allows hiding controls --- .../src/components/DistributionChart.tsx | 55 ++++++++++--------- .../src/components/SquiggleChart.tsx | 8 +++ .../src/components/SquiggleEditor.tsx | 6 ++ 3 files changed, 44 insertions(+), 25 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index f43b642c..5eafecf9 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -18,27 +18,45 @@ type DistributionChartProps = { distribution: Distribution; width?: number; height: number; + /** Whether to show the user graph controls (scale etc) */ + showControls?: boolean; }; export const DistributionChart: React.FC = ({ distribution, height, width, + showControls = false, }: DistributionChartProps) => { let [isLogX, setLogX] = React.useState(false); let [isExpY, setExpY] = React.useState(false); let shape = distribution.pointSet(); const [sized, _] = useSize((size) => { - var disableLog = false; if (shape.tag === "Ok") { let massBelow0 = shape.value.continuous.some((x) => x.x <= 0) || shape.value.discrete.some((x) => x.x <= 0); - if (massBelow0) { - disableLog = true; - } let spec = buildVegaSpec(isLogX, isExpY); let widthProp = width ? width - 20 : size.width - 10; + + // Check whether we should disable the checkbox + var logCheckbox = ( + + ); + if (massBelow0) { + logCheckbox = ( + + ); + } + var result = (
= ({ height={height} actions={false} /> + {showControls && ( +
+ {logCheckbox} + +
+ )}
); } else { @@ -57,27 +81,8 @@ export const DistributionChart: React.FC = ({ ); } - return ( - <> - {result} -
- {disableLog ? ( - - ) : ( - - )} - -
- - ); + + return result; }); return sized; }; diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 3210b1d8..a9fde172 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -67,6 +67,8 @@ export interface SquiggleItemProps { height: number; /** Whether to show type information */ showTypes?: boolean; + /** Whether to show users graph controls (scale etc) */ + showControls?: boolean; } const SquiggleItem: React.FC = ({ @@ -74,6 +76,7 @@ const SquiggleItem: React.FC = ({ width, height, showTypes = false, + showControls = false, }: SquiggleItemProps) => { switch (expression.tag) { case "number": @@ -100,6 +103,7 @@ const SquiggleItem: React.FC = ({ distribution={expression.value} height={height} width={width} + showControls={showControls} /> ); @@ -185,6 +189,8 @@ export interface SquiggleChartProps { jsImports?: jsImports; /** Whether to show type information about returns, default false */ showTypes?: boolean; + /** Whether to show graph controls (scale etc)*/ + showControls?: boolean; } const ChartWrapper = styled.div` @@ -203,6 +209,7 @@ export const SquiggleChart: React.FC = ({ jsImports = defaultImports, width, showTypes = false, + showControls = false, }: SquiggleChartProps) => { let samplingInputs: samplingParams = { sampleCount: sampleCount, @@ -224,6 +231,7 @@ export const SquiggleChart: React.FC = ({ width={width} height={height} showTypes={showTypes} + showControls={showControls} /> ); } else { diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index 9a453ab8..572dbd76 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -42,6 +42,8 @@ export interface SquiggleEditorProps { jsImports?: jsImports; /** Whether to show detail about types of the returns, default false */ showTypes?: boolean; + /** Whether to give users access to graph controls */ + showControls: boolean; } const Input = styled.div` @@ -64,6 +66,7 @@ export let SquiggleEditor: React.FC = ({ bindings = defaultBindings, jsImports = defaultImports, showTypes = false, + showControls = false, }: SquiggleEditorProps) => { let [expression, setExpression] = React.useState(initialSquiggleString); return ( @@ -91,6 +94,7 @@ export let SquiggleEditor: React.FC = ({ bindings={bindings} jsImports={jsImports} showTypes={showTypes} + showControls={showControls} />
); @@ -149,6 +153,8 @@ export interface SquigglePartialProps { bindings?: bindings; /** Variables imported from js */ jsImports?: jsImports; + /** Whether to give users access to graph controls */ + showControls?: boolean; } export let SquigglePartial: React.FC = ({ From 11d4a3bc8be0bd152f783b8aad2d9071c6d30e3b Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 23:42:11 +0200 Subject: [PATCH 124/146] do not export private modules from Reducer module --- .../Reducer_MathJs/Reducer_MathJsEval_test.res | 2 +- .../Reducer_MathJs/Reducer_MathJsParse_test.res | 2 +- .../__tests__/Reducer/Reducer_functionTricks_test.res | 11 ++++++----- .../squiggle-lang/src/rescript/Reducer/Reducer.res | 4 ---- .../squiggle-lang/src/rescript/Reducer/Reducer.resi | 4 ---- 5 files changed, 8 insertions(+), 15 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsEval_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsEval_test.res index 355c69ea..6f232d0e 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsEval_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsEval_test.res @@ -1,5 +1,5 @@ open ReducerInterface.ExpressionValue -module MathJs = Reducer.MathJs +module MathJs = Reducer_MathJs module ErrorValue = Reducer.ErrorValue open Jest diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res index a79ff024..b085eeb3 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res @@ -1,4 +1,4 @@ -module Parse = Reducer.MathJs.Parse +module Parse = Reducer_MathJs.Parse module Result = Belt.Result open Jest diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index b425c88e..9ca8304d 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -64,9 +64,10 @@ describe("call and bindings", () => { describe("function trics", () => { testParseToBe( - "f(x)=f(y)=2; f(2)", - "Ok((:$$block (:$$block (:$let :f (:$$lambda [x] (:$$block (:$let :f (:$$lambda [y] (:$$block 2)))))) (:f 2))))") - testEvalToBe("f(x)=f(y)=2; f(2)","Ok({f: lambda(y=>internal code),x: 2})") - testEvalToBe("y=2;g(x)=y+1;g(2)", "Ok(3)") - testEvalToBe("y=2;g(x)=inspect(y)+1", "Ok({g: lambda(x=>internal code),y: 2})") + "f(x)=f(y)=2; f(2)", + "Ok((:$$block (:$$block (:$let :f (:$$lambda [x] (:$$block (:$let :f (:$$lambda [y] (:$$block 2)))))) (:f 2))))", + ) + testEvalToBe("f(x)=f(y)=2; f(2)", "Ok({f: lambda(y=>internal code),x: 2})") + testEvalToBe("y=2;g(x)=y+1;g(2)", "Ok(3)") + testEvalToBe("y=2;g(x)=inspect(y)+1", "Ok({g: lambda(x=>internal code),y: 2})") }) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res index 24c985d8..1ee57529 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res @@ -1,9 +1,5 @@ -module Dispatch = Reducer_Dispatch module ErrorValue = Reducer_ErrorValue module Expression = Reducer_Expression -module Extra = Reducer_Extra -module Js = Reducer_Js -module MathJs = Reducer_MathJs type environment = ReducerInterface_ExpressionValue.environment type errorValue = Reducer_ErrorValue.errorValue diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi index 4e86361a..71b394fb 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi @@ -1,9 +1,5 @@ -module Dispatch = Reducer_Dispatch module ErrorValue = Reducer_ErrorValue module Expression = Reducer_Expression -module Extra = Reducer_Extra -module Js = Reducer_Js -module MathJs = Reducer_MathJs @genType type environment = ReducerInterface_ExpressionValue.environment From 5df9d0e51b8e919d1e8f6519292738b5bd8c51c7 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 21:51:58 +0000 Subject: [PATCH 125/146] Pass showTypes and showControls in playground --- .../components/src/components/SquigglePlayground.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/components/src/components/SquigglePlayground.tsx b/packages/components/src/components/SquigglePlayground.tsx index 93e1d963..424cff8d 100644 --- a/packages/components/src/components/SquigglePlayground.tsx +++ b/packages/components/src/components/SquigglePlayground.tsx @@ -43,6 +43,8 @@ function FieldFloat(Props: FieldFloatProps) { interface Props { initialSquiggleString?: string; height?: number; + showTypes?: boolean; + showControls?: boolean; } interface Props2 { @@ -55,10 +57,6 @@ const ShowBox = styled.div` height: ${(props) => props.height}; `; -const MyComponent = styled.div` - color: ${(props) => props.theme.colors.main}; -`; - interface TitleProps { readonly maxHeight: number; } @@ -81,6 +79,8 @@ const Col = styled.div``; let SquigglePlayground: FC = ({ initialSquiggleString = "", height = 300, + showTypes = false, + showControls = false, }: Props) => { let [squiggleString, setSquiggleString] = useState(initialSquiggleString); let [sampleCount, setSampleCount] = useState(1000); @@ -112,6 +112,8 @@ let SquigglePlayground: FC = ({ diagramCount={diagramCount} pointDistLength={pointDistLength} height={150} + showTypes={showTypes} + showControls={showControls} /> From 75a55de3734a67adfe018823c2c1cac9ca6e54c3 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 21:55:43 +0000 Subject: [PATCH 126/146] Recurse showTypes --- packages/components/src/components/SquiggleChart.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index a9fde172..898b2e95 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -141,6 +141,8 @@ const SquiggleItem: React.FC = ({ expression={r} width={width !== undefined ? width - 20 : width} height={50} + showTypes={showTypes} + showControls={showControls} /> ))} @@ -155,6 +157,8 @@ const SquiggleItem: React.FC = ({ expression={r} width={width !== undefined ? width - 20 : width} height={50} + showTypes={showTypes} + showControls={showControls} /> ))} From 6e72b89f7f878f34312cd70b254e4013f7cfd8b3 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 2 May 2022 21:59:56 +0000 Subject: [PATCH 127/146] Add array string and function viewers --- packages/components/src/components/SquiggleChart.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 3210b1d8..887b792b 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -156,6 +156,18 @@ const SquiggleItem: React.FC = ({ ))} ); + case "arraystring": + return ( + + {expression.value.map((r) => `"${r}"`)} + + ); + case "lambda": + return ( + + There is no viewer currently available for function types. + + ); } }; From d26eaa2523d88b52c019d431433884d548a0e8f7 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 3 May 2022 00:16:29 +0200 Subject: [PATCH 128/146] Note infinite recursion --- .../__tests__/Reducer/Reducer_functionTricks_test.res | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index 9ca8304d..208c3085 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -70,4 +70,5 @@ describe("function trics", () => { testEvalToBe("f(x)=f(y)=2; f(2)", "Ok({f: lambda(y=>internal code),x: 2})") testEvalToBe("y=2;g(x)=y+1;g(2)", "Ok(3)") testEvalToBe("y=2;g(x)=inspect(y)+1", "Ok({g: lambda(x=>internal code),y: 2})") + //testEvalToBe("f(x) = x(x); f(f)", "????") // TODO: Infinite loop. Any solution? Catching proper exception or timeout? }) From 78f46daed8ce7d03c23a8b23fd50c0bf1d230a64 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 3 May 2022 00:18:23 +0200 Subject: [PATCH 129/146] Note infinite recursion --- .../__tests__/Reducer/Reducer_functionTricks_test.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index 208c3085..d7040910 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -70,5 +70,5 @@ describe("function trics", () => { testEvalToBe("f(x)=f(y)=2; f(2)", "Ok({f: lambda(y=>internal code),x: 2})") testEvalToBe("y=2;g(x)=y+1;g(2)", "Ok(3)") testEvalToBe("y=2;g(x)=inspect(y)+1", "Ok({g: lambda(x=>internal code),y: 2})") - //testEvalToBe("f(x) = x(x); f(f)", "????") // TODO: Infinite loop. Any solution? Catching proper exception or timeout? + MySkip.testEvalToBe("f(x) = x(x); f(f)", "????") // TODO: Infinite loop. Any solution? Catching proper exception or timeout? }) From c5ae846df4559a31ff31d639f1eed9edb7898de4 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 3 May 2022 00:30:41 +0200 Subject: [PATCH 130/146] Note duplicate parameters --- .../__tests__/Reducer/Reducer_functionTricks_test.res | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index d7040910..0d2ed4c5 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -71,4 +71,5 @@ describe("function trics", () => { testEvalToBe("y=2;g(x)=y+1;g(2)", "Ok(3)") testEvalToBe("y=2;g(x)=inspect(y)+1", "Ok({g: lambda(x=>internal code),y: 2})") MySkip.testEvalToBe("f(x) = x(x); f(f)", "????") // TODO: Infinite loop. Any solution? Catching proper exception or timeout? + MySkip.testEvalToBe("f(x, x)=x+x; f(1,2)", "????") // TODO: Duplicate parameters }) From 88428c74afa8b2ec48b4dd569fbc98e8792e0109 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 3 May 2022 00:38:40 +0200 Subject: [PATCH 131/146] cases to handle with new parser. lambdas in arrays and records --- .../__tests__/Reducer/Reducer_functionTricks_test.res | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index 0d2ed4c5..284364e6 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -72,4 +72,6 @@ describe("function trics", () => { testEvalToBe("y=2;g(x)=inspect(y)+1", "Ok({g: lambda(x=>internal code),y: 2})") MySkip.testEvalToBe("f(x) = x(x); f(f)", "????") // TODO: Infinite loop. Any solution? Catching proper exception or timeout? MySkip.testEvalToBe("f(x, x)=x+x; f(1,2)", "????") // TODO: Duplicate parameters + MySkip.testEvalToBe("myadd(x,y)=x+y; z=[add]; z[0](3,2)", "????") //TODO: to fix with new parser + MySkip.testEvalToBe("myaddd(x,y)=x+y; z={x: add}; z.x(3,2)", "????") //TODO: to fix with new parser }) From b28df258e1a682cd6663ff19fd839536d6b59404 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Tue, 3 May 2022 11:06:53 -0400 Subject: [PATCH 132/146] Ran formatter --- .../SymbolicDist/SymbolicDist.res | 2 +- .../website/docs/Features/Distributions.mdx | 31 ++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res index 94fd42ca..58129d0b 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res @@ -230,7 +230,7 @@ module Float = { let inv = (p, t: t) => p < t ? 0.0 : 1.0 let mean = (t: t) => Ok(t) let sample = (t: t) => t - let toString = Js.Float.toString + let toString = (t:t) => j`Delta($t)` } module From90thPercentile = { diff --git a/packages/website/docs/Features/Distributions.mdx b/packages/website/docs/Features/Distributions.mdx index 5d840ee0..c57ed075 100644 --- a/packages/website/docs/Features/Distributions.mdx +++ b/packages/website/docs/Features/Distributions.mdx @@ -220,9 +220,12 @@ Creates a [uniform distribution]( @@ -234,8 +237,11 @@ with values at 1 and 2. Therefore, `mixture(1,2,normal(5,2))` is the same as `mi - - + + + + + @@ -315,8 +321,6 @@ Creates an [exponential distribution](https://en.wikipedia.org/wiki/Exponential_ Creates a [triangular distribution](https://en.wikipedia.org/wiki/Triangular_distribution) with the given low, mode, and high values. -#### Validity - ### Arguments - `low`: Number @@ -336,3 +340,16 @@ Creates a sample set distribution using an array of samples. ### Arguments - `samples`: An array of at least 5 numbers. + + +

+ Samples are converted into{" "} + PDF{" "} + shapes automatically using{" "} + + kernel density estimation + {" "} + and an approximated bandwidth. Eventually Squiggle will allow for more + specificity. +

+
From 02a2d96f8f28f8ab67cac5b5b89e7052e8a11277 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Tue, 3 May 2022 11:12:44 -0400 Subject: [PATCH 133/146] Added appropriate code blocsk --- .../website/docs/Features/Distributions.mdx | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/website/docs/Features/Distributions.mdx b/packages/website/docs/Features/Distributions.mdx index c57ed075..2ade1a3c 100644 --- a/packages/website/docs/Features/Distributions.mdx +++ b/packages/website/docs/Features/Distributions.mdx @@ -22,17 +22,19 @@ If both values are above zero, a `lognormal` distribution is used. If not, a `no - When `5 to 10` is entered, both numbers are positive, so it generates a - lognormal distribution with 5th and 95th percentiles at 5 and 10. + When 5 to 10 is entered, both numbers are positive, so it + generates a lognormal distribution with 5th and 95th percentiles at 5 and + 10. - `5 to 10` does the same thing as `to(5,10)`. + 5 to 10 does the same thing as to(5,10). - When `-5 to 5` is entered, there's negative values, so it generates a normal - distribution. This has 5th and 95th percentiles at 5 and 10. + When -5 to 5 is entered, there's negative values, so it + generates a normal distribution. This has 5th and 95th percentiles at 5 and + 10. @@ -173,9 +175,10 @@ Creates a [log-normal distribution](https://en.wikipedia.org/wiki/Log-normal_dis ❓ Understanding mu and sigma

- The log of `lognormal(mu, sigma)` is a normal distribution with mean `mu` - and standard deviation `sigma`. For example, these two distributions are - identical: + The log of lognormal(mu, sigma) is a normal distribution with + mean mu + and standard deviation sigma. For example, these two distributions + are identical:

Date: Tue, 3 May 2022 11:30:00 -0400 Subject: [PATCH 134/146] Formatted rescript --- .../src/rescript/Distributions/SymbolicDist/SymbolicDist.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res index 58129d0b..a4704a34 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res @@ -230,7 +230,7 @@ module Float = { let inv = (p, t: t) => p < t ? 0.0 : 1.0 let mean = (t: t) => Ok(t) let sample = (t: t) => t - let toString = (t:t) => j`Delta($t)` + let toString = (t: t) => j`Delta($t)` } module From90thPercentile = { From 526ee921b5d9abab381fbc687440277fe4c563da Mon Sep 17 00:00:00 2001 From: NunoSempere Date: Tue, 3 May 2022 17:22:08 -0400 Subject: [PATCH 135/146] tweak: some tweaks to documentation, part 1/2 --- .../Three-Formats-Of-Distributions.md | 19 ++++++----- .../website/docs/Features/Distributions.mdx | 4 ++- packages/website/docs/Features/Functions.mdx | 33 ++++++++++++++----- packages/website/docs/Features/Language.mdx | 16 ++++----- .../website/docs/Features/Node-Packages.md | 2 +- 5 files changed, 47 insertions(+), 27 deletions(-) diff --git a/packages/website/docs/Discussions/Three-Formats-Of-Distributions.md b/packages/website/docs/Discussions/Three-Formats-Of-Distributions.md index 8ec5b88d..405bc97c 100644 --- a/packages/website/docs/Discussions/Three-Formats-Of-Distributions.md +++ b/packages/website/docs/Discussions/Three-Formats-Of-Distributions.md @@ -11,7 +11,7 @@ _Symbolic_ formats are just the math equations. `normal(5,3)` is the symbolic re When you sample distributions (usually starting with symbolic formats), you get lists of samples. Monte Carlo techniques return lists of samples. Let’s call this the “_Sample Set_” format. -Lastly is what I’ll refer to as the _Graph_ format. It describes the coordinates, or the shape, of the distribution. You can save these formats in JSON, for instance, like, `{xs: [1, 2, 3, 4…], ys: [.0001, .0003, .002, …]}`. +Lastly is what I’ll refer to as the _Graph_ format. It describes the coordinates, or the shape, of the distribution. You can save these formats in JSON, for instance, like, `{xs: [1, 2, 3, 4, …], ys: [.0001, .0003, .002, …]}`. Symbolic, Sample Set, and Graph formats all have very different advantages and disadvantages. @@ -19,7 +19,7 @@ Note that the name "Symbolic" is fairly standard, but I haven't found common nam ## Symbolic Formats -**TLDR** +**TL;DR** Mathematical representations. Require analytic solutions. These are often ideal where they can be applied, but apply to very few actual functions. Typically used sparsely, except for the starting distributions (before any computation is performed). **Examples** @@ -29,9 +29,6 @@ Mathematical representations. Require analytic solutions. These are often ideal **How to Do Computation** To perform calculations of symbolic systems, you need to find analytical solutions. For example, there are equations to find the pdf or cdf of most distribution shapes at any point. There are also lots of simplifications that could be done in particular situations. For example, there’s an analytical solution for combining normal distributions. -**Special: The Metalog Distribution** -The Metalog distribution seems like it can represent almost any reasonable distribution. It’s symbolic. This is great for storage, but it’s not clear if it helps with calculation. My impression is that we don’t have symbolic ways of doing most functions (addition, multiplication, etc) on metalog distributions. Also, note that it can take a fair bit of computation to fit a shape to the Metalog distribution. - **Advantages** - Maximally compressed; i.e. very easy to store. @@ -54,10 +51,14 @@ The Metalog distribution seems like it can represent almost any reasonable distr **How to Visualize** Convert to graph, then display that. (Optionally, you can also convert to samples, then display those using a histogram, but this is often worse you have both options.) +**Bonus: The Metalog Distribution** + +The Metalog distribution seems like it can represent almost any reasonable distribution. It’s symbolic. This is great for storage, but it’s not clear if it helps with calculation. My impression is that we don’t have symbolic ways of doing most functions (addition, multiplication, etc) on metalog distributions. Also, note that it can take a fair bit of computation to fit a shape to the Metalog distribution. + ## Graph Formats -**TLDR** -Lists of the x-y coordinates of the shape of a distribution. (Usually the pdf, which is more compressed than the cdf). Some key functions (like pdf, cdf) and manipulations can work on almost any graphally-described distribution. +**TL;DR** +Lists of the x-y coordinates of the shape of a distribution. (Usually the pdf, which is more compressed than the cdf). Some key functions (like pdf, cdf) and manipulations can work on almost any graphically-described distribution. **Alternative Names:** Grid, Mesh, Graph, Vector, Pdf, PdfCoords/PdfPoints, Discretised, Bezier, Curve @@ -77,7 +78,7 @@ Use graph techniques. These can be fairly computationally-intensive (particularl **Disadvantages** -- Most calculations are infeasible/impossible to perform graphally. In these cases, you need to use sampling. +- Most calculations are infeasible/impossible to perform graphically. In these cases, you need to use sampling. - Not as accurate or fast as symbolic methods, where the symbolic methods are applicable. - The tails get cut off, which is subideal. It’s assumed that the value of the pdf outside of the bounded range is exactly 0, which is not correct. (Note: If you have ideas on how to store graph formats that don’t cut off tails, let me know) @@ -108,7 +109,7 @@ Use graph techniques. These can be fairly computationally-intensive (particularl ## Sample Set Formats -**TLDR** +**TL;DR** Random samples. Use Monte Carlo simulation to perform calculations. This is the predominant technique using Monte Carlo methods; in these cases, most nodes are essentially represented as sample sets. [Guesstimate](https://www.getguesstimate.com/) works this way. **How to Do Computation** diff --git a/packages/website/docs/Features/Distributions.mdx b/packages/website/docs/Features/Distributions.mdx index 2ade1a3c..28e1db01 100644 --- a/packages/website/docs/Features/Distributions.mdx +++ b/packages/website/docs/Features/Distributions.mdx @@ -159,7 +159,9 @@ Creates a [normal distribution](https://en.wikipedia.org/wiki/Normal_distributio Creates a [log-normal distribution](https://en.wikipedia.org/wiki/Log-normal_distribution) with the given mu and sigma. -`Mu` and `sigma` can be difficult to directly reason about. Because of this complexity, we recommend typically using the to syntax instead of estimating `mu` and `sigma` directly. +`Mu` and `sigma` represent the mean and standard deviation of the normal which results when +you take the log of our lognormal distribution. They can be difficult to directly reason about. +Because of this complexity, we recommend typically using the to syntax instead of estimating `mu` and `sigma` directly. diff --git a/packages/website/docs/Features/Functions.mdx b/packages/website/docs/Features/Functions.mdx index 38872db3..46bc4e39 100644 --- a/packages/website/docs/Features/Functions.mdx +++ b/packages/website/docs/Features/Functions.mdx @@ -11,7 +11,9 @@ Here are the ways we combine distributions. ### Addition -A horizontal right shift +A horizontal right shift. The addition operation represents the distribution of the sum of +the value of one random sample chosen from the first distribution and the value one random sample +chosen from the second distribution. @@ -68,6 +80,8 @@ exp(dist)`} ### Taking logarithms +A projection over a stretched x-axis. + @@ -201,7 +218,7 @@ Or `PointSet` format Above, we saw the unary `toSampleSet`, which uses an internal hardcoded number of samples. If you'd like to provide the number of samples, it has a binary signature as well (floored) - + #### Validity @@ -241,7 +258,7 @@ You can cut off from the left You can cut off from the right - + You can cut off from both sides diff --git a/packages/website/docs/Features/Language.mdx b/packages/website/docs/Features/Language.mdx index 5b66d2e2..74c703ae 100644 --- a/packages/website/docs/Features/Language.mdx +++ b/packages/website/docs/Features/Language.mdx @@ -7,21 +7,21 @@ import { SquiggleEditor } from "../../src/components/SquiggleEditor"; ## Expressions -A distribution +### Distributions -A number +### Numbers - + -Arrays +### Arrays -Records +### Records = We can define functions ## See more diff --git a/packages/website/docs/Features/Node-Packages.md b/packages/website/docs/Features/Node-Packages.md index ab590c32..381cef1f 100644 --- a/packages/website/docs/Features/Node-Packages.md +++ b/packages/website/docs/Features/Node-Packages.md @@ -30,7 +30,7 @@ this library to help navigate the return type. The `@quri/squiggle-components` package offers several components and utilities for people who want to embed Squiggle components into websites. This documentation -relies on `@quri/squiggle-components` frequently. +uses `@quri/squiggle-components` frequently. We host [a storybook](https://squiggle-components.netlify.app/) with details and usage of each of the components made available. From 33ee0b27d50cf8dfcfb067ae0a613c760a7e16bc Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Wed, 4 May 2022 15:14:34 +0200 Subject: [PATCH 136/146] remove inspect performance completely Redesign required on the function interface --- .../Reducer/Reducer_debugging_test.res | 1 - .../Reducer_Dispatch_BuiltIn.res | 38 ++++++++----------- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res index f005c1fc..51efdbea 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res @@ -12,5 +12,4 @@ open Reducer_TestHelpers describe("Debugging", () => { testEvalToBe("inspect(1)", "Ok(1)") testEvalToBe("inspect(1, \"one\")", "Ok(1)") - testEvalToBe("inspectPerformance(1, \"one\")", "Ok(1)") }) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 25fc05a7..b8630a6a 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -1,6 +1,7 @@ module ExternalLibrary = ReducerInterface.ExternalLibrary module MathJs = Reducer_MathJs module Bindings = Reducer_Expression_Bindings +module Lambda = Reducer_Expression_Lambda open ReducerInterface.ExpressionValue open Reducer_ErrorValue @@ -54,21 +55,6 @@ let callInternal = (call: functionCall, _environment): result<'b, errorValue> => value->Ok } - /* - NOTE: This function is cancelled. The related issue is - https://github.com/webpack/webpack/issues/13435 - */ - let inspectPerformance = (value: expressionValue, label: string) => { - // let _ = %raw("{performance} = require('perf_hooks')") - // let start = %raw(`performance.now()`) - // let finish = %raw(`performance.now()`) - // let performance = finish - start - // Js.log(`${label}: ${value->toString} performance: ${Js.String.make(performance)}ms`) - // TODO find a way of failing the hook gracefully, also needs a block parameter - Js.log(`${label}: ${value->toString}`) - value->Ok - } - let doSetBindings = ( externalBindings: externalBindings, symbol: string, @@ -83,19 +69,25 @@ let callInternal = (call: functionCall, _environment): result<'b, errorValue> => let doExportBindings = (externalBindings: externalBindings) => EvRecord(externalBindings)->Ok + // let doMapArray = (aValueArray, aLambdaValue) => { + // aValueArray->Belt.Array.reduceReverse( + // Ok(list{}), + // (rAcc, elem) => R + // ) + // } + // let doReduceArray(aValueArray, initialValue, aLambdaValue) + switch call { - | ("$atIndex", [EvArray(aValueArray), EvArray([EvNumber(fIndex)])]) => - arrayAtIndex(aValueArray, fIndex) + // | ("$atIndex", [obj, index]) => (toStringWithType(obj) ++ "??~~~~" ++ toStringWithType(index))->EvString->Ok + | ("$atIndex", [EvArray(aValueArray), EvArray([EvNumber(fIndex)])]) => arrayAtIndex(aValueArray, fIndex) | ("$atIndex", [EvRecord(dict), EvArray([EvString(sIndex)])]) => recordAtIndex(dict, sIndex) - | ("$atIndex", [obj, index]) => - (toStringWithType(obj) ++ "??~~~~" ++ toStringWithType(index))->EvString->Ok | ("$constructRecord", [EvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) + | ("$exportBindings", [EvRecord(externalBindings)]) => doExportBindings(externalBindings) + | ("$setBindings", [EvRecord(externalBindings), EvSymbol(symbol), value]) => doSetBindings(externalBindings, symbol, value) | ("inspect", [value, EvString(label)]) => inspectLabel(value, label) | ("inspect", [value]) => inspect(value) - | ("inspectPerformance", [value, EvString(label)]) => inspectPerformance(value, label) - | ("$setBindings", [EvRecord(externalBindings), EvSymbol(symbol), value]) => - doSetBindings(externalBindings, symbol, value) - | ("$exportBindings", [EvRecord(externalBindings)]) => doExportBindings(externalBindings) + // | ("map", [EvArray(aValueArray), EvLambda(lambdaValue)]) => doMapArray(aValueArray, aLambdaValue) + // | ("reduce", [EvArray(aValueArray), initialValue, EvLambda(lambdaValue)]) => doReduceArray(aValueArray, initialValue, aLambdaValue) | call => callMathJs(call) } } From ae48bd642002595c8cbd1fe818c0752d919ca9e2 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Wed, 4 May 2022 15:22:28 +0200 Subject: [PATCH 137/146] pass reducer to dispatch to define functions that has lambda arguments, dispatching requires a reducer --- .../Reducer_Dispatch_BuiltIn.res | 24 +++++++++++++------ .../Reducer_Expression/Reducer_Expression.res | 3 ++- .../Reducer_Expression_Lambda.res | 3 +-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index b8630a6a..60f31c89 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -1,7 +1,8 @@ -module ExternalLibrary = ReducerInterface.ExternalLibrary -module MathJs = Reducer_MathJs module Bindings = Reducer_Expression_Bindings +module ExpressionT = Reducer_Expression_T +module ExternalLibrary = ReducerInterface.ExternalLibrary module Lambda = Reducer_Expression_Lambda +module MathJs = Reducer_MathJs open ReducerInterface.ExpressionValue open Reducer_ErrorValue @@ -13,7 +14,10 @@ open Reducer_ErrorValue exception TestRescriptException -let callInternal = (call: functionCall, _environment): result<'b, errorValue> => { +let callInternal = (call: functionCall, _environment, _reducer: ExpressionT.reducerFn): result< + 'b, + errorValue, +> => { let callMathJs = (call: functionCall): result<'b, errorValue> => switch call { | ("javascriptraise", [msg]) => Js.Exn.raiseError(toString(msg)) // For Tests @@ -79,11 +83,13 @@ let callInternal = (call: functionCall, _environment): result<'b, errorValue> => switch call { // | ("$atIndex", [obj, index]) => (toStringWithType(obj) ++ "??~~~~" ++ toStringWithType(index))->EvString->Ok - | ("$atIndex", [EvArray(aValueArray), EvArray([EvNumber(fIndex)])]) => arrayAtIndex(aValueArray, fIndex) + | ("$atIndex", [EvArray(aValueArray), EvArray([EvNumber(fIndex)])]) => + arrayAtIndex(aValueArray, fIndex) | ("$atIndex", [EvRecord(dict), EvArray([EvString(sIndex)])]) => recordAtIndex(dict, sIndex) | ("$constructRecord", [EvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) | ("$exportBindings", [EvRecord(externalBindings)]) => doExportBindings(externalBindings) - | ("$setBindings", [EvRecord(externalBindings), EvSymbol(symbol), value]) => doSetBindings(externalBindings, symbol, value) + | ("$setBindings", [EvRecord(externalBindings), EvSymbol(symbol), value]) => + doSetBindings(externalBindings, symbol, value) | ("inspect", [value, EvString(label)]) => inspectLabel(value, label) | ("inspect", [value]) => inspect(value) // | ("map", [EvArray(aValueArray), EvLambda(lambdaValue)]) => doMapArray(aValueArray, aLambdaValue) @@ -95,12 +101,16 @@ let callInternal = (call: functionCall, _environment): result<'b, errorValue> => /* Reducer uses Result monad while reducing expressions */ -let dispatch = (call: functionCall, environment): result => +let dispatch = (call: functionCall, environment, reducer: ExpressionT.reducerFn): result< + expressionValue, + errorValue, +> => try { + let callInternalWithReducer = (call, environment) => callInternal(call, environment, reducer) let (fn, args) = call // There is a bug that prevents string match in patterns // So we have to recreate a copy of the string - ExternalLibrary.dispatch((Js.String.make(fn), args), environment, callInternal) + ExternalLibrary.dispatch((Js.String.make(fn), args), environment, callInternalWithReducer) } catch { | Js.Exn.Error(obj) => REJavaScriptExn(Js.Exn.message(obj), Js.Exn.name(obj))->Error | _ => RETodo("unhandled rescript exception")->Error 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 e1df1418..81830e84 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 @@ -77,7 +77,8 @@ and reduceValueList = (valueList: list, environment): result< 'e, > => switch valueList { - | list{EvCall(fName), ...args} => (fName, args->Belt.List.toArray)->BuiltIn.dispatch(environment) + | list{EvCall(fName), ...args} => + (fName, args->Belt.List.toArray)->BuiltIn.dispatch(environment, reduceExpression) | list{EvLambda(lamdaCall), ...args} => Lambda.doLambdaCall(lamdaCall, args, environment, reduceExpression) 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 55931cc7..35546465 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 @@ -55,6 +55,5 @@ let applyParametersToLambda = ( ) } -let doLambdaCall = (lambdaValue: ExpressionValue.lambdaValue, args, environment, reducer) => { +let doLambdaCall = (lambdaValue: ExpressionValue.lambdaValue, args, environment, reducer) => applyParametersToLambda(lambdaValue, args, environment, reducer) -} From c0512e5eed60eefd63167adadb0ff09b4ba2c1c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 May 2022 14:40:32 +0000 Subject: [PATCH 138/146] :arrow_up: Bump @testing-library/react from 13.1.1 to 13.2.0 Bumps [@testing-library/react](https://github.com/testing-library/react-testing-library) from 13.1.1 to 13.2.0. - [Release notes](https://github.com/testing-library/react-testing-library/releases) - [Changelog](https://github.com/testing-library/react-testing-library/blob/main/CHANGELOG.md) - [Commits](https://github.com/testing-library/react-testing-library/compare/v13.1.1...v13.2.0) --- updated-dependencies: - dependency-name: "@testing-library/react" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 3ffc28af..2579668a 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -27,7 +27,7 @@ "@storybook/preset-create-react-app": "^4.1.0", "@storybook/react": "^6.4.22", "@testing-library/jest-dom": "^5.16.4", - "@testing-library/react": "^13.1.1", + "@testing-library/react": "^13.2.0", "@testing-library/user-event": "^14.1.1", "@types/jest": "^27.4.0", "@types/lodash": "^4.14.182", diff --git a/yarn.lock b/yarn.lock index 11bb1227..8753ca0d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3754,10 +3754,10 @@ lodash "^4.17.15" redent "^3.0.0" -"@testing-library/react@^13.1.1": - version "13.1.1" - resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-13.1.1.tgz#6c1635e25acca8ca5be8ee3b19ad1391681c5846" - integrity sha512-8mirlAa0OKaUvnqnZF6MdAh2tReYA2KtWVw1PKvaF5EcCZqgK5pl8iF+3uW90JdG5Ua2c2c2E2wtLdaug3dsVg== +"@testing-library/react@^13.2.0": + version "13.2.0" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-13.2.0.tgz#2db00bc94d71c4e90e5c25582e90a650ae2925bf" + integrity sha512-Bprbz/SZVONCJy5f7hcihNCv313IJXdYiv0nSJklIs1SQCIHHNlnGNkosSXnGZTmesyGIcBGNppYhXcc11pb7g== dependencies: "@babel/runtime" "^7.12.5" "@testing-library/dom" "^8.5.0" From e561a47d51f05d79d9d768a4e2a032ff85999318 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 May 2022 14:41:05 +0000 Subject: [PATCH 139/146] :arrow_up: Bump @types/jest from 27.4.1 to 27.5.0 Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 27.4.1 to 27.5.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) --- updated-dependencies: - dependency-name: "@types/jest" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- packages/squiggle-lang/package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 3ffc28af..92fe4ad5 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -29,7 +29,7 @@ "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.1.1", "@testing-library/user-event": "^14.1.1", - "@types/jest": "^27.4.0", + "@types/jest": "^27.5.0", "@types/lodash": "^4.14.182", "@types/node": "^17.0.31", "@types/react": "^18.0.3", diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 98748e63..97b710b6 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -46,7 +46,7 @@ "rescript-fast-check": "^1.1.1", "@glennsl/rescript-jest": "^0.9.0", "@istanbuljs/nyc-config-typescript": "^1.0.2", - "@types/jest": "^27.4.0", + "@types/jest": "^27.5.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", "chalk": "^5.0.1", "codecov": "^3.8.3", diff --git a/yarn.lock b/yarn.lock index 11bb1227..55dd931a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4017,10 +4017,10 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@*", "@types/jest@^27.4.0": - version "27.4.1" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.1.tgz#185cbe2926eaaf9662d340cc02e548ce9e11ab6d" - integrity sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw== +"@types/jest@*", "@types/jest@^27.5.0": + version "27.5.0" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.0.tgz#e04ed1824ca6b1dd0438997ba60f99a7405d4c7b" + integrity sha512-9RBFx7r4k+msyj/arpfaa0WOOEcaAZNmN+j80KFbFCoSqCJGHTz7YMAMGQW9Xmqm5w6l5c25vbSjMwlikJi5+g== dependencies: jest-matcher-utils "^27.0.0" pretty-format "^27.0.0" From 5de6aa8e0d1590d787eb50eacf1454cfd8e3b4cf Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Wed, 4 May 2022 15:46:00 +0200 Subject: [PATCH 140/146] map reduce reduceReverse reverse keep --- .../Reducer/Reducer_mapReduce_test.res | 11 ++++ .../Reducer_Dispatch_BuiltIn.res | 61 +++++++++++++++---- 2 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res new file mode 100644 index 00000000..674012be --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res @@ -0,0 +1,11 @@ +open Jest +open Reducer_TestHelpers + +describe("map reduce", () => { + testEvalToBe("double(x)=2*x; arr=[1,2,3]; map(arr, double)", "Ok([2,4,6])") + testEvalToBe("myadd(acc,x)=acc+x; arr=[1,2,3]; reduce(arr, 0, myadd)", "Ok(6)") + testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; reduce(arr, 0, change)", "Ok(15)") + testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; reduceReverse(arr, 0, change)", "Ok(9)") + testEvalToBe("arr=[1,2,3]; reverse(arr)", "Ok([3,2,1])") + testEvalToBe("check(x)=(x==2);arr=[1,2,3]; keep(arr,check)", "Ok([2])") +}) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 60f31c89..d1a77040 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -3,6 +3,7 @@ module ExpressionT = Reducer_Expression_T module ExternalLibrary = ReducerInterface.ExternalLibrary module Lambda = Reducer_Expression_Lambda module MathJs = Reducer_MathJs +module Result = Belt.Result open ReducerInterface.ExpressionValue open Reducer_ErrorValue @@ -14,7 +15,7 @@ open Reducer_ErrorValue exception TestRescriptException -let callInternal = (call: functionCall, _environment, _reducer: ExpressionT.reducerFn): result< +let callInternal = (call: functionCall, environment, reducer: ExpressionT.reducerFn): result< 'b, errorValue, > => { @@ -73,16 +74,48 @@ let callInternal = (call: functionCall, _environment, _reducer: ExpressionT.redu let doExportBindings = (externalBindings: externalBindings) => EvRecord(externalBindings)->Ok - // let doMapArray = (aValueArray, aLambdaValue) => { - // aValueArray->Belt.Array.reduceReverse( - // Ok(list{}), - // (rAcc, elem) => R - // ) - // } - // let doReduceArray(aValueArray, initialValue, aLambdaValue) + let doKeepArray = (aValueArray, aLambdaValue) => { + let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) => + rAcc->Result.flatMap(acc => { + let rNewElem = Lambda.doLambdaCall(aLambdaValue, list{elem}, environment, reducer) + rNewElem->Result.map(newElem => + switch newElem { + | EvBool(true) => list{elem, ...acc} + | _ => acc + } + ) + }) + ) + rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->EvArray) + } + + let doMapArray = (aValueArray, aLambdaValue) => { + let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) => + rAcc->Result.flatMap(acc => { + let rNewElem = Lambda.doLambdaCall(aLambdaValue, list{elem}, environment, reducer) + rNewElem->Result.map(newElem => list{newElem, ...acc}) + }) + ) + rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->EvArray) + } + + let doReduceArray = (aValueArray, initialValue, aLambdaValue) => { + aValueArray->Belt.Array.reduce(Ok(initialValue), (rAcc, elem) => + rAcc->Result.flatMap(acc => + Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer) + ) + ) + } + + let doReduceReverseArray = (aValueArray, initialValue, aLambdaValue) => { + aValueArray->Belt.Array.reduceReverse(Ok(initialValue), (rAcc, elem) => + rAcc->Result.flatMap(acc => + Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer) + ) + ) + } switch call { - // | ("$atIndex", [obj, index]) => (toStringWithType(obj) ++ "??~~~~" ++ toStringWithType(index))->EvString->Ok | ("$atIndex", [EvArray(aValueArray), EvArray([EvNumber(fIndex)])]) => arrayAtIndex(aValueArray, fIndex) | ("$atIndex", [EvRecord(dict), EvArray([EvString(sIndex)])]) => recordAtIndex(dict, sIndex) @@ -92,8 +125,14 @@ let callInternal = (call: functionCall, _environment, _reducer: ExpressionT.redu doSetBindings(externalBindings, symbol, value) | ("inspect", [value, EvString(label)]) => inspectLabel(value, label) | ("inspect", [value]) => inspect(value) - // | ("map", [EvArray(aValueArray), EvLambda(lambdaValue)]) => doMapArray(aValueArray, aLambdaValue) - // | ("reduce", [EvArray(aValueArray), initialValue, EvLambda(lambdaValue)]) => doReduceArray(aValueArray, initialValue, aLambdaValue) + | ("keep", [EvArray(aValueArray), EvLambda(aLambdaValue)]) => + doKeepArray(aValueArray, aLambdaValue) + | ("map", [EvArray(aValueArray), EvLambda(aLambdaValue)]) => doMapArray(aValueArray, aLambdaValue) + | ("reduce", [EvArray(aValueArray), initialValue, EvLambda(aLambdaValue)]) => + doReduceArray(aValueArray, initialValue, aLambdaValue) + | ("reduceReverse", [EvArray(aValueArray), initialValue, EvLambda(aLambdaValue)]) => + doReduceReverseArray(aValueArray, initialValue, aLambdaValue) + | ("reverse", [EvArray(aValueArray)]) => aValueArray->Belt.Array.reverse->EvArray->Ok | call => callMathJs(call) } } From 930c2d2b67b96a1374de98fa3aadecf7c9c64858 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Wed, 4 May 2022 15:53:41 +0000 Subject: [PATCH 141/146] Add Gamma distribution --- .../ReducerInterface_Distribution_test.res | 1 + .../SymbolicDist/SymbolicDist.res | 29 +++++++++++++++++++ .../SymbolicDist/SymbolicDistTypes.res | 6 ++++ .../ReducerInterface_GenericDistribution.res | 3 +- .../src/rescript/Utility/Jstat.res | 8 +++++ 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res index bb330479..571a838b 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res @@ -30,6 +30,7 @@ describe("eval on distribution functions", () => { describe("mean", () => { testEval("mean(normal(5,2))", "Ok(5)") testEval("mean(lognormal(1,2))", "Ok(20.085536923187668)") + testEval("mean(gamma(5,5))", "Ok(25)") }) describe("toString", () => { testEval("toString(normal(5,2))", "Ok('Normal(5,2)')") diff --git a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res index a4704a34..fb338ded 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res @@ -216,6 +216,27 @@ module Uniform = { } } +module Gamma = { + type t = gamma + let make = (shape: float, scale: float) => { + if shape > 0. { + if scale > 0. { + Ok(#Gamma({shape: shape, scale: scale})) + } else { + Error("scale must be larger than 0") + } + } else { + Error("shape must be larger than 0") + } + } + let pdf = (x: float, t: t) => Jstat.Gamma.pdf(x, t.shape, t.scale) + let cdf = (x: float, t: t) => Jstat.Gamma.cdf(x, t.shape, t.scale) + let inv = (p: float, t: t) => Jstat.Gamma.inv(p, t.shape, t.scale) + let sample = (t: t) => Jstat.Gamma.sample(t.shape, t.scale) + let mean = (t: t) => Ok(Jstat.Gamma.mean(t.shape, t.scale)) + let toString = ({shape, scale}: t) => j`($shape, $scale)` +} + module Float = { type t = float let make = t => #Float(t) @@ -252,6 +273,7 @@ module T = { | #Triangular(n) => Triangular.pdf(x, n) | #Exponential(n) => Exponential.pdf(x, n) | #Cauchy(n) => Cauchy.pdf(x, n) + | #Gamma(n) => Gamma.pdf(x, n) | #Lognormal(n) => Lognormal.pdf(x, n) | #Uniform(n) => Uniform.pdf(x, n) | #Beta(n) => Beta.pdf(x, n) @@ -264,6 +286,7 @@ module T = { | #Triangular(n) => Triangular.cdf(x, n) | #Exponential(n) => Exponential.cdf(x, n) | #Cauchy(n) => Cauchy.cdf(x, n) + | #Gamma(n) => Gamma.cdf(x, n) | #Lognormal(n) => Lognormal.cdf(x, n) | #Uniform(n) => Uniform.cdf(x, n) | #Beta(n) => Beta.cdf(x, n) @@ -276,6 +299,7 @@ module T = { | #Triangular(n) => Triangular.inv(x, n) | #Exponential(n) => Exponential.inv(x, n) | #Cauchy(n) => Cauchy.inv(x, n) + | #Gamma(n) => Gamma.inv(x, n) | #Lognormal(n) => Lognormal.inv(x, n) | #Uniform(n) => Uniform.inv(x, n) | #Beta(n) => Beta.inv(x, n) @@ -288,6 +312,7 @@ module T = { | #Triangular(n) => Triangular.sample(n) | #Exponential(n) => Exponential.sample(n) | #Cauchy(n) => Cauchy.sample(n) + | #Gamma(n) => Gamma.sample(n) | #Lognormal(n) => Lognormal.sample(n) | #Uniform(n) => Uniform.sample(n) | #Beta(n) => Beta.sample(n) @@ -310,6 +335,7 @@ module T = { | #Exponential(n) => Exponential.toString(n) | #Cauchy(n) => Cauchy.toString(n) | #Normal(n) => Normal.toString(n) + | #Gamma(n) => Gamma.toString(n) | #Lognormal(n) => Lognormal.toString(n) | #Uniform(n) => Uniform.toString(n) | #Beta(n) => Beta.toString(n) @@ -323,6 +349,7 @@ module T = { | #Cauchy(n) => Cauchy.inv(minCdfValue, n) | #Normal(n) => Normal.inv(minCdfValue, n) | #Lognormal(n) => Lognormal.inv(minCdfValue, n) + | #Gamma(n) => Gamma.inv(minCdfValue, n) | #Uniform({low}) => low | #Beta(n) => Beta.inv(minCdfValue, n) | #Float(n) => n @@ -334,6 +361,7 @@ module T = { | #Exponential(n) => Exponential.inv(maxCdfValue, n) | #Cauchy(n) => Cauchy.inv(maxCdfValue, n) | #Normal(n) => Normal.inv(maxCdfValue, n) + | #Gamma(n) => Gamma.inv(maxCdfValue, n) | #Lognormal(n) => Lognormal.inv(maxCdfValue, n) | #Beta(n) => Beta.inv(maxCdfValue, n) | #Uniform({high}) => high @@ -349,6 +377,7 @@ module T = { | #Lognormal(n) => Lognormal.mean(n) | #Beta(n) => Beta.mean(n) | #Uniform(n) => Uniform.mean(n) + | #Gamma(n) => Gamma.mean(n) | #Float(n) => Float.mean(n) } diff --git a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res index 333e2e63..7878a3bc 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res @@ -31,6 +31,11 @@ type triangular = { high: float, } +type gamma = { + shape: float, + scale: float, +} + @genType type symbolicDist = [ | #Normal(normal) @@ -40,6 +45,7 @@ type symbolicDist = [ | #Exponential(exponential) | #Cauchy(cauchy) | #Triangular(triangular) + | #Gamma(gamma) | #Float(float) ] diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index 542a54a2..b6f42697 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -154,6 +154,7 @@ module SymbolicConstructors = { | "beta" => Ok(SymbolicDist.Beta.make) | "lognormal" => Ok(SymbolicDist.Lognormal.make) | "cauchy" => Ok(SymbolicDist.Cauchy.make) + | "gamma" => Ok(SymbolicDist.Gamma.make) | "to" => Ok(SymbolicDist.From90thPercentile.make) | _ => Error("Unreachable state") } @@ -185,7 +186,7 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall, _environment) | ("delta", [EvNumber(f)]) => SymbolicDist.Float.makeSafe(f)->SymbolicConstructors.symbolicResultToOutput | ( - ("normal" | "uniform" | "beta" | "lognormal" | "cauchy" | "to") as fnName, + ("normal" | "uniform" | "beta" | "lognormal" | "cauchy" | "gamma" | "to") as fnName, [EvNumber(f1), EvNumber(f2)], ) => SymbolicConstructors.twoFloat(fnName) diff --git a/packages/squiggle-lang/src/rescript/Utility/Jstat.res b/packages/squiggle-lang/src/rescript/Utility/Jstat.res index 03c43174..1de2e8ed 100644 --- a/packages/squiggle-lang/src/rescript/Utility/Jstat.res +++ b/packages/squiggle-lang/src/rescript/Utility/Jstat.res @@ -81,6 +81,14 @@ module Binomial = { @module("jstat") @scope("binomial") external cdf: (float, float, float) => float = "cdf" } +module Gamma = { + @module("jstat") @scope("gamma") external pdf: (float, float, float) => float = "pdf" + @module("jstat") @scope("gamma") external cdf: (float, float, float) => float = "cdf" + @module("jstat") @scope("gamma") external inv: (float, float, float) => float = "inv" + @module("jstat") @scope("gamma") external mean: (float, float) => float = "mean" + @module("jstat") @scope("gamma") external sample: (float, float) => float = "sample" +} + @module("jstat") external sum: array => float = "sum" @module("jstat") external product: array => float = "product" @module("jstat") external min: array => float = "min" From 801e4c23d180e17e2da0157d14feb2de6a48065b Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Wed, 4 May 2022 16:50:08 +0000 Subject: [PATCH 142/146] v0.2.19 --- packages/components/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/package.json b/packages/components/package.json index db097341..b7841dda 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@quri/squiggle-components", - "version": "0.2.17", + "version": "0.2.19", "license": "MIT", "dependencies": { "@quri/squiggle-lang": "^0.2.8", From ad220ed2b414e151b84c94c81d99cc87e3e2b1ad Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Wed, 4 May 2022 20:44:46 +0200 Subject: [PATCH 143/146] foreign function interface --- .../Reducer/Reducer_mapReduce_test.res | 5 +++++ .../src/rescript/Reducer/Reducer.res | 21 +++++++++++++++++++ .../src/rescript/Reducer/Reducer.resi | 16 ++++++++++++++ .../Reducer_Expression_Lambda.res | 10 +++++++++ 4 files changed, 52 insertions(+) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res index 674012be..5414f827 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res @@ -9,3 +9,8 @@ describe("map reduce", () => { testEvalToBe("arr=[1,2,3]; reverse(arr)", "Ok([3,2,1])") testEvalToBe("check(x)=(x==2);arr=[1,2,3]; keep(arr,check)", "Ok([2])") }) + +Skip.describe("map reduce (sam)", () => { + testEvalToBe("addone(x)=x+1; map(2, addone)", "Error???") + testEvalToBe("addone(x)=x+1; map(2, {x: addone})", "Error???") +}) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res index 1ee57529..0ea1a733 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res @@ -1,11 +1,32 @@ module ErrorValue = Reducer_ErrorValue module Expression = Reducer_Expression +module ExpressionValue = ReducerInterface_ExpressionValue +module Lambda = Reducer_Expression_Lambda type environment = ReducerInterface_ExpressionValue.environment type errorValue = Reducer_ErrorValue.errorValue type expressionValue = ReducerInterface_ExpressionValue.expressionValue type externalBindings = ReducerInterface_ExpressionValue.externalBindings +type lambdaValue = ExpressionValue.lambdaValue + let evaluate = Expression.evaluate let evaluateUsingOptions = Expression.evaluateUsingOptions let evaluatePartialUsingExternalBindings = Expression.evaluatePartialUsingExternalBindings let parse = Expression.parse + +let foreignFunctionInterface = ( + lambdaValue: lambdaValue, + argArray: array, + environment: ExpressionValue.environment, +) => { + Lambda.foreignFunctionInterface( + lambdaValue, + argArray, + environment, + Expression.reduceExpression, + ) +} + +let defaultEnvironment = ExpressionValue.defaultEnvironment + +let defaultExternalBindings = ExpressionValue.defaultExternalBindings diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi index 71b394fb..2cd4155b 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi @@ -9,6 +9,9 @@ type errorValue = Reducer_ErrorValue.errorValue type expressionValue = ReducerInterface_ExpressionValue.expressionValue @genType type externalBindings = ReducerInterface_ExpressionValue.externalBindings +@genType +type lambdaValue = ReducerInterface_ExpressionValue.lambdaValue + @genType let evaluateUsingOptions: ( @@ -26,3 +29,16 @@ let evaluatePartialUsingExternalBindings: ( let evaluate: string => result let parse: string => result + +@genType +let foreignFunctionInterface: ( + QuriSquiggleLang.ReducerInterface_ExpressionValue.lambdaValue, + array, + QuriSquiggleLang.ReducerInterface_ExpressionValue.environment, +) => result + +@genType +let defaultEnvironment: environment + +@genType +let defaultExternalBindings: externalBindings 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 35546465..dc4920f3 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 @@ -57,3 +57,13 @@ let applyParametersToLambda = ( let doLambdaCall = (lambdaValue: ExpressionValue.lambdaValue, args, environment, reducer) => applyParametersToLambda(lambdaValue, args, environment, reducer) + +let foreignFunctionInterface = ( + lambdaValue: ExpressionValue.lambdaValue, + argArray: array, + environment: ExpressionValue.environment, + reducer: ExpressionT.reducerFn, +): result => { + let args = argArray->Belt.List.fromArray + applyParametersToLambda(lambdaValue, args, environment, reducer) +} From 8aa4248996f69fcffdf628dcd3c3ca10cf6457f3 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Wed, 4 May 2022 21:23:40 +0200 Subject: [PATCH 144/146] spelling --- .../__tests__/Reducer/Reducer_functionTricks_test.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index 284364e6..d9f7e7c8 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -62,7 +62,7 @@ describe("call and bindings", () => { testEvalToBe("f(x)=x+1; g(x)=f(x)+1; g(2)", "Ok(4)") }) -describe("function trics", () => { +describe("function tricks", () => { testParseToBe( "f(x)=f(y)=2; f(2)", "Ok((:$$block (:$$block (:$let :f (:$$lambda [x] (:$$block (:$let :f (:$$lambda [y] (:$$block 2)))))) (:f 2))))", From 99f54f596c2062ccebdec332eb0f5959d48e037c Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Wed, 4 May 2022 22:36:34 +0200 Subject: [PATCH 145/146] ternary operator (tested) --- .../Reducer/Reducer_ternaryOperator_test.res | 10 ++++++---- .../src/rescript/Reducer/Reducer.res | 7 +------ .../src/rescript/Reducer/Reducer.resi | 1 - .../Reducer_Dispatch_BuiltInMacros.res | 19 +++++++++++++++++++ .../rescript/Reducer/Reducer_ErrorValue.res | 2 ++ 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res index 61bfc8c7..c0311450 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res @@ -1,12 +1,14 @@ open Jest open Reducer_TestHelpers -Skip.describe("Parse ternary operator", () => { - testParseToBe("true ? 'YES' : 'NO'", "Ok('YES')") - testParseToBe("false ? 'YES' : 'NO'", "Ok('NO')") +describe("Parse ternary operator", () => { + testParseToBe("true ? 'YES' : 'NO'", "Ok((:$$block (:$$ternary true 'YES' 'NO')))") }) -Skip.describe("Evaluate ternary operator", () => { +describe("Evaluate ternary operator", () => { testEvalToBe("true ? 'YES' : 'NO'", "Ok('YES')") testEvalToBe("false ? 'YES' : 'NO'", "Ok('NO')") + testEvalToBe("2 > 1 ? 'YES' : 'NO'", "Ok('YES')") + testEvalToBe("2 <= 1 ? 'YES' : 'NO'", "Ok('NO')") + testEvalToBe("1+1 ? 'YES' : 'NO'", "Error(Expected type: Boolean)") }) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res index 0ea1a733..3b3450c3 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res @@ -19,12 +19,7 @@ let foreignFunctionInterface = ( argArray: array, environment: ExpressionValue.environment, ) => { - Lambda.foreignFunctionInterface( - lambdaValue, - argArray, - environment, - Expression.reduceExpression, - ) + Lambda.foreignFunctionInterface(lambdaValue, argArray, environment, Expression.reduceExpression) } let defaultEnvironment = ExpressionValue.defaultEnvironment diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi index 2cd4155b..d4e40a63 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi @@ -12,7 +12,6 @@ type externalBindings = ReducerInterface_ExpressionValue.externalBindings @genType type lambdaValue = ReducerInterface_ExpressionValue.lambdaValue - @genType let evaluateUsingOptions: ( ~environment: option, diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index c106c0ff..a771dd32 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -132,6 +132,23 @@ let dispatchMacroCall = ( eLambda(parameters, bindings->Bindings.toExternalBindings, lambdaDefinition), )->Ok + let doTernary = ( + condition: expression, + ifTrue: expression, + ifFalse: expression, + bindings: ExpressionT.bindings, + environment, + ): result => { + let rCondition = reduceExpression(condition, bindings, environment) + rCondition->Result.flatMap(conditionValue => + switch conditionValue { + | ExpressionValue.EvBool(false) => ExpressionWithContext.noContext(ifFalse)->Ok + | ExpressionValue.EvBool(true) => ExpressionWithContext.noContext(ifTrue)->Ok + | _ => REExpectedType("Boolean")->Error + } + ) + } + let expandExpressionList = (aList, bindings: ExpressionT.bindings, environment): result< expressionWithContext, errorValue, @@ -162,6 +179,8 @@ let dispatchMacroCall = ( lambdaDefinition, } => doLambdaDefinition(bindings, parameters, lambdaDefinition) + | list{ExpressionT.EValue(EvCall("$$ternary")), condition, ifTrue, ifFalse} => + doTernary(condition, ifTrue, ifFalse, bindings, environment) | _ => ExpressionWithContext.noContext(ExpressionT.EList(aList))->Ok } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res index 7964c3a4..4d859a79 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res @@ -13,6 +13,7 @@ type errorValue = | RESymbolNotFound(string) | RESyntaxError(string) | RETodo(string) // To do + | REExpectedType(string) type t = errorValue @@ -46,4 +47,5 @@ let errorToString = err => | RESymbolNotFound(symbolName) => `${symbolName} is not defined` | RESyntaxError(desc) => `Syntax Error: ${desc}` | RETodo(msg) => `TODO: ${msg}` + | REExpectedType(typeName) => `Expected type: ${typeName}` } From 2cc40970212a54e6a7f603ce842749c6d24e39ad Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Wed, 4 May 2022 20:54:18 +0000 Subject: [PATCH 146/146] Format reducer code --- packages/squiggle-lang/src/rescript/Reducer/Reducer.res | 7 +------ packages/squiggle-lang/src/rescript/Reducer/Reducer.resi | 1 - 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res index 0ea1a733..3b3450c3 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res @@ -19,12 +19,7 @@ let foreignFunctionInterface = ( argArray: array, environment: ExpressionValue.environment, ) => { - Lambda.foreignFunctionInterface( - lambdaValue, - argArray, - environment, - Expression.reduceExpression, - ) + Lambda.foreignFunctionInterface(lambdaValue, argArray, environment, Expression.reduceExpression) } let defaultEnvironment = ExpressionValue.defaultEnvironment diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi index 2cd4155b..d4e40a63 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi @@ -12,7 +12,6 @@ type externalBindings = ReducerInterface_ExpressionValue.externalBindings @genType type lambdaValue = ReducerInterface_ExpressionValue.lambdaValue - @genType let evaluateUsingOptions: ( ~environment: option,