From ba104e4dfea682094ddfcfdd8e5cbb9587198d19 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 2 May 2022 15:22:01 +0200 Subject: [PATCH 1/3] 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 2/3] 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 3/3] 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 })