diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res index 682e1737..fb891bb3 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res @@ -18,7 +18,7 @@ describe("builtin", () => { testEval("2>1", "Ok(true)") testEval("concat('a','b')", "Ok('ab')") testEval( - "addOne(t)=t+1; toInternalSampleArray(mapSamples(fromSamples([1,2,3,4,5,6]), addOne))", + "addOne(t)=t+1; toList(mapSamples(fromSamples([1,2,3,4,5,6]), addOne))", "Ok([2,3,4,5,6,7])", ) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_type_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_type_test.res index 05ec5722..e5609aea 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_type_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_type_test.res @@ -88,8 +88,8 @@ describe("Peggy Types to Expression", () => { }) describe("squiggle expressions in type modifiers", () => { testToExpression( - "odds1 = [1,3,5]; odds2 = [7, 9]; type odds = number<-memberOf(odds1 + odds2)", - "{(:$_let_$ :odds1 {(:$_constructArray_$ (1 3 5))}); (:$_let_$ :odds2 {(:$_constructArray_$ (7 9))}); (:$_typeAlias_$ #odds (:$_typeModifier_memberOf_$ #number (:add :odds1 :odds2)))}", + "odds1 = [1,3,5]; odds2 = [7, 9]; type odds = number<-memberOf(concat(odds1, odds2))", + "{(:$_let_$ :odds1 {(:$_constructArray_$ (1 3 5))}); (:$_let_$ :odds2 {(:$_constructArray_$ (7 9))}); (:$_typeAlias_$ #odds (:$_typeModifier_memberOf_$ #number (:concat :odds1 :odds2)))}", ~v="{_typeAliases_: {odds: {typeTag: 'typeIdentifier',typeIdentifier: #number,memberOf: [1,3,5,7,9]}},odds1: [1,3,5],odds2: [7,9]}", (), ) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res index 5414f827..f3df0962 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res @@ -7,7 +7,7 @@ describe("map reduce", () => { 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])") + testEvalToBe("check(x)=(x==2);arr=[1,2,3]; filter(arr,check)", "Ok([2])") }) Skip.describe("map reduce (sam)", () => { diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index 845d2ffc..22323e80 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -47,6 +47,9 @@ type fnDefinition = { type function = { name: string, definitions: array, + examples: option, + description: option, + isExperimental: bool, } type registry = array @@ -57,10 +60,10 @@ module FRType = { switch t { | FRTypeNumber => "number" | FRTypeNumeric => "numeric" - | FRTypeDistOrNumber => "frValueDistOrNumber" + | FRTypeDistOrNumber => "distribution|number" | FRTypeRecord(r) => { let input = ((name, frType): frTypeRecordParam) => `${name}: ${toString(frType)}` - `record({${r->E.A2.fmap(input)->E.A2.joinWith(", ")}})` + `{${r->E.A2.fmap(input)->E.A2.joinWith(", ")}}` } | FRTypeArray(r) => `list(${toString(r)})` | FRTypeLambda => `lambda` @@ -331,13 +334,34 @@ module FnDefinition = { module Function = { type t = function - let make = (~name, ~definitions): t => { + type functionJson = { + name: string, + definitions: array, + examples: option, + description: option, + isExperimental: bool, + } + + let make = (~name, ~definitions, ~examples=?, ~description=?, ~isExperimental=false, ()): t => { name: name, definitions: definitions, + examples: examples, + isExperimental: isExperimental, + description: description, + } + + let toJson = (t: t): functionJson => { + name: t.name, + definitions: t.definitions->E.A2.fmap(FnDefinition.toString), + examples: t.examples, + description: t.description, + isExperimental: t.isExperimental, } } module Registry = { + let toJson = (r: registry) => r->E.A2.fmap(Function.toJson) + /* There's a (potential+minor) bug here: If a function definition is called outside of the calls to the registry, then it's possible that there could be a match after the registry is @@ -350,6 +374,7 @@ module Registry = { ~env: DistributionOperation.env, ) => { let matchToDef = m => Matcher.Registry.matchToDef(registry, m) + //Js.log(toSimple(registry)) let showNameMatchDefinitions = matches => { let defs = matches diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index 13c49991..74929c0b 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -57,6 +57,7 @@ let registry = [ ~run=(inputs, _) => inputsTodist(inputs, r => Continuous(Continuous.make(r))), ), ], + (), ), Function.make( ~name="toDiscretePointSet", @@ -67,6 +68,7 @@ let registry = [ ~run=(inputs, _) => inputsTodist(inputs, r => Discrete(Discrete.make(r))), ), ], + (), ), Function.make( ~name="Declaration", @@ -75,9 +77,13 @@ let registry = [ inputs->getOrError(0)->E.R.bind(Declaration.fromExpressionValue) }), ], + (), ), Function.make( ~name="Normal", + ~examples=`normal(5,1) +normal({p5: 4, p95: 10}) +normal({mean: 5, stdev: 2})`, ~definitions=[ TwoArgDist.make("normal", twoArgs(SymbolicDist.Normal.make)), TwoArgDist.makeRecordP5P95("normal", r => @@ -85,9 +91,13 @@ let registry = [ ), TwoArgDist.makeRecordMeanStdev("normal", twoArgs(SymbolicDist.Normal.make)), ], + (), ), Function.make( ~name="Lognormal", + ~examples=`lognormal(0.5, 0.8) +lognormal({p5: 4, p95: 10}) +lognormal({mean: 5, stdev: 2})`, ~definitions=[ TwoArgDist.make("lognormal", twoArgs(SymbolicDist.Lognormal.make)), TwoArgDist.makeRecordP5P95("lognormal", r => @@ -95,29 +105,43 @@ let registry = [ ), TwoArgDist.makeRecordMeanStdev("lognormal", twoArgs(SymbolicDist.Lognormal.fromMeanAndStdev)), ], + (), ), Function.make( ~name="Uniform", + ~examples=`uniform(10, 12)`, ~definitions=[TwoArgDist.make("uniform", twoArgs(SymbolicDist.Uniform.make))], + (), ), Function.make( ~name="Beta", + ~examples=`beta(20, 25)`, ~definitions=[TwoArgDist.make("beta", twoArgs(SymbolicDist.Beta.make))], + (), ), Function.make( ~name="Cauchy", + ~examples=`cauchy(5, 1)`, ~definitions=[TwoArgDist.make("cauchy", twoArgs(SymbolicDist.Cauchy.make))], + (), ), Function.make( ~name="Gamma", + ~examples=`gamma(5, 1)`, ~definitions=[TwoArgDist.make("gamma", twoArgs(SymbolicDist.Gamma.make))], + (), ), Function.make( ~name="Logistic", + ~examples=`gamma(5, 1)`, ~definitions=[TwoArgDist.make("logistic", twoArgs(SymbolicDist.Logistic.make))], + (), ), Function.make( - ~name="To", + ~name="To (Distribution)", + ~examples=`5 to 10 +to(5,10) +-5 to 5`, ~definitions=[ TwoArgDist.make("to", twoArgs(SymbolicDist.From90thPercentile.make)), TwoArgDist.make( @@ -125,63 +149,149 @@ let registry = [ twoArgs(SymbolicDist.From90thPercentile.make), ), ], + (), ), Function.make( ~name="Exponential", + ~examples=`exponential(2)`, ~definitions=[OneArgDist.make("exponential", SymbolicDist.Exponential.make)], + (), ), Function.make( ~name="Bernoulli", + ~examples=`bernoulli(0.5)`, ~definitions=[OneArgDist.make("bernoulli", SymbolicDist.Bernoulli.make)], + (), + ), + Function.make( + ~name="PointMass", + ~examples=`pointMass(0.5)`, + ~definitions=[OneArgDist.make("pointMass", SymbolicDist.Float.makeSafe)], + (), + ), + Function.make( + ~name="toContinuousPointSet", + ~description="Converts a set of points to a continuous distribution", + ~examples=`toContinuousPointSet([ + {x: 0, y: 0.1}, + {x: 1, y: 0.2}, + {x: 2, y: 0.15}, + {x: 3, y: 0.1} +])`, + ~definitions=[ + FnDefinition.make( + ~name="toContinuousPointSet", + ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], + ~run=(inputs, _) => inputsTodist(inputs, r => Continuous(Continuous.make(r))), + ), + ], + (), + ), + Function.make( + ~name="toDiscretePointSet", + ~description="Converts a set of points to a discrete distribution", + ~examples=`toDiscretePointSet([ + {x: 0, y: 0.1}, + {x: 1, y: 0.2}, + {x: 2, y: 0.15}, + {x: 3, y: 0.1} +])`, + ~definitions=[ + FnDefinition.make( + ~name="toDiscretePointSet", + ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], + ~run=(inputs, _) => inputsTodist(inputs, r => Discrete(Discrete.make(r))), + ), + ], + (), + ), + Function.make( + ~name="Declaration (Continuous Function)", + ~description="Adds metadata to a function of the input ranges. Works now for numeric and date inputs. This is useful when making predictions. It allows you to limit the domain that your prediction will be used and scored within.", + ~examples=`declareFn({ + fn: {|a,b| a }, + inputs: [ + {min: 0, max: 100}, + {min: 30, max: 50} + ] +})`, + ~definitions=[ + FnDefinition.make(~name="declareFn", ~inputs=[Declaration.frType], ~run=(inputs, _) => { + inputs->E.A.unsafe_get(0)->Declaration.fromExpressionValue + }), + ], + ~isExperimental=true, + (), + ), + Function.make( + ~name="Floor", + ~definitions=[NumberToNumber.make("floor", Js.Math.floor_float)], + (), + ), + Function.make( + ~name="Ceiling", + ~definitions=[NumberToNumber.make("ceil", Js.Math.ceil_float)], + (), ), - Function.make(~name="Floor", ~definitions=[NumberToNumber.make("floor", Js.Math.floor_float)]), - Function.make(~name="Ceiling", ~definitions=[NumberToNumber.make("ceil", Js.Math.ceil_float)]), Function.make( ~name="Absolute Value", ~definitions=[NumberToNumber.make("abs", Js.Math.abs_float)], + (), ), - Function.make(~name="Exponent", ~definitions=[NumberToNumber.make("exp", Js.Math.exp)]), - Function.make(~name="Log", ~definitions=[NumberToNumber.make("log", Js.Math.log)]), - Function.make(~name="Log Base 10", ~definitions=[NumberToNumber.make("log10", Js.Math.log10)]), - Function.make(~name="Log Base 2", ~definitions=[NumberToNumber.make("log2", Js.Math.log2)]), - Function.make(~name="Round", ~definitions=[NumberToNumber.make("round", Js.Math.round)]), + Function.make(~name="Exponent", ~definitions=[NumberToNumber.make("exp", Js.Math.exp)], ()), + Function.make(~name="Log", ~definitions=[NumberToNumber.make("log", Js.Math.log)], ()), + Function.make( + ~name="Log Base 10", + ~definitions=[NumberToNumber.make("log10", Js.Math.log10)], + (), + ), + Function.make(~name="Log Base 2", ~definitions=[NumberToNumber.make("log2", Js.Math.log2)], ()), + Function.make(~name="Round", ~definitions=[NumberToNumber.make("round", Js.Math.round)], ()), Function.make( ~name="Sum", ~definitions=[ArrayNumberDist.make("sum", r => r->E.A.Floats.sum->Wrappers.evNumber->Ok)], + (), ), Function.make( ~name="Product", ~definitions=[ ArrayNumberDist.make("product", r => r->E.A.Floats.product->Wrappers.evNumber->Ok), ], + (), ), Function.make( ~name="Min", ~definitions=[ArrayNumberDist.make("min", r => r->E.A.Floats.min->Wrappers.evNumber->Ok)], + (), ), Function.make( ~name="Max", ~definitions=[ArrayNumberDist.make("max", r => r->E.A.Floats.max->Wrappers.evNumber->Ok)], + (), ), Function.make( ~name="Mean", ~definitions=[ArrayNumberDist.make("mean", r => r->E.A.Floats.mean->Wrappers.evNumber->Ok)], + (), ), Function.make( ~name="Geometric Mean", ~definitions=[ ArrayNumberDist.make("geomean", r => r->E.A.Floats.geomean->Wrappers.evNumber->Ok), ], + (), ), Function.make( ~name="Standard Deviation", ~definitions=[ArrayNumberDist.make("stdev", r => r->E.A.Floats.stdev->Wrappers.evNumber->Ok)], + (), ), Function.make( ~name="Variance", ~definitions=[ ArrayNumberDist.make("variance", r => r->E.A.Floats.stdev->Wrappers.evNumber->Ok), ], + (), ), Function.make( ~name="First", @@ -190,6 +300,7 @@ let registry = [ r->E.A.first |> E.O.toResult(impossibleError) |> E.R.fmap(Wrappers.evNumber) ), ], + (), ), Function.make( ~name="Last", @@ -198,6 +309,7 @@ let registry = [ r->E.A.last |> E.O.toResult(impossibleError) |> E.R.fmap(Wrappers.evNumber) ), ], + (), ), Function.make( ~name="Sort", @@ -206,6 +318,7 @@ let registry = [ r->E.A.Floats.sort->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray->Ok ), ], + (), ), Function.make( ~name="Reverse", @@ -214,6 +327,7 @@ let registry = [ r->Belt_Array.reverse->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray->Ok ), ], + (), ), Function.make( ~name="Cumulative Sum", @@ -222,6 +336,7 @@ let registry = [ r->E.A.Floats.cumsum->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray->Ok ), ], + (), ), Function.make( ~name="Cumulative Prod", @@ -230,6 +345,7 @@ let registry = [ r->E.A.Floats.cumsum->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray->Ok ), ], + (), ), Function.make( ~name="Diff", @@ -238,6 +354,7 @@ let registry = [ r->E.A.Floats.diff->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray->Ok ), ], + (), ), Function.make( ~name="Dict.merge", @@ -259,6 +376,7 @@ let registry = [ }, ), ], + (), ), //TODO: Make sure that two functions can't have the same name. This causes chaos elsewhere. Function.make( @@ -275,6 +393,7 @@ let registry = [ ->E.R2.fmap(Wrappers.evRecord) ), ], + (), ), Function.make( ~name="Dict.keys", @@ -286,6 +405,7 @@ let registry = [ } ), ], + (), ), Function.make( ~name="Dict.values", @@ -301,6 +421,7 @@ let registry = [ } ), ], + (), ), Function.make( ~name="Dict.toList", @@ -322,6 +443,7 @@ let registry = [ } ), ], + (), ), Function.make( ~name="Dict.fromList", @@ -346,6 +468,7 @@ let registry = [ |> E.R2.bind(convertInternalItems) }), ], + (), ), Function.make( ~name="List.make", @@ -362,6 +485,7 @@ let registry = [ } }), ], + (), ), Function.make( ~name="upTo", @@ -376,5 +500,6 @@ let registry = [ ) ), ], + (), ), ] 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 33e63496..5d1ee5f3 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 @@ -282,12 +282,12 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce | ("$_typeModifier_opaque_$", [EvRecord(typeRecord)]) => typeModifier_opaque_update(typeRecord) | ("$_typeOr_$", [EvArray(arr)]) => typeOr(EvArray(arr)) | ("$_typeFunction_$", [EvArray(arr)]) => typeFunction(arr) - | ("add", [EvArray(aValueArray), EvArray(bValueArray)]) => doAddArray(aValueArray, bValueArray) - | ("add", [EvString(aValueString), EvString(bValueString)]) => + | ("concat", [EvArray(aValueArray), EvArray(bValueArray)]) => doAddArray(aValueArray, bValueArray) + | ("concat", [EvString(aValueString), EvString(bValueString)]) => doAddString(aValueString, bValueString) | ("inspect", [value, EvString(label)]) => inspectLabel(value, label) | ("inspect", [value]) => inspect(value) - | ("keep", [EvArray(aValueArray), EvLambda(aLambdaValue)]) => + | ("filter", [EvArray(aValueArray), EvLambda(aLambdaValue)]) => doKeepArray(aValueArray, aLambdaValue) | ("map", [EvArray(aValueArray), EvLambda(aLambdaValue)]) => doMapArray(aValueArray, aLambdaValue) | ("mapSamples", [EvDistribution(SampleSet(dist)), EvLambda(aLambdaValue)]) => diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res index 4e10dfa0..b11eda89 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res @@ -27,6 +27,7 @@ let dispatch = (call: EV.functionCall, _: DistributionOperation.env): option< EV.EvTimeDuration(DateTime.Duration.multiply(d1, d2))->Ok->Some | ("divide", [EvTimeDuration(d1), EvNumber(d2)]) => EV.EvTimeDuration(DateTime.Duration.divide(d1, d2))->Ok->Some + | ("divide", [EvTimeDuration(d1), EvTimeDuration(d2)]) => EV.EvNumber(d1 /. d2)->Ok->Some | _ => None } } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index 20b8498a..6ef3f7a6 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -200,8 +200,6 @@ let dispatchToGenericOutput = ( ): option => { let (fnName, args) = call switch (fnName, args) { - | ("delta", [EvNumber(f)]) => - SymbolicDist.Float.makeSafe(f)->SymbolicConstructors.symbolicResultToOutput | ("triangular" as fnName, [EvNumber(f1), EvNumber(f2), EvNumber(f3)]) => SymbolicConstructors.threeFloat(fnName) ->E.R.bind(r => r(f1, f2, f3)) @@ -279,8 +277,7 @@ let dispatchToGenericOutput = ( Helpers.toDistFn(ToSampleSet(Belt.Int.fromFloat(float)), dist, ~env) | ("toSampleSet", [EvDistribution(dist)]) => Helpers.toDistFn(ToSampleSet(env.sampleCount), dist, ~env) - | ("toInternalSampleArray", [EvDistribution(SampleSet(dist))]) => - Some(FloatArray(SampleSetDist.T.get(dist))) + | ("toList", [EvDistribution(SampleSet(dist))]) => Some(FloatArray(SampleSetDist.T.get(dist))) | ("fromSamples", [EvArray(inputArray)]) => { let _wrapInputErrors = x => SampleSetDist.NonNumericInput(x) let parsedArray = Helpers.parseNumberArray(inputArray)->E.R2.errMap(_wrapInputErrors) diff --git a/packages/website/docs/Api/Date.md b/packages/website/docs/Api/Date.md new file mode 100644 index 00000000..4c50f582 --- /dev/null +++ b/packages/website/docs/Api/Date.md @@ -0,0 +1,42 @@ +--- +sidebar_position: 1 +title: Date +--- + +### makeFromYear + +``` +Date.makeFromYear: (number) => date +``` + +```js +makeFromYear(2022.32); +``` + +### toString + +``` +toString: (date) => string +``` + +### subtract + +``` +subtract: (date, date) => duration +subtract: (date, duration) => date +``` + +```js +makeFromYear(2040) - makeFromYear(2020); // 20 years +makeFromYear(2040) - years(20); // 2020 +``` + +### add + +``` +add: (date, duration) => date +``` + +```js +makeFromYear(2022.32) + years(5); +``` diff --git a/packages/website/docs/Api/Dictionary.md b/packages/website/docs/Api/Dictionary.md new file mode 100644 index 00000000..136342d2 --- /dev/null +++ b/packages/website/docs/Api/Dictionary.md @@ -0,0 +1,71 @@ +--- +sidebar_position: 2 +title: Dictionary +--- + +### toList + +``` +Dict.toList: (dict<'a>) => list> +``` + +```js +Dict.toList({ foo: 3, bar: 20 }); // [["foo", 3], ["bar", 20]] +``` + +### fromList + +``` +Dict.fromList: (list>) => dict<'a> +``` + +```js +Dict.fromList([ + ["foo", 3], + ["bar", 20], +]); // {foo: 3, bar: 20} +``` + +### keys + +``` +Dict.keys: (dict<'a>) => list +``` + +```js +Dict.keys({ foo: 3, bar: 20 }); // ["foo", "bar"] +``` + +### values + +``` +Dict.values: (dict<'a>) => list<'a> +``` + +```js +Dict.values({ foo: 3, bar: 20 }); // [3, 20] +``` + +### merge + +``` +Dict.merge: (dict<'a>, dict<'b>) => dict<'a|b> +``` + +```js +first = { a: 1, b: 2 }; +snd = { b: 3, c: 5 }; +Dict.merge(first, snd); // {a: 1, b: 3, c: 5} +``` + +### mergeMany + +``` +Dict.mergeMany: (list>) => dict<'a> +``` + +```js +first = { a: 1, b: 2 }; +snd = { b: 3, c: 5 }; +Dict.mergeMany([first, snd]); // {a: 1, b: 3, c: 5} +``` diff --git a/packages/website/docs/Api/DistGeneric.mdx b/packages/website/docs/Api/DistGeneric.mdx new file mode 100644 index 00000000..d70476e5 --- /dev/null +++ b/packages/website/docs/Api/DistGeneric.mdx @@ -0,0 +1,647 @@ +--- +sidebar_position: 3 +title: Distribution +--- + +import TOCInline from "@theme/TOCInline"; + + + +## Distribution Creation + +### Normal Distribution + +**Definitions** + +```javascript +normal: (frValueDistOrNumber, frValueDistOrNumber) => distribution; +``` + +```javascript +normal: (dict<{p5: frValueDistOrNumber, p95: frValueDistOrNumber}>) => distribution +``` + +```javascript +normal: (dict<{mean: frValueDistOrNumber, stdev: frValueDistOrNumber}>) => distribution +``` + +**Examples** + +```js +normal(5, 1); +normal({ p5: 4, p95: 10 }); +normal({ mean: 5, stdev: 2 }); +``` + +### Lognormal Distribution + +**Definitions** + +```javascript +lognormal: (frValueDistOrNumber, frValueDistOrNumber) => distribution; +``` + +```javascript +lognormal: (dict<{p5: frValueDistOrNumber, p95: frValueDistOrNumber}>) => distribution +``` + +```javascript +lognormal: (dict<{mean: frValueDistOrNumber, stdev: frValueDistOrNumber}>) => distribution +``` + +**Examples** + +```javascript +lognormal(0.5, 0.8); +lognormal({ p5: 4, p95: 10 }); +lognormal({ mean: 5, stdev: 2 }); +``` + +### Uniform Distribution + +**Definitions** + +```javascript +uniform: (frValueDistOrNumber, frValueDistOrNumber) => distribution; +``` + +**Examples** + +```javascript +uniform(10, 12); +``` + +### Beta Distribution + +**Definitions** + +```javascript +beta: (frValueDistOrNumber, frValueDistOrNumber) => distribution; +``` + +**Examples** + +```javascript +beta(20, 25); +``` + +### Cauchy Distribution + +**Definitions** + +```javascript +cauchy: (frValueDistOrNumber, frValueDistOrNumber) => distribution; +``` + +**Examples** + +```javascript +cauchy(5, 1); +``` + +### Gamma Distribution + +**Definitions** + +```javascript +gamma: (frValueDistOrNumber, frValueDistOrNumber) => distribution; +``` + +**Examples** + +```javascript +gamma(5, 1); +``` + +### Logistic Distribution + +**Definitions** + +```javascript +logistic: (frValueDistOrNumber, frValueDistOrNumber) => distribution; +``` + +**Examples** + +```javascript +gamma(5, 1); +``` + +### To (Distribution) + +**Definitions** + +```javascript +to: (frValueDistOrNumber, frValueDistOrNumber) => distribution; +``` + +```javascript +credibleIntervalToDistribution(frValueDistOrNumber, frValueDistOrNumber) => distribution; +``` + +**Examples** + +```javascript +5 to 10 +to(5,10) +-5 to 5 +``` + +### Exponential + +**Definitions** + +```javascript +exponential: (frValueDistOrNumber) => distribution; +``` + +**Examples** + +```javascript +exponential(2); +``` + +### Bernoulli + +**Definitions** + +```javascript +bernoulli: (frValueDistOrNumber) => distribution; +``` + +**Examples** + +```javascript +bernoulli(0.5); +``` + +### toContinuousPointSet + +Converts a set of points to a continuous distribution + +**Definitions** + +```javascript +toContinuousPointSet: (array>) => distribution +``` + +**Examples** + +```javascript +toContinuousPointSet([ + { x: 0, y: 0.1 }, + { x: 1, y: 0.2 }, + { x: 2, y: 0.15 }, + { x: 3, y: 0.1 }, +]); +``` + +### toDiscretePointSet + +Converts a set of points to a discrete distribution + +**Definitions** + +```javascript +toDiscretePointSet: (array>) => distribution +``` + +**Examples** + +```javascript +toDiscretePointSet([ + { x: 0, y: 0.1 }, + { x: 1, y: 0.2 }, + { x: 2, y: 0.15 }, + { x: 3, y: 0.1 }, +]); +``` + +## Functions + +### mixture + +```javascript +mixture: (...distributionLike, weights:list) => distribution +``` + +**Examples** + +```javascript +mixture(normal(5, 1), normal(10, 1)); +mx(normal(5, 1), normal(10, 1), [0.3, 0.7]); +``` + +### sample + +Get one random sample from the distribution + +```javascript +sample(distribution) => number +``` + +**Examples** + +```javascript +sample(normal(5, 2)); +``` + +### sampleN + +Get n random samples from the distribution + +```javascript +sampleN: (distribution, number) => list +``` + +**Examples** + +```javascript +sample: normal(5, 2), 100; +``` + +### mean + +Get the distribution mean + +```javascript +mean: (distribution) => number; +``` + +**Examples** + +```javascript +mean: normal(5, 2); +``` + +### stdev + +```javascript +stdev: (distribution) => number; +``` + +### variance + +```javascript +variance: (distribution) => number; +``` + +### mode + +```javascript +mode: (distribution) => number; +``` + +### cdf + +```javascript +cdf: (distribution, number) => number; +``` + +**Examples** + +```javascript +cdf: normal(5, 2), 3; +``` + +### pdf + +```javascript +pdf: (distribution, number) => number; +``` + +**Examples** + +```javascript +pdf(normal(5, 2), 3); +``` + +### inv + +```javascript +inv: (distribution, number) => number; +``` + +**Examples** + +```javascript +inv(normal(5, 2), 0.5); +``` + +### toPointSet + +Converts a distribution to the pointSet format + +```javascript +toPointSet: (distribution) => pointSetDistribution; +``` + +**Examples** + +```javascript +toPointSet(normal(5, 2)); +``` + +### toSampleSet + +Converts a distribution to the sampleSet format, with n samples + +```javascript +toSampleSet: (distribution, number) => sampleSetDistribution; +``` + +**Examples** + +```javascript +toSampleSet(normal(5, 2), 1000); +``` + +### truncateLeft + +Truncates the left side of a distribution. Returns either a pointSet distribution or a symbolic distribution. + +```javascript +truncateLeft: (distribution, l => number) => distribution +``` + +**Examples** + +```javascript +truncateLeft(normal(5, 2), 3); +``` + +### truncateRight + +Truncates the right side of a distribution. Returns either a pointSet distribution or a symbolic distribution. + +```javascript +truncateRight: (distribution, r => number) => distribution +``` + +**Examples** + +```javascript +truncateLeft(normal(5, 2), 6); +``` + +## Scoring + +### klDivergence + +Kullback–Leibler divergence between two distributions + +```javascript +klDivergence: (distribution, distribution) => number; +``` + +**Examples** + +```javascript +klDivergence(normal(5, 2), normal(5, 4)); // returns 0.57 +``` + +## Display + +### toString + +```javascript +toString: (distribution) => string; +``` + +**Examples** + +```javascript +toString(normal(5, 2)); +``` + +### toSparkline + +Produce a sparkline of length n + +```javascript +toSparkline: (distribution, n = 20) => string; +``` + +**Examples** + +```javascript +toSparkline(normal(5, 2), 10); +``` + +### inspect + +Prints the value of the distribution to the Javascript console, then returns the distribution. + +```javascript +inspect: (distribution) => distribution; +``` + +**Examples** + +```javascript +inspect(normal(5, 2)); +``` + +## Normalization + +### normalize + +Normalize a distribution. This means scaling it appropriately so that it's cumulative sum is equal to 1. + +```javascript +normalize: (distribution) => distribution; +``` + +**Examples** + +```javascript +normalize(normal(5, 2)); +``` + +### isNormalized + +Check of a distribution is normalized. Most distributions are typically normalized, but there are some commands that could produce non-normalized distributions. + +```javascript +isNormalized: (distribution) => bool; +``` + +**Examples** + +```javascript +isNormalized(normal(5, 2)); // returns true +``` + +### integralSum + +Get the sum of the integral of a distribution. If the distribution is normalized, this will be 1. + +```javascript +integralSum: (distribution) => number; +``` + +**Examples** + +```javascript +integralSum(normal(5, 2)); +``` + +## Algebraic Operations + +### add + +```javascript +add: (distributionLike, distributionLike) => distribution; +``` + +### sum + +```javascript +sum: (list) => distribution +``` + +### multiply + +```javascript +multiply: (distributionLike, distributionLike) => distribution; +``` + +### product + +```javascript +product: (list) => distribution +``` + +### subtract + +```javascript +subtract: (distributionLike, distributionLike) => distribution; +``` + +### divide + +```javascript +divide: (distributionLike, distributionLike) => distribution; +``` + +### pow + +```javascript +pow: (distributionLike, distributionLike) => distribution; +``` + +### exp + +```javascript +exp: (distributionLike, distributionLike) => distribution; +``` + +### log + +```javascript +log: (distributionLike, distributionLike) => distribution; +``` + +### log10 + +```javascript +log10: (distributionLike, distributionLike) => distribution; +``` + +### unaryMinus + +```javascript +unaryMinus: (distribution) => distribution; +``` + +## Pointwise Operations + +### dotAdd + +```javascript +dotAdd: (distributionLike, distributionLike) => distribution; +``` + +### dotMultiply + +```javascript +dotMultiply: (distributionLike, distributionLike) => distribution; +``` + +### dotSubtract + +```javascript +dotSubtract: (distributionLike, distributionLike) => distribution; +``` + +### dotDivide + +```javascript +dotDivide: (distributionLike, distributionLike) => distribution; +``` + +### dotPow + +```javascript +dotPow: (distributionLike, distributionLike) => distribution; +``` + +### dotExp + +```javascript +dotExp: (distributionLike, distributionLike) => distribution; +``` + +## Scale Operations + +### scaleMultiply + +```javascript +scaleMultiply: (distributionLike, number) => distribution; +``` + +### scalePow + +```javascript +scalePow: (distributionLike, number) => distribution; +``` + +### scaleExp + +```javascript +scaleExp: (distributionLike, number) => distribution; +``` + +### scaleLog + +```javascript +scaleLog: (distributionLike, number) => distribution; +``` + +### scaleLog10 + +```javascript +scaleLog10: (distributionLike, number) => distribution; +``` + +## Special + +### Declaration (Continuous Function) + +Adds metadata to a function of the input ranges. Works now for numeric and date inputs. This is useful when making predictions. It allows you to limit the domain that your prediction will be used and scored within. + +```javascript +declareFn: (dict<{fn: lambda, inputs: array>}>) => declaration +``` + +**Examples** + +```javascript +declareFn({ + fn: {|a,b| a }, + inputs: [ + {min: 0, max: 100}, + {min: 30, max: 50} + ] +}) +``` diff --git a/packages/website/docs/Api/DistPointSet.md b/packages/website/docs/Api/DistPointSet.md new file mode 100644 index 00000000..bf65ad68 --- /dev/null +++ b/packages/website/docs/Api/DistPointSet.md @@ -0,0 +1,22 @@ +--- +sidebar_position: 4 +title: Point Set Distribution +--- + +### make + +``` +PointSet.make: (distribution) => pointSetDist +``` + +### makeContinuous + +``` +PointSet.makeContinuous: (list<{x: number, y: number}>) => pointSetDist +``` + +### makeDiscrete + +``` +PointSet.makeDiscrete: (list<{x: number, y: number}>) => pointSetDist +``` diff --git a/packages/website/docs/Api/DistSampleSet.md b/packages/website/docs/Api/DistSampleSet.md new file mode 100644 index 00000000..9d0f5ed9 --- /dev/null +++ b/packages/website/docs/Api/DistSampleSet.md @@ -0,0 +1,44 @@ +--- +sidebar_position: 5 +title: Sample Set Distribution +--- + +### make + +``` +SampleSet.make: (distribution) => sampleSet +SampleSet.make: (() => number) => sampleSet +SampleSet.make: (list) => sampleSet +``` + +### map + +``` +SampleSet.map: (sampleSet, (number => number)) => sampleSet +``` + +### map2 + +``` +SampleSet.map2: (sampleSet, sampleSet, ((number, number) => number)) => sampleSet +``` + +### map3 + +``` +SampleSet.map3: (sampleSet, sampleSet, sampleSet, ((number, number, number) => number)) => sampleSet +``` + +### toList + +``` +SampleSet.toList: (sampleSet) => list +``` + +Gets the internal samples of a sampleSet distribution. This is separate from the sampleN() function, which would shuffle the samples. toList() maintains order and length. Gets the internal samples of a sampleSet distribution. This is separate from the sampleN() function, which would shuffle the samples. toList() maintains order and length. + +**Examples** + +``` +toList(toSampleSet(normal(5,2))) +``` diff --git a/packages/website/docs/Api/Duration.mdx b/packages/website/docs/Api/Duration.mdx new file mode 100644 index 00000000..6f81a352 --- /dev/null +++ b/packages/website/docs/Api/Duration.mdx @@ -0,0 +1,90 @@ +--- +sidebar_position: 6 +title: Duration +--- + +import TOCInline from "@theme/TOCInline"; + + + +### toString + +``` +toString: (duration) => string +``` + +## Units + +### minutes + +``` +minutes: (number) => duration +``` + +### hours + +``` +hours: (number) => duration +``` + +### days + +``` +days: (number) => duration +``` + +### years + +``` +years: (number) => duration +``` + +### toHours + +``` +toHours: (duration) => number +``` + +### toMinutes + +``` +toMinutes: (duration) => number +``` + +### toDays + +``` +toDays: (duration) => number +``` + +### toYears + +``` +toYears: (duration) => number +``` + +## Algebra + +### add + +``` +add: (duration, duration) => duration +``` + +### subtract + +``` +subtract: (duration, duration) => duration +``` + +### multiply + +``` +multiply: (duration, number) => duration +``` + +### divide + +``` +divide: (duration, number) => duration +``` diff --git a/packages/website/docs/Api/List.md b/packages/website/docs/Api/List.md new file mode 100644 index 00000000..c6d89e7d --- /dev/null +++ b/packages/website/docs/Api/List.md @@ -0,0 +1,94 @@ +--- +sidebar_position: 7 +title: List +--- + +### make + +``` +List.make: (number, 'a) => list<'a> +``` + +Returns an array of size `n` filled with value `e`. + +```js +List.make(4, 1); // creates the list [1, 1, 1, 1] +``` + +See [Rescript implementation](https://rescript-lang.org/docs/manual/latest/api/belt/array#make) + +### toString + +``` +toString: (list<'a>) => string +``` + +### length + +``` +length: (list<'a>) => number +``` + +### up to + +``` +List.upTo: (low:number, high:number) => list +``` + +```js +List.upTo(0, 5); // creates the list [0, 1, 2, 3, 4, 5] +``` + +Syntax taken from [Ruby](https://apidock.com/ruby/v2_5_5/Integer/upto). + +### first + +``` +first: (list<'a>) => 'a +``` + +### last + +``` +last: (list<'a>) => 'a +``` + +### reverse + +``` +reverse: (list<'a>) => list<'a> +``` + +### map + +``` +map: (list<'a>, a => b) => list<'b> +``` + +See [Rescript implementation](https://rescript-lang.org/docs/manual/latest/api/belt/array#map). + +### reduce + +``` +reduce: (list<'b>, 'a, ('a, 'b) => 'a) => 'a +``` + +`reduce(arr, init, f)` + +Applies `f` to each element of `arr`. The function `f` has two paramaters, an accumulator and the next value from the array. + +```js +reduce([2, 3, 4], 1, {|acc, value| acc + value}) == 10 +``` + +See [Rescript implementation](https://rescript-lang.org/docs/manual/latest/api/belt/array#reduce). + +### reduce reverse + +``` +reduceReverse: (list<'b>, 'a, ('a, 'b) => 'a) => 'a +``` + +Works like `reduce`, but the function is applied to each item from the last back to the first. + +See [Rescript implementation](https://rescript-lang.org/docs/manual/latest/api/belt/array#reducereverse). diff --git a/packages/website/docs/Api/Math.md b/packages/website/docs/Api/Math.md new file mode 100644 index 00000000..37f3fe1d --- /dev/null +++ b/packages/website/docs/Api/Math.md @@ -0,0 +1,84 @@ +--- +sidebar_position: 8 +title: Math +--- + +### E + +``` +Math.E: +``` + +Euler's number; ≈ 2.718281828459045 + +### LN2 + +``` +Math.LN2: +``` + +Natural logarithm of 2; ≈ 0.6931471805599453 + +### LN10 + +``` +Math.LN10: +``` + +Natural logarithm of 10; ≈ 2.302585092994046 + +### LOG2E + +``` +Math.LOG2E: +``` + +Base 2 logarithm of E; ≈ 1.4426950408889634Base 2 logarithm of E; ≈ 1.4426950408889634 + +### LOG10E + +``` +Math.LOG10E: +``` + +Base 10 logarithm of E; ≈ 0.4342944819032518 + +### PI + +``` +Math.PI: +``` + +Pi - ratio of the circumference to the diameter of a circle; ≈ 3.141592653589793 + +### SQRT1_2 + +``` +Math.SQRT1_2: +``` + +Square root of 1/2; ≈ 0.7071067811865476 + +### SQRT2 + +``` +Math.SQRT2: +``` + +Square root of 2; ≈ 1.4142135623730951 + +### PHI + +``` +Math.PHI: +``` + +Phi is the golden ratio. 1.618033988749895 + +### TAU + +``` +Math.TAU: +``` + +Tau is the ratio constant of a circle's circumference to radius, equal to 2 \* pi. 6.283185307179586 diff --git a/packages/website/docs/Api/Number.mdx b/packages/website/docs/Api/Number.mdx new file mode 100644 index 00000000..6e4015c2 --- /dev/null +++ b/packages/website/docs/Api/Number.mdx @@ -0,0 +1,144 @@ +--- +sidebar_position: 9 +title: Number +--- + +import TOCInline from "@theme/TOCInline"; + + + +### ceil + +```javascript +ceil: (number) => number; +``` + +### floor + +```javascript +floor: (number) => number; +``` + +### abs + +```javascript +abs: (number) => number; +``` + +### round + +```javascript +round: (number) => number; +``` + +## Statistics + +### max + +```javascript +max: (list) => number +``` + +### min + +```javascript +min: (list) => number +``` + +### mean + +```javascript +mean: (list) => number +``` + +### stdev + +```javascript +stdev: (list) => number +``` + +### variance + +```javascript +variance: (list) => number +``` + +## Algebra + +### unaryMinus + +```javascript +unaryMinus: (number) => number; +``` + +### equal + +```javascript +equal: (number, number) => boolean; +``` + +### add + +```javascript +add: (number, number) => number; +``` + +### sum + +```javascript +sum: (list) => number +``` + +### cumulative sum + +``` +cumsum: (list) => list +``` + +### multiply + +```javascript +multiply: (number, number) => number; +``` + +### product + +```javascript +product: (list) => number +``` + +### cumulative product + +``` +cumprod: (list) => list +``` + +### subtract + +```javascript +subtract: (number, number) => number; +``` + +### divide + +```javascript +divide: (number, number) => number; +``` + +### pow + +```javascript +pow: (number, number) => number; +``` + +### exp + +```javascript +exp: (number) => number; +``` + +### log + +```javascript +log: (number) => number; +``` diff --git a/packages/website/docs/Features/Distributions.mdx b/packages/website/docs/Guides/Distributions.mdx similarity index 99% rename from packages/website/docs/Features/Distributions.mdx rename to packages/website/docs/Guides/Distributions.mdx index 6cc5967d..2688f398 100644 --- a/packages/website/docs/Features/Distributions.mdx +++ b/packages/website/docs/Guides/Distributions.mdx @@ -1,16 +1,13 @@ --- title: "Distribution Creation" -sidebar_position: 2 +sidebar_position: 20 --- -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: number) to (95thPercentile: number)` diff --git a/packages/website/docs/Features/Functions.mdx b/packages/website/docs/Guides/Functions.mdx similarity index 100% rename from packages/website/docs/Features/Functions.mdx rename to packages/website/docs/Guides/Functions.mdx diff --git a/packages/website/docs/Features/Language.mdx b/packages/website/docs/Guides/Language.mdx similarity index 100% rename from packages/website/docs/Features/Language.mdx rename to packages/website/docs/Guides/Language.mdx diff --git a/packages/website/docs/Features/Node-Packages.md b/packages/website/docs/Guides/Node-Packages.md similarity index 100% rename from packages/website/docs/Features/Node-Packages.md rename to packages/website/docs/Guides/Node-Packages.md diff --git a/packages/website/docs/Introduction.md b/packages/website/docs/Introduction.md index e81b0782..35ff63b6 100644 --- a/packages/website/docs/Introduction.md +++ b/packages/website/docs/Introduction.md @@ -9,8 +9,8 @@ Squiggle is an _estimation language_, and a syntax for _calculating and expressi - [Gallery](./Discussions/Gallery) - [Squiggle playground](/playground) -- [Language basics](./Features/Language) -- [Squiggle functions source of truth](./docs/Features/Functions) +- [Language basics](./Guides/Language) +- [Squiggle functions source of truth](./docs/Guides/Functions) - [Known bugs](./Discussions/Bugs) - [Original lesswrong sequence](https://www.lesswrong.com/s/rDe8QE5NvXcZYzgZ3) - [Author your squiggle models as Observable notebooks](https://observablehq.com/@hazelfire/squiggle) diff --git a/packages/website/docusaurus.config.js b/packages/website/docusaurus.config.js index 330002ef..4152ae6e 100644 --- a/packages/website/docusaurus.config.js +++ b/packages/website/docusaurus.config.js @@ -18,9 +18,7 @@ const config = { favicon: "img/favicon.ico", organizationName: "quantified-uncertainty", // Usually your GitHub org/user name. projectName: "squiggle", // Usually your repo name. - plugins: [], - presets: [ [ "classic", @@ -66,6 +64,12 @@ const config = { position: "left", label: "Documentation", }, + { + type: "doc", + docId: "Api/Dictionary", + position: "left", + label: "API", + }, { to: "/blog", label: "Blog", position: "left" }, { to: "/playground", label: "Playground", position: "left" }, { diff --git a/packages/website/sidebars.js b/packages/website/sidebars.js index 78ad249f..5c63ccb9 100644 --- a/packages/website/sidebars.js +++ b/packages/website/sidebars.js @@ -14,6 +14,12 @@ /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ const sidebars = { // By default, Docusaurus generates a sidebar from the docs folder structure + apiSidebar: [ + { + type: "autogenerated", + dirName: "Api", + }, + ], tutorialSidebar: [ { type: "doc", @@ -22,11 +28,11 @@ const sidebars = { }, { type: "category", - label: "Features", + label: "Guides", items: [ { type: "autogenerated", - dirName: "Features", + dirName: "Guides", }, ], },