From ac1e2ee9ae2c26bcddfbbde4203cfb58f266da8f Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Mon, 8 Jan 2024 21:35:55 -0800 Subject: [PATCH 1/9] Generic doc cleanup --- packages/squiggle-lang/src/fr/builtin.ts | 7 +++ packages/squiggle-lang/src/fr/danger.ts | 52 +------------------ packages/squiggle-lang/src/fr/date.ts | 19 +++---- packages/squiggle-lang/src/fr/dict.ts | 4 +- packages/squiggle-lang/src/fr/dist.ts | 2 +- packages/squiggle-lang/src/fr/genericDist.ts | 15 +++--- packages/squiggle-lang/src/fr/sampleset.ts | 15 ++++-- packages/squiggle-lang/src/fr/scoring.ts | 28 +++++----- packages/website/templates.mts | 54 ++++++++++++++------ 9 files changed, 93 insertions(+), 103 deletions(-) diff --git a/packages/squiggle-lang/src/fr/builtin.ts b/packages/squiggle-lang/src/fr/builtin.ts index 40d479fb50..53a104885a 100644 --- a/packages/squiggle-lang/src/fr/builtin.ts +++ b/packages/squiggle-lang/src/fr/builtin.ts @@ -17,6 +17,7 @@ const maker = new FnFactory({ export const library = [ maker.make({ name: "equal", + description: `Returns true if the two values passed in are equal, false otherwise. Does not work for Squiggle functions, but works for most other types.`, definitions: [ makeDefinition([frAny(), frAny()], frBool, ([a, b]) => { return isEqual(a, b); @@ -35,6 +36,12 @@ export const library = [ name: "typeOf", description: "Returns the type of the value passed in as a string. This is useful when you want to treat a value differently depending on its type.", + interactiveExamples: [ + `myString = typeOf("foo") +myBool = typeOf(true) +myDist = typeOf(5 to 10) +myFn = typeOf({|e| e})`, + ], definitions: [ makeDefinition([frAny()], frString, ([value]) => { return value.publicName; diff --git a/packages/squiggle-lang/src/fr/danger.ts b/packages/squiggle-lang/src/fr/danger.ts index 7b77b71563..9d7798d0b1 100644 --- a/packages/squiggle-lang/src/fr/danger.ts +++ b/packages/squiggle-lang/src/fr/danger.ts @@ -85,7 +85,7 @@ Danger.laplace(successes, trials) // (successes + 1) / (trials + 2) = 2 / 12 = }), maker.n2n({ name: "factorial", - displaySection: "Math", + displaySection: "Combinatorics", examples: [`Danger.factorial(20)`], fn: factorial, }), @@ -415,56 +415,6 @@ const diminishingReturnsLibrary = [ ]; const mapYLibrary: FRFunction[] = [ - maker.d2d({ - name: "mapYLog", - displaySection: "Distribution Functions", - fn: (dist, env) => unwrapDistResult(scaleLog(dist, Math.E, { env })), - }), - maker.d2d({ - name: "mapYLog10", - displaySection: "Distribution Functions", - fn: (dist, env) => unwrapDistResult(scaleLog(dist, 10, { env })), - }), - maker.dn2d({ - name: "mapYLog", - displaySection: "Distribution Functions", - fn: (dist, x, env) => unwrapDistResult(scaleLog(dist, x, { env })), - }), - maker.make({ - name: "mapYLogWithThreshold", - displaySection: "Distribution Functions", - definitions: [ - makeDefinition( - [frDist, frNumber, frNumber], - frDistPointset, - ([dist, base, eps], { environment }) => - unwrapDistResult( - scaleLogWithThreshold(dist, { - env: environment, - eps, - base, - }) - ) - ), - ], - }), - - maker.dn2d({ - name: "mapYMultiply", - displaySection: "Distribution Functions", - fn: (dist, f, env) => unwrapDistResult(scaleMultiply(dist, f, { env })), - }), - maker.dn2d({ - name: "mapYPow", - displaySection: "Distribution Functions", - fn: (dist, f, env) => unwrapDistResult(scalePower(dist, f, { env })), - }), - maker.d2d({ - name: "mapYExp", - displaySection: "Distribution Functions", - // TODO - shouldn't it be other way around, e^value? - fn: (dist, env) => unwrapDistResult(scalePower(dist, Math.E, { env })), - }), maker.make({ name: "binomialDist", examples: ["Danger.binomialDist(8, 0.5)"], diff --git a/packages/squiggle-lang/src/fr/date.ts b/packages/squiggle-lang/src/fr/date.ts index 913d8a6dee..2e212db4ac 100644 --- a/packages/squiggle-lang/src/fr/date.ts +++ b/packages/squiggle-lang/src/fr/date.ts @@ -32,11 +32,10 @@ export const library = [ maker.make({ name: "make", requiresNamespace: true, - examples: [ - 'Date.make("2020-05-12")', - "Date.make(2020, 5, 10)", - "Date.make(2020)", - "Date(2020.1)", + interactiveExamples: [ + `d1 = Date.make("2020-05-12") +d2 = Date.make(2020, 5, 10) +d3 = Date.make(2020.5)`, ], displaySection: "Constructors", output: "Date", @@ -96,7 +95,7 @@ export const library = [ }), maker.make({ name: "subtract", - examples: ["Date.make(2020, 5, 12) - Date.make(2000, 1, 1)"], + interactiveExamples: ["Date.make(2020, 5, 12) - Date.make(2000, 1, 1)"], output: "Duration", displaySection: "Algebra", definitions: [ @@ -107,7 +106,7 @@ export const library = [ }), maker.make({ name: "subtract", - examples: ["Date.make(2020, 5, 12) - 20years"], + interactiveExamples: ["Date.make(2020, 5, 12) - 20years"], output: "Date", displaySection: "Algebra", definitions: [ @@ -118,10 +117,8 @@ export const library = [ }), maker.make({ name: "add", - examples: [ - "Date.make(2020, 5, 12) + 20years", - "20years + Date.make(2020, 5, 12)", - ], + examples: ["Date.make(2020, 5, 12) + 20years"], + interactiveExamples: ["20years + Date.make(2020, 5, 12)"], output: "Date", displaySection: "Algebra", definitions: [ diff --git a/packages/squiggle-lang/src/fr/dict.ts b/packages/squiggle-lang/src/fr/dict.ts index dd6ffff33b..fbcb0c4371 100644 --- a/packages/squiggle-lang/src/fr/dict.ts +++ b/packages/squiggle-lang/src/fr/dict.ts @@ -208,7 +208,9 @@ Dict.mergeMany([first, snd]) // {a: 1, b: 3, c: 5}`, maker.make({ name: "mapKeys", output: "Dict", - examples: [`Dict.mapKeys({a: 1, b: 2}, {|x| concat(x, "-1")})`], + interactiveExamples: [ + `Dict.mapKeys({a: 1, b: 2, c: 5}, {|x| concat(x, "-foobar")})`, + ], displaySection: "Transformations", definitions: [ makeDefinition( diff --git a/packages/squiggle-lang/src/fr/dist.ts b/packages/squiggle-lang/src/fr/dist.ts index 2dba47faeb..5ae2355bed 100644 --- a/packages/squiggle-lang/src/fr/dist.ts +++ b/packages/squiggle-lang/src/fr/dist.ts @@ -79,7 +79,7 @@ export const library: FRFunction[] = [ "mixture(normal(5,2), normal(10,2), normal(15,2), [0.3, 0.5, 0.2])", "mixture([normal(5,2), normal(10,2), normal(15,2), normal(20,1)], [0.3, 0.5, 0.1, 0.1])", ], - description: `The mixture function takes a list of distributions and a list of weights, and returns a new distribution that is a mixture of the distributions in the list. The weights should be positive numbers that sum to 1. If no weights are provided, the function will assume that all distributions have equal weight. + description: `The \`\`mixture\`\` function takes a list of distributions and a list of weights, and returns a new distribution that is a mixture of the distributions in the list. The weights should be positive numbers that sum to 1. If no weights are provided, the function will assume that all distributions have equal weight. Note: If you want to pass in over 5 distributions, you must use the list syntax.`, definitions: mixtureDefinitions, diff --git a/packages/squiggle-lang/src/fr/genericDist.ts b/packages/squiggle-lang/src/fr/genericDist.ts index e679c96487..4a3475a8cd 100644 --- a/packages/squiggle-lang/src/fr/genericDist.ts +++ b/packages/squiggle-lang/src/fr/genericDist.ts @@ -105,7 +105,7 @@ export const library: FRFunction[] = [ name: "sparkline", displaySection: "Utility", description: ` -Produce a sparkline of length n. For example, \`▁▁▁▁▁▂▄▆▇██▇▆▄▂▁▁▁▁▁\`. These can be useful for testing or quick text visualizations.`, +Produce a sparkline of length \`\`n\`\`. For example, \`▁▁▁▁▁▂▄▆▇██▇▆▄▂▁▁▁▁▁\`. These can be useful for testing or quick visualizations that can be copied and pasted into text.`, definitions: [ makeDefinition( [frDist, frOptional(frNumber)], @@ -156,12 +156,7 @@ Produce a sparkline of length n. For example, \`▁▁▁▁▁▂▄▆▇█ displaySection: "Basic Functions", fn: (d) => unwrapDistResult(d.mode()), }), - maker.d2n({ - name: "integralSum", - displaySection: "Basic Functions", - description: `Get the sum of the integral of a distribution. If the distribution is normalized, this will be 1.0. This is useful for understanding unnormalized distributions.`, - fn: (d) => d.integralSum(), - }), + maker.d2n({ name: "sample", displaySection: "Basic Functions", @@ -207,6 +202,12 @@ Produce a sparkline of length n. For example, \`▁▁▁▁▁▂▄▆▇█ description: `Check if a distribution is normalized. This only impacts Point Set distributions, because those are the only ones that can be non-normlized. Most distributions are typically normalized, but there are some commands that could produce non-normalized distributions.`, fn: (d) => d.isNormalized(), }), + maker.d2n({ + name: "integralSum", + displaySection: "Normalization", + description: `Get the sum of the integral of a distribution. If the distribution is normalized, this will be 1.0. This is useful for understanding unnormalized distributions.`, + fn: (d) => d.integralSum(), + }), maker.dn2n({ name: "cdf", displaySection: "Basic Functions", diff --git a/packages/squiggle-lang/src/fr/sampleset.ts b/packages/squiggle-lang/src/fr/sampleset.ts index 1de753c36a..2c9d98aa4f 100644 --- a/packages/squiggle-lang/src/fr/sampleset.ts +++ b/packages/squiggle-lang/src/fr/sampleset.ts @@ -75,7 +75,7 @@ const baseLibrary = [ maker.make({ name: "make", description: - "Calls the correct conversion constructor, based on the corresponding input type, to create a Sample Set distribution.", + "Calls the correct conversion constructor, based on the corresponding input type, to create a sample set distribution", output: "Dist", examples: [ `SampleSet(5)`, @@ -87,19 +87,24 @@ const baseLibrary = [ }), maker.make({ name: "fromDist", - examples: [`SampleSet.fromDist(normal(5,2))`], + description: + "Converts any distribution type into a sample set distribution.", + examples: [`SampleSet.fromDist(Sym.normal(5,2))`], displaySection: "Conversions", definitions: [fromDist], }), maker.make({ name: "fromNumber", displaySection: "Conversions", + description: + "Convert a number into a sample set distribution that contains ``n`` copies of that number. ``n`` refers to the model sample count.", examples: [`SampleSet.fromNumber(3)`], definitions: [fromNumber], }), maker.make({ name: "fromList", displaySection: "Conversions", + description: "Convert a list of numbers into a sample set distribution.", examples: [`SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5,3,2,3,1,1,3])`], output: "Dist", definitions: [fromList], @@ -109,7 +114,7 @@ const baseLibrary = [ displaySection: "Conversions", examples: [`SampleSet.toList(SampleSet.fromDist(normal(5,2)))`], description: - "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.", output: "Array", definitions: [ makeDefinition([frSampleSetDist], frArray(frNumber), ([dist]) => { @@ -120,6 +125,8 @@ const baseLibrary = [ maker.make({ name: "fromFn", displaySection: "Conversions", + description: + "Convert a function into a sample set distribution by calling it ``n`` times.", examples: [`SampleSet.fromFn({|i| sample(normal(5,2))})`], output: "Dist", definitions: [fromFnDefinition], @@ -128,6 +135,7 @@ const baseLibrary = [ name: "map", displaySection: "Transformations", examples: [`SampleSet.map(SampleSet.fromDist(normal(5,2)), {|x| x + 1})`], + description: `Transforms a sample set distribution by applying a function to each sample. Returns a new sample set distribution.`, output: "Dist", definitions: [ makeDefinition( @@ -145,6 +153,7 @@ const baseLibrary = [ }), maker.make({ name: "map2", + description: `Transforms two sample set distributions by applying a function to each pair of samples. Returns a new sample set distribution.`, examples: [ `SampleSet.map2( SampleSet.fromDist(normal(5,2)), diff --git a/packages/squiggle-lang/src/fr/scoring.ts b/packages/squiggle-lang/src/fr/scoring.ts index df584bff4d..0f0abe48b8 100644 --- a/packages/squiggle-lang/src/fr/scoring.ts +++ b/packages/squiggle-lang/src/fr/scoring.ts @@ -54,6 +54,20 @@ const runScoringDistAnswer = ( }; export const library = [ + maker.make({ + name: "klDivergence", + output: "Number", + examples: ["Dist.klDivergence(Sym.normal(5,2), Sym.normal(5,1.5))"], + displaySection: "Scoring", + description: `[Kullback–Leibler divergence](https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence) between two distributions. + +Note that this can be very brittle. If the second distribution has probability mass at areas where the first doesn't, then the result will be infinite. Due to numeric approximations, some probability mass in point set distributions is rounded to zero, leading to infinite results with klDivergence.`, + definitions: [ + makeDefinition([frDist, frDist], frNumber, ([estimate, d], context) => + runScoringDistAnswer(estimate, d, undefined, context.environment) + ), + ], + }), maker.make({ name: "logScore", output: "Number", @@ -116,18 +130,4 @@ export const library = [ ), ], }), - maker.make({ - name: "klDivergence", - output: "Number", - examples: ["Dist.klDivergence(Sym.normal(5,2), Sym.normal(5,1.5))"], - displaySection: "Scoring", - description: `[Kullback–Leibler divergence](https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence) between two distributions. - -Note that this can be very brittle. If the second distribution has probability mass at areas where the first doesn't, then the result will be infinite. Due to numeric approximations, some probability mass in point set distributions is rounded to zero, leading to infinite results with klDivergence.`, - definitions: [ - makeDefinition([frDist, frDist], frNumber, ([estimate, d], context) => - runScoringDistAnswer(estimate, d, undefined, context.environment) - ), - ], - }), ]; diff --git a/packages/website/templates.mts b/packages/website/templates.mts index 10e3176c9f..81336cbeb3 100644 --- a/packages/website/templates.mts +++ b/packages/website/templates.mts @@ -11,7 +11,7 @@ export const modulePages: ModulePage[] = [ { name: "Common", description: "", - intro: `Functions that work on many different types of values.`, + intro: `Functions that work on many different types of values. Also see the experimental [Json functions](/docs/Api/Danger#json).`, }, { name: "Boolean", @@ -22,7 +22,15 @@ export const modulePages: ModulePage[] = [ { description: "Dates are a simple date time type.", name: "Date", - intro: ``, + intro: `A simple date type. Dates are stored as milliseconds since the epoch. They are immutable, and all functions that modify dates return a new date. Used with [Duration](./Duration) values. + + Dates can be useful for modeling values that change over time. Below is a simple example of a function that returns a normal distribution that changes over time, based on the number of years passed since 2020. + + `, sections: [ { name: "Constructors" }, { name: "Conversions" }, @@ -40,11 +48,19 @@ export const modulePages: ModulePage[] = [ ], description: "Squiggle dictionaries work similar to Python dictionaries. The syntax is similar to objects in Javascript.", - intro: ` -`, + intro: `Squiggle dictionaries work similar to Python dictionaries. The syntax is similar to objects in Javascript.`, }, { name: "Dist", + description: + "Distributions are the flagship data type in Squiggle. The distribution type is a generic data type that contains one of three different formats of distributions.", + intro: `Distributions are the flagship data type in Squiggle. The distribution type is a generic data type that contains one of three different formats of distributions. + +These subtypes are [point set](/docs/api/DistPointSet), [sample set](/docs/api/DistSampleSet), and [symbolic](/docs/api/Sym). The first two of these have a few custom functions that only work on them. You can read more about the differences between these formats [here](/docs/Discussions/Three-Formats-Of-Distributions). + +Several functions below only can work on particular distribution formats. For example, scoring and pointwise math requires the point set format. When this happens, the types are automatically converted to the correct format. These conversions are lossy. + +Distributions are created as [sample sets](/DistSampleSet) by default. To create a symbolic distribution, use \`Sym.\` namespace: \`Sym.normal\`, \`Sym.beta\` and so on.`, sections: [ { name: "Distributions", @@ -72,11 +88,6 @@ The only functions that do not return normalized distributions are the pointwise { name: "Utility" }, { name: "Scoring" }, ], - description: - "Point set distributions are one of the three distribution formats. They are stored as a list of x-y coordinates representing both discrete and continuous distributions.", - intro: `Point set distributions are one of the three distribution formats. They are stored as a list of x-y coordinates representing both discrete and continuous distributions. - -One complication is that it's possible to represent invalid probability distributions in the point set format. For example, you can represent shapes with negative values, or shapes that are not normalized.`, }, { name: "Sym", @@ -97,7 +108,7 @@ One complication is that it's possible to represent invalid probability distribu Monte Carlo calculations typically result in sample set distributions. -All regular distribution function work on sample set distributions. In addition, there are several functions that only work on sample set distributions..`, +All regular distribution function work on sample set distributions. In addition, there are several functions that only work on sample set distributions.`, }, { name: "PointSet", @@ -122,7 +133,7 @@ One complication is that it's possible to represent invalid probability distribu { name: "Algebra" }, { name: "Comparison" }, ], - intro: `Durations are a simple time type, representing a length of time. They are internally stored as milliseconds, but often shown and written using seconds, minutes, hours, days, etc. + intro: `Durations are a simple time type, representing a length of time. They are internally stored as milliseconds, but often shown and written using seconds, minutes, hours, days, etc. Durations are typically used with [Date](./Date) values. | **Unit Name** | **Example** | **Convert Number to Duration** | **Convert Duration to Number** | @@ -131,8 +142,6 @@ One complication is that it's possible to represent invalid probability distribu | Hour | \`5hour\` | \`fromHours(number)\` | \`toHours(duration)\` | | Day | \`5days\` | \`fromDays(number)\` | \`toDays(duration)\` | | Year | \`5years\` | \`fromYears(number)\` | \`toYears(duration)\` | - -This table now presents the information in a clear and concise manner, focusing only on the essential columns. `, }, { @@ -281,11 +290,26 @@ Calculators can be useful for debugging functions or to present functions to end description: "Newer experimental functions which are less stable than Squiggle as a whole", sections: [ - { name: "JSON" }, + { + name: "JSON", + description: ` +The JSON module provides JSON-like objects in Squiggle. \`\`Danger.json\`\`\ is mainly useful for debugging, and \`\`Danger.jsonString\`\`\ is useful for sending data to other systems. A simple example is shown below. + +We have custom serializers for different Squiggle objects. Note that this API is unstable and might change over time. + +`, + }, { name: "Math" }, { name: "Combinatorics" }, { name: "Distributions" }, - { name: "Distribution Functions" }, { name: "Integration" }, { name: "Optimization" }, ], From c70680ef319b87d4d7bf7853d8d613fecb50798d Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Wed, 10 Jan 2024 19:50:01 -0800 Subject: [PATCH 2/9] Small tag doc fixes --- packages/squiggle-lang/src/fr/tag.ts | 30 ++++++++++++++-------------- packages/website/templates.mts | 5 +++-- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/packages/squiggle-lang/src/fr/tag.ts b/packages/squiggle-lang/src/fr/tag.ts index 05a86aa2fb..2f87029093 100644 --- a/packages/squiggle-lang/src/fr/tag.ts +++ b/packages/squiggle-lang/src/fr/tag.ts @@ -176,13 +176,8 @@ export const library = [ maker.make({ name: "showAs", description: `Overrides the default visualization for a value. -\`showAs()\` can take either a visualization, or a function that calls the value and returns a visualization. You can use it like, -~~~squiggle -example1 = {|x| x + 1} -> Tag.showAs(Calculator) -//... -@showAs({|f| Plot.numericFn(f, { xScale: Scale.symlog() })}) -example2 = {|x| x + 1} -~~~ +\`showAs()\` can take either a visualization, or a function that calls the value and returns a visualization. + Different types of values can be displayed in different ways. The following table shows the potential visualization types for each input type. In this table, \`Number\` can be used with Dates and Durations as well. | **Input Type** | **Visualization Types** | | ----------------------------------- | ------------------------------------- | @@ -193,6 +188,12 @@ Different types of values can be displayed in different ways. The following tabl | **Function** | \`Calculator\` | `, displaySection: "Tags", + examples: [ + `example1 = {|x| x + 1} -> Tag.showAs(Calculator) +//... +@showAs({|f| Plot.numericFn(f, { xScale: Scale.symlog() })}) +example2 = {|x| x + 1}`, + ], definitions: [ showAsDef(frWithTags(frDist), frPlot), showAsDef(frArray(frAny()), frTableChart), @@ -288,23 +289,22 @@ Different types of values can be displayed in different ways. The following tabl maker.make({ name: "notebook", description: `Displays the list of values as a notebook. This means that element indices are hidden, and the values are displayed in a vertical list. Useful for displaying combinations of text and values.`, - examples: [ - `@notebook -showAsNotebook = [ + interactiveExamples: [ + `[ "### This is an opening section Here is more text. Here is more text.", Calculator({|f| f + 3}), - "## Distributions", - "### Distribution 1", + "### Distributions", + "#### Distribution 1", normal(5, 2), - "### Distribution 1", + "#### Distribution 1", normal(20, 1), - " ### This is an opening section + " #### This is an opening section Here is more text. ", -] `, +] -> Tag.notebook`, ], displaySection: "Tags", definitions: booleanTagDefs( diff --git a/packages/website/templates.mts b/packages/website/templates.mts index 81336cbeb3..469ef4ad94 100644 --- a/packages/website/templates.mts +++ b/packages/website/templates.mts @@ -244,16 +244,17 @@ Tags can be added to variables either by using their name \`Tag.[name]\` or by u | \`doc\` | Adds documentation to the variable in the playground. | | \`showAs\` | Change the default view for the value when displayed. | | \`format\` | Format a number, date, or duration when displayed. | +| \`notebook\` | Formats lists as notebooks. | | \`hide\` | Don't show the variable in the playground | -## Examples +## Example Date: Thu, 11 Jan 2024 16:10:30 -0800 Subject: [PATCH 3/9] Continued small docs improvements --- packages/squiggle-lang/src/fr/calculator.ts | 9 +- packages/squiggle-lang/src/fr/number.ts | 1 - packages/squiggle-lang/src/fr/string.ts | 4 +- packages/website/public/llms/prompt.txt | 162 +++++++++++------- .../src/pages/docs/Ecosystem/Tooling.md | 5 +- .../Guides/{Debugging.md => Debugging.mdx} | 18 +- .../website/src/pages/docs/Guides/Gotchas.mdx | 2 +- .../website/src/pages/docs/Guides/Roadmap.md | 7 +- packages/website/src/pages/docs/index.mdx | 1 - packages/website/templates.mts | 2 +- 10 files changed, 132 insertions(+), 79 deletions(-) rename packages/website/src/pages/docs/Guides/{Debugging.md => Debugging.mdx} (61%) diff --git a/packages/squiggle-lang/src/fr/calculator.ts b/packages/squiggle-lang/src/fr/calculator.ts index 78ced14ffc..946e508a53 100644 --- a/packages/squiggle-lang/src/fr/calculator.ts +++ b/packages/squiggle-lang/src/fr/calculator.ts @@ -34,12 +34,15 @@ export const library = [ maker.make({ name: "make", output: "Calculator", - examples: [ + interactiveExamples: [ `Calculator.make( - {|x| x * 5}, + {|x, y| x * y}, { title: "My great calculator", - inputs: [Input.text({ name: "x", default: "20" })], + inputs: [ + Input.text({ name: "x", default: "20" }), + Input.textArea({ name: "y", default: "50 to 80" }), + ], autorun: false, sampleCount: 10k, } diff --git a/packages/squiggle-lang/src/fr/number.ts b/packages/squiggle-lang/src/fr/number.ts index 56114e9fa0..f049eb2120 100644 --- a/packages/squiggle-lang/src/fr/number.ts +++ b/packages/squiggle-lang/src/fr/number.ts @@ -83,7 +83,6 @@ export const library = [ name: "unaryMinus", output: "Number", displaySection: "Functions (Number)", - description: "exponent", examples: [`exp(3.5)`], fn: (x) => -x, }), diff --git a/packages/squiggle-lang/src/fr/string.ts b/packages/squiggle-lang/src/fr/string.ts index e25dbb8767..55c7f18e12 100644 --- a/packages/squiggle-lang/src/fr/string.ts +++ b/packages/squiggle-lang/src/fr/string.ts @@ -20,7 +20,6 @@ export const library = [ "Converts any value to a string. Some information is often lost.", definitions: [makeDefinition([frAny()], frString, ([x]) => x.toString())], }), - maker.ss2s({ name: "add", requiresNamespace: false, fn: (x, y) => x + y }), // infix + on strings maker.make({ name: "concat", requiresNamespace: false, @@ -37,6 +36,9 @@ export const library = [ name: "add", requiresNamespace: false, definitions: [ + makeDefinition([frString, frString], frString, ([a, b]) => { + return a + b; + }), makeDefinition([frString, frAny()], frString, ([a, b]) => { return a + b.toString(); }), diff --git a/packages/website/public/llms/prompt.txt b/packages/website/public/llms/prompt.txt index 80a640b32e..2f493427d2 100644 --- a/packages/website/public/llms/prompt.txt +++ b/packages/website/public/llms/prompt.txt @@ -5,68 +5,101 @@ Key instructions: 2. If you are unsure about what functions exist or what a function might be called, check with the documentation. 3. Try out the code by running it. Make sure it works. 4. Present the final code to the user. +5. Annotate key variables with @name for their name, and @doc for reasoning behind them. About Squiggle. Squiggle is a very simple language, that's much simpler than JS. Don't try using language primitives/constructs you don't see below, or that aren't in our documentation. They are likely to fail. When writing Squiggle code, it's important to avoid certain common mistakes: -1. Input Types: Use Input.text for numeric inputs instead of Input.number. -2. Variable Declaration: Directly assign values to variables without using keywords like let. For example, use foo = 3 instead of let foo = 3. -3. Variable Expansion: Avoid using syntax like |v...| or |...v| as variable expansion is not supported. -4. Anonymous Functions: Write anonymous functions using the syntax {|e| 3} instead of (e) => 3. -5. Conditional Statements: There are no case or switch statements. Use if/else for conditional logic. -6. Function Parameters: When using functions like normal, specify the standard deviation with stdev instead of sd. For example, use normal({mean: 0.3, stdev: 0.1}) instead of normal({mean: 0.3, sd: 0.1}). -7. There aren't for loops or mutation. Use immutable code, and List.map / List.reduce / List.reduceWhile. -8. You can't do "(0..years)". Use List.make or List.upTo -9. The only function param types you can provide are numeric ranges, for numbers. f(n:[1,10]). Nothing else is valid. -10. All pipes are "->", not "|>". -11. There's no "List.sort", but there is "List.sortBy", "Number.sort". -12. The only "units" are k/m/n/M/t/B, for different orders of magnitude. No other units work, like "MWh". -13. There's no random() fn. Use something like sample(uniform(0,1)). -14. There's no recursion. -15. Dict keys and variable names must be lowercase. -16. Only use Inputs directly inside calculators. They won't return numbers, just input types. -17. There's no "return", as in JS. The last value in a block/function is returned. +### Syntax and Structure +1. Variable Expansion: Not supported. Don't use syntax like |v...| or |...v|. +2. All pipes are "->", not "|>". +3. Dict keys and variable names must be lowercase. +4. The last value in a block/function is returned (no "return" keyword). +5. Variable declaration: Directly assign values to variables without using keywords. For example, use ``foo = 3`` instead of ``let foo = 3``. +6. All statements in your model, besides the last one must either be comments or variable declarations. You can't do, ```4 \n 5 \n 6``` Similarly, you can't do, ```Calculator() ... Table()``` - instead, you need to set everything but the last item to a variable. + +### Function Definitions and Use +1. Anonymous Functions: Use {|e| e} syntax for anonymous functions. +2. Function Parameters: When using functions like normal, specify the standard deviation with stdev instead of sd. For example, use normal({mean: 0.3, stdev: 0.1}) instead of normal({mean: 0.3, sd: 0.1}). +3. There's no recursion. +4. You can't call functions that accept ranges, with distributions. No, ``({|foo: [1,20]| foo}) (4 to 5)``. + +### Data Types and Input Handling +1. Input Types: Use Input.text for numeric inputs instead of Input.number or Input.slider. +2. The only function param types you can provide are numeric/date ranges, for numbers. f(n:[1,10]). Nothing else is valid. You cannot provide regular input type declarations. +3. Only use Inputs directly inside calculators. They won't return numbers, just input types. + +### Looping, Conditionals, and Data Operations +1. Conditional Statements: There are no case or switch statements. Use if/else for conditional logic. +2. There aren't for loops or mutation. Use immutable code, and List.map / List.reduce / List.reduceWhile. +3. Remember to use ``Number.sum`` and ``Number.product``, instead of using Reduce in those cases. + +### List and Dictionary Operations +1. You can't do "(0..years)". Use List.make or List.upTo. +2. There's no "List.sort", but there is "List.sortBy", "Number.sort". + +### Randomness and Distribution Handling +1. There's no random() function. Use alternatives like sample(uniform(0,1)). +2. When representing percentages, use "5%" instead of "0.05" for readability. +3. The ``to`` syntax only works for >0 values. "4 to 10", not "0 to 10". + +### Units and Scales +1. The only "units" are k/m/n/M/t/B, for different orders of magnitude, and "%" for percentage (which is equal to 0.01). +2. If you make a table that contains a column of similar distributions, use a scale to ensure consistent min and max. +3. Scale.symlog() has support for negative values, Scale.log() doesn't. Scale.symlog() is often a better choice for this reason, though Scale.log() is better when you are sure values are above 0. +4. Do use Scale.symlog() and Scale.log() on dists/plots that might need it. Many do! + +### Documentation and Comments +1. Tags like @name and @doc apply to the following variable, not the full file. +2. If you use a domain for Years, try to use the Date domain, and pass in Date objects, like Date(2022) instead of 2022. + +--- + +This format provides a clear and organized view of the guidelines for writing Squiggle code. + Here's are some simple example Squiggle programs: ```squiggle +//Model for Piano Tuners in New York Over Time + +@name("Population of New York in 2022") +@doc("I'm really not sure here, this is a quick guess.") populationOfNewYork2022 = 8.1M to 8.4M -proportionOfPopulationWithPianos = { - percentage = (.2 to 1) - percentage * 0.01 -} +@name("Percentage of Population with Pianos") +proportionOfPopulationWithPianos = 0.2% to 1% + +@name("Number of Piano Tuners per Piano") pianoTunersPerPiano = { - pianosPerPianoTuner = 2k to 50k - 1 / pianosPerPianoTuner + pianosPerPianoTuner = 2k to 50k + 1 / pianosPerPianoTuner } //We only mean to make an estimate for the next 10 years. -startYear = 2024 -endYear = 2034 -domain = [startYear, endYear] +@hide +domain = [Date(2024), Date(2034)] -/** Time in years after 2024 */ +@name("Time in years after 2024") populationAtTime(t: domain) = { - averageYearlyPercentageChange = normal({p5:-0.01, p95:0.05}) // We're expecting NYC to continuously grow with an mean of roughly between -1% and +4% per year - populationOfNewYork2022 * ((averageYearlyPercentageChange + 1) ^ (t - startYear)) + dateDiff = Duration.toYears(t - Date(2024)) + averageYearlyPercentageChange = normal({ p5: -1%, p95: 5% }) // We're expecting NYC to continuously grow with an mean of roughly between -1% and +4% per year + populationOfNewYork2022 * (averageYearlyPercentageChange + 1) ^ dateDiff } -median(v) = quantile(v, .5) -totalTunersAtTime(t: domain) = ( - populationAtTime(t) * +totalTunersAtTime(t: domain) = populationAtTime(t) * proportionOfPopulationWithPianos * pianoTunersPerPiano -) + { - populationAtTime, - totalTunersAtTimeMedian: {|t: domain| median(totalTunersAtTime(t))} + populationAtTime, + totalTunersAtTimeMedian: {|t: domain| median(totalTunersAtTime(t))}, } ``` ```squiggle -Calculator.make( +Calculator( + {|a, b,c,d| [a,b,c,d]}, { - fn: {|a, b,c,d| [a,b,c,d]}, title: "Concat()", description: "This function takes in 4 arguments, then displays them", autorun: true, @@ -86,12 +119,12 @@ Calculator.make( ``` ```squiggle Table.make( + [ + { name: "First Dist", value: Sym.lognormal({ p5: 1, p95: 10 }) }, + { name: "Second Dist", value: Sym.lognormal({ p5: 5, p95: 30 }) }, + { name: "Third Dist", value: Sym.lognormal({ p5: 50, p95: 90 }) }, + ], { - data: [ - { name: "First Dist", value: Sym.lognormal({ p5: 1, p95: 10 }) }, - { name: "Second Dist", value: Sym.lognormal({ p5: 5, p95: 30 }) }, - { name: "Third Dist", value: Sym.lognormal({ p5: 50, p95: 90 }) }, - ], columns: [ { name: "Name", fn: {|d|d.name} }, { @@ -99,12 +132,12 @@ Table.make( fn: { |d| Plot.dist( - { - dist: d.value, - xScale: Scale.log({ min: 0.5, max: 100 }), - showSummary: false, - } - ) + { + dist: d.value, + xScale: Scale.log({ min: 0.5, max: 100 }), + showSummary: false, + } + ) }, }, ], @@ -122,21 +155,24 @@ y = result.y z = result.z ``` ```squiggle -Plot.numericFn({ - fn: {|t| t^2}, - xScale: Scale.log({ - min: 1, - max: 100 - }), - points: 10 -}) +@showAs({|f| Plot.numericFn(f, { xScale: Scale.log({ min: 1, max: 100 }) })}) +fn(t) = t ^ 2 ``` ```squiggle -Plot.distFn({ - fn: {|t| normal(t,2)*normal(5,3)}, - title: "A Function of Value over Time", - xScale: Scale.log({ min: 3, max: 100, title: "Time (years)"}), - yScale: Scale.linear({ title: "Value"}), - distXScale: Scale.linear({ tickFormat: '#x' }), -}) +{|t| normal(t, 2) * normal(5, 3)} + -> Plot.distFn( + { + title: "A Function of Value over Time", + xScale: Scale.log({ min: 3, max: 100, title: "Time (years)" }), + yScale: Scale.linear({ title: "Value" }), + distXScale: Scale.linear({ tickFormat: "#x" }), + } + ) +``` + +``` +f(t: [Date(2020), Date(2040)]) = { + yearsPassed = toYears(t - Date(2020)) + normal({mean: yearsPassed ^ 2, stdev: yearsPassed^1.3+1}) +} ``` \ No newline at end of file diff --git a/packages/website/src/pages/docs/Ecosystem/Tooling.md b/packages/website/src/pages/docs/Ecosystem/Tooling.md index b971b21360..30af2b44e2 100644 --- a/packages/website/src/pages/docs/Ecosystem/Tooling.md +++ b/packages/website/src/pages/docs/Ecosystem/Tooling.md @@ -34,7 +34,8 @@ This extention allows you to run and visualize Squiggle code. An exportable [Observable Notebook](https://observablehq.com/@hazelfire/squiggle) of the key components that you can directly import and use in Observable notebooks. -## [NextJS starter](https://github.com/quantified-uncertainty/next-app-with-squiggle) +We don't update this regularly, so message us if you need a new version. -A template for presenting estimates on a nextjs site. +## [NextJS starter](https://github.com/quantified-uncertainty/next-app-with-squiggle) +A template for presenting estimates on a nextjs site. We don't update this regularly, so message us if you need a new version. diff --git a/packages/website/src/pages/docs/Guides/Debugging.md b/packages/website/src/pages/docs/Guides/Debugging.mdx similarity index 61% rename from packages/website/src/pages/docs/Guides/Debugging.md rename to packages/website/src/pages/docs/Guides/Debugging.mdx index b306493f69..396b8bde73 100644 --- a/packages/website/src/pages/docs/Guides/Debugging.md +++ b/packages/website/src/pages/docs/Guides/Debugging.mdx @@ -2,6 +2,8 @@ description: Tips for debugging Squiggle code --- +import { SquiggleEditor } from "../../../components/SquiggleEditor"; + # Debugging Interactive visualizations are a primary tool for understanding Squiggle code, but there are some additional techniques that can improve the debugging process. Here are some tips and tricks: @@ -11,4 +13,18 @@ Interactive visualizations are a primary tool for understanding Squiggle code, b - **Variable Settings Toggle:** Click on the variable menu in the Squiggle interface and select "Log to JS Console". ## ``Window.squiggleOutput`` -Squiggle pushes its output to ``window.squiggleOutput``. Like with the outputs of ``inspect``, you can see this in the [JS developer console](https://www.digitalocean.com/community/tutorials/how-to-use-the-javascript-developer-console). \ No newline at end of file +Squiggle pushes its output to ``window.squiggleOutput``. Like with the outputs of ``inspect``, you can see this in the [JS developer console](https://www.digitalocean.com/community/tutorials/how-to-use-the-javascript-developer-console). + +## ``Danger.json`` +You can call [``Danger.json()``](/docs/Api/Danger#json) see variables in a format similar to JSON. This is useful for seeing all aspects of complex types like distributions. + + diff --git a/packages/website/src/pages/docs/Guides/Gotchas.mdx b/packages/website/src/pages/docs/Guides/Gotchas.mdx index 4df0df7623..6a8257d3d7 100644 --- a/packages/website/src/pages/docs/Guides/Gotchas.mdx +++ b/packages/website/src/pages/docs/Guides/Gotchas.mdx @@ -32,7 +32,7 @@ We plan to later support more configuration of kernel density estimation, and fo Correlations with Sample Set distributions are a bit complicated. Monte Carlo generations with Squiggle are ordered. The first sample in one Sample Set distribution will correspond to the first sample in a distribution that comes from a resulting Monte Carlo generation. Therefore, Sample Set distributions in a chain of Monte Carlo generations are likely to all be correlated with each other. This connection breaks if any node changes to the Point Set or Symbolic format. -In this example, we subtract all three types of distributions by themselves. Notice that the Sample Set distribution returns 1. The other two return the result of subtracting one normal distribution from a separate uncorrelated distribution. These results are clearly very different to each other. +In this example, we subtract all three types of distributions by themselves. Notice that the Sample Set distribution returns 0. The other two return the result of subtracting one normal distribution from a separate uncorrelated distribution. These results are clearly very different to each other. Date: Thu, 11 Jan 2024 17:51:30 -0800 Subject: [PATCH 4/9] Refactoring examples to use custom makeFnExample fn --- .../__tests__/library/examples_test.ts | 25 ++++--- packages/squiggle-lang/src/fr/danger.ts | 50 ++++++++----- packages/squiggle-lang/src/fr/date.ts | 17 +++-- packages/squiggle-lang/src/fr/dict.ts | 47 +++++++----- packages/squiggle-lang/src/fr/dist.ts | 60 +++++++++------- packages/squiggle-lang/src/fr/duration.ts | 17 ++--- packages/squiggle-lang/src/fr/input.ts | 19 +++-- packages/squiggle-lang/src/fr/list.ts | 71 ++++++++++--------- packages/squiggle-lang/src/fr/number.ts | 51 ++++++------- packages/squiggle-lang/src/fr/pointset.ts | 26 ++++--- packages/squiggle-lang/src/fr/sampleset.ts | 49 ++++++++----- packages/squiggle-lang/src/fr/scale.ts | 15 ++-- packages/squiggle-lang/src/fr/scoring.ts | 15 ++-- packages/squiggle-lang/src/fr/sym.ts | 43 +++++------ packages/squiggle-lang/src/fr/units.ts | 3 +- .../src/library/registry/core.ts | 38 +++++++--- 16 files changed, 326 insertions(+), 220 deletions(-) diff --git a/packages/squiggle-lang/__tests__/library/examples_test.ts b/packages/squiggle-lang/__tests__/library/examples_test.ts index f72432a573..fe60ef28dd 100644 --- a/packages/squiggle-lang/__tests__/library/examples_test.ts +++ b/packages/squiggle-lang/__tests__/library/examples_test.ts @@ -1,19 +1,18 @@ import { registry } from "../../src/library/registry/index.js"; import { evaluateStringToResult } from "../../src/reducer/index.js"; -test.each(registry.allExamplesWithFns())( - "tests of example $example", - async ({ fn, example }) => { - const result = await evaluateStringToResult(example); +test.each( + registry.allExamplesWithFns().filter(({ example }) => example.useForTests) +)("tests of example $example", async ({ fn, example }) => { + const result = await evaluateStringToResult(example.text); - if (!result.ok) { - throw new Error(`Can't test type, with error: ${result.value}`); - } - - if (fn.output !== undefined) { - expect(result.value.type).toEqual(fn.output); - } + if (!result.ok) { + throw new Error(`Can't test type, with error: ${result.value}`); + } - expect(result.ok).toBe(true); + if (fn.output !== undefined) { + expect(result.value.type).toEqual(fn.output); } -); + + expect(result.ok).toBe(true); +}); diff --git a/packages/squiggle-lang/src/fr/danger.ts b/packages/squiggle-lang/src/fr/danger.ts index 9d7798d0b1..cf7e5897fc 100644 --- a/packages/squiggle-lang/src/fr/danger.ts +++ b/packages/squiggle-lang/src/fr/danger.ts @@ -12,7 +12,7 @@ import { } from "../dist/distOperations/scaleOperations.js"; import * as SymbolicDist from "../dist/SymbolicDist.js"; import { REArgumentError, REOther } from "../errors/messages.js"; -import { FRFunction } from "../library/registry/core.js"; +import { FRFunction, makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frAny, @@ -76,9 +76,9 @@ const combinatoricsLibrary: FRFunction[] = [ name: "laplace", description: `Calculates the probability implied by [Laplace's rule of succession](https://en.wikipedia.org/wiki/Rule_of_succession)`, examples: [ - `trials = 10 + makeFnExample(`trials = 10 successes = 1 -Danger.laplace(successes, trials) // (successes + 1) / (trials + 2) = 2 / 12 = 0.1666`, +Danger.laplace(successes, trials) // (successes + 1) / (trials + 2) = 2 / 12 = 0.1666`), ], displaySection: "Math", fn: (successes, trials) => (successes + 1) / (trials + 2), @@ -86,14 +86,14 @@ Danger.laplace(successes, trials) // (successes + 1) / (trials + 2) = 2 / 12 = maker.n2n({ name: "factorial", displaySection: "Combinatorics", - examples: [`Danger.factorial(20)`], + examples: [makeFnExample(`Danger.factorial(20)`)], fn: factorial, }), maker.nn2n({ name: "choose", displaySection: "Combinatorics", description: `\`Danger.choose(n,k)\` returns \`factorial(n) / (factorial(n - k) * factorial(k))\`, i.e., the number of ways you can choose k items from n choices, without repetition. This function is also known as the [binomial coefficient](https://en.wikipedia.org/wiki/Binomial_coefficient).`, - examples: [`Danger.choose(1, 20)`], + examples: [makeFnExample(`Danger.choose(1, 20)`)], fn: choose, }), maker.make({ @@ -101,7 +101,7 @@ Danger.laplace(successes, trials) // (successes + 1) / (trials + 2) = 2 / 12 = output: "Number", displaySection: "Combinatorics", description: `\`Danger.binomial(n, k, p)\` returns \`choose((n, k)) * pow(p, k) * pow(1 - p, n - k)\`, i.e., the probability that an event of probability p will happen exactly k times in n draws.`, - examples: [`Danger.binomial(1, 20, 0.5)`], + examples: [makeFnExample(`Danger.binomial(1, 20, 0.5)`)], definitions: [ makeDefinition( [frNumber, frNumber, frNumber], @@ -190,7 +190,9 @@ const integrationLibrary: FRFunction[] = [ output: "Number", displaySection: "Integration", examples: [ - `Danger.integrateFunctionBetweenWithNumIntegrationPoints({|x| x+1}, 1, 10, 10)`, + makeFnExample( + `Danger.integrateFunctionBetweenWithNumIntegrationPoints({|x| x+1}, 1, 10, 10)` + ), ], description: `Integrates the function \`f\` between \`min\` and \`max\`, and computes \`numIntegrationPoints\` in between to do so. @@ -242,7 +244,9 @@ Danger.integrateFunctionBetweenWithNumIntegrationPoints(auxiliaryF, min, max, nu output: "Number", displaySection: "Integration", examples: [ - `Danger.integrateFunctionBetweenWithEpsilon({|x| x+1}, 1, 10, 0.1)`, + makeFnExample( + `Danger.integrateFunctionBetweenWithEpsilon({|x| x+1}, 1, 10, 0.1)` + ), ], description: `Integrates the function \`f\` between \`min\` and \`max\`, and uses an interval of \`epsilon\` between integration points when doing so. This makes its runtime less predictable than \`integrateFunctionBetweenWithNumIntegrationPoints\`, because runtime will not only depend on \`epsilon\`, but also on \`min\` and \`max\`. @@ -290,14 +294,14 @@ const diminishingReturnsLibrary = [ output: "Array", requiresNamespace: false, examples: [ - `Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions( + makeFnExample(`Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions( [ {|x| x+1}, {|y| 10} ], 100, 0.01 -)`, +)`), ], description: `Computes the optimal allocation of $\`funds\` between \`f1\` and \`f2\`. For the answer given to be correct, \`f1\` and \`f2\` will have to be decreasing, i.e., if \`x > y\`, then \`f_i(x) < f_i(y)\`.`, displaySection: "Optimization", @@ -417,7 +421,7 @@ const diminishingReturnsLibrary = [ const mapYLibrary: FRFunction[] = [ maker.make({ name: "binomialDist", - examples: ["Danger.binomialDist(8, 0.5)"], + examples: [makeFnExample("Danger.binomialDist(8, 0.5)")], displaySection: "Distributions", description: `A binomial distribution. @@ -434,7 +438,7 @@ Note: The binomial distribution is a discrete distribution. When representing th }), maker.make({ name: "poissonDist", - examples: ["Danger.poissonDist(10)"], + examples: [makeFnExample("Danger.poissonDist(10)")], displaySection: "Distributions", description: `A Poisson distribution. @@ -449,7 +453,11 @@ Note: The Poisson distribution is a discrete distribution. When representing thi maker.make({ name: "combinations", displaySection: "Combinatorics", - examples: [`Danger.combinations([1, 2, 3], 2) // [[1, 2], [1, 3], [2, 3]]`], + examples: [ + makeFnExample( + `Danger.combinations([1, 2, 3], 2) // [[1, 2], [1, 3], [2, 3]]` + ), + ], description: `Returns all combinations of the input list taken r elements at a time.`, definitions: [ makeDefinition( @@ -471,7 +479,9 @@ Note: The Poisson distribution is a discrete distribution. When representing thi displaySection: "Combinatorics", description: `Returns all possible combinations of the elements in the input list.`, examples: [ - `Danger.allCombinations([1, 2, 3]) // [[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]`, + makeFnExample( + `Danger.allCombinations([1, 2, 3]) // [[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]` + ), ], definitions: [ makeDefinition( @@ -489,8 +499,10 @@ Note: The Poisson distribution is a discrete distribution. When representing thi description: "Converts a value to a simpler form, similar to JSON. This is useful for debugging. Keeps functions and dates, but converts objects like distributions, calculators, and plots to combinations of dictionaries and lists.", examples: [ - `Danger.json({a: 1, b: 2})`, - `Danger.json([2 to 5, Sym.normal(5, 2), Calculator({|x| x + 1})])`, + makeFnExample(`Danger.json({a: 1, b: 2})`), + makeFnExample( + `Danger.json([2 to 5, Sym.normal(5, 2), Calculator({|x| x + 1})])` + ), ], definitions: [ makeDefinition([frAny()], frAny(), ([v]) => { @@ -504,8 +516,10 @@ Note: The Poisson distribution is a discrete distribution. When representing thi description: "Converts a value to a stringified JSON, similar to JSON.stringify() in Javasript. Replaces functions with dict summaries.", examples: [ - `Danger.jsonString({a: 1, b: 2})`, - `Danger.jsonString([2 to 5, Sym.normal(5, 2), Calculator({|x| x + 1})])`, + makeFnExample(`Danger.jsonString({a: 1, b: 2})`), + makeFnExample( + `Danger.jsonString([2 to 5, Sym.normal(5, 2), Calculator({|x| x + 1})])` + ), ], definitions: [ makeDefinition([frAny()], frString, ([v]) => { diff --git a/packages/squiggle-lang/src/fr/date.ts b/packages/squiggle-lang/src/fr/date.ts index 2e212db4ac..1860f4930b 100644 --- a/packages/squiggle-lang/src/fr/date.ts +++ b/packages/squiggle-lang/src/fr/date.ts @@ -1,4 +1,5 @@ import { REOther } from "../errors/messages.js"; +import { makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frDate, @@ -32,10 +33,14 @@ export const library = [ maker.make({ name: "make", requiresNamespace: true, - interactiveExamples: [ - `d1 = Date.make("2020-05-12") + examples: [ + makeFnExample( + `d1 = Date.make("2020-05-12") d2 = Date.make(2020, 5, 10) d3 = Date.make(2020.5)`, + true, + false + ), ], displaySection: "Constructors", output: "Date", @@ -71,7 +76,7 @@ d3 = Date.make(2020.5)`, // same name as used in date-fns maker.make({ name: "fromUnixTime", - examples: ["Date.fromUnixTime(1589222400)"], + examples: [makeFnExample("Date.fromUnixTime(1589222400)")], requiresNamespace: true, output: "Date", displaySection: "Conversions", @@ -83,7 +88,7 @@ d3 = Date.make(2020.5)`, }), maker.make({ name: "toUnixTime", - examples: ["Date.toUnixTime(Date.make(2020, 5, 12))"], + examples: [makeFnExample("Date.toUnixTime(Date.make(2020, 5, 12))")], requiresNamespace: true, displaySection: "Conversions", output: "Number", @@ -117,7 +122,7 @@ d3 = Date.make(2020.5)`, }), maker.make({ name: "add", - examples: ["Date.make(2020, 5, 12) + 20years"], + examples: [makeFnExample("Date.make(2020, 5, 12) + 20years")], interactiveExamples: ["20years + Date.make(2020, 5, 12)"], output: "Date", displaySection: "Algebra", @@ -134,7 +139,7 @@ d3 = Date.make(2020.5)`, name: "rangeDomain", requiresNamespace: true, output: "Domain", - examples: ["Date.rangeDomain(Date(2000), Date(2010))"], + examples: [makeFnExample("Date.rangeDomain(Date(2000), Date(2010))")], displaySection: "Other", definitions: [ makeDefinition( diff --git a/packages/squiggle-lang/src/fr/dict.ts b/packages/squiggle-lang/src/fr/dict.ts index fbcb0c4371..265e909614 100644 --- a/packages/squiggle-lang/src/fr/dict.ts +++ b/packages/squiggle-lang/src/fr/dict.ts @@ -16,6 +16,7 @@ import { import { FnFactory } from "../library/registry/helpers.js"; import { ImmutableMap } from "../utility/immutableMap.js"; import { Value, vString } from "../value/index.js"; +import { makeFnExample } from "../library/registry/core.js"; const maker = new FnFactory({ nameSpace: "Dict", @@ -26,7 +27,7 @@ export const library = [ maker.make({ name: "set", output: "Dict", - examples: [`Dict.set({a: 1, b: 2}, "c", 3)`], + examples: [makeFnExample(`Dict.set({a: 1, b: 2}, "c", 3)`)], displaySection: "Transformations", description: "Creates a new dictionary that includes the added element, while leaving the original dictionary unaltered.", @@ -45,7 +46,7 @@ export const library = [ maker.make({ name: "has", output: "Bool", - examples: [`Dict.has({a: 1, b: 2}, "c")`], + examples: [makeFnExample(`Dict.has({a: 1, b: 2}, "c")`)], displaySection: "Queries", definitions: [ makeDefinition( @@ -59,7 +60,7 @@ export const library = [ name: "size", output: "Number", displaySection: "Queries", - examples: [`Dict.size({a: 1, b: 2})`], + examples: [makeFnExample(`Dict.size({a: 1, b: 2})`)], definitions: [ makeDefinition( [frDictWithArbitraryKeys(frAny())], @@ -71,7 +72,7 @@ export const library = [ maker.make({ name: "delete", output: "Dict", - examples: [`Dict.delete({a: 1, b: 2}, "a")`], + examples: [makeFnExample(`Dict.delete({a: 1, b: 2}, "a")`)], description: "Creates a new dictionary that excludes the deleted element.", displaySection: "Transformations", definitions: [ @@ -89,9 +90,11 @@ export const library = [ name: "merge", output: "Dict", examples: [ - `first = { a: 1, b: 2 } + makeFnExample( + `first = { a: 1, b: 2 } snd = { b: 3, c: 5 } -Dict.merge(first, snd)`, +Dict.merge(first, snd)` + ), ], displaySection: "Transformations", definitions: [ @@ -106,9 +109,11 @@ Dict.merge(first, snd)`, name: "mergeMany", output: "Dict", examples: [ - `first = { a: 1, b: 2 } + makeFnExample( + `first = { a: 1, b: 2 } snd = { b: 3, c: 5 } -Dict.mergeMany([first, snd]) // {a: 1, b: 3, c: 5}`, +Dict.mergeMany([first, snd]) // {a: 1, b: 3, c: 5}` + ), ], displaySection: "Transformations", definitions: [ @@ -122,7 +127,7 @@ Dict.mergeMany([first, snd]) // {a: 1, b: 3, c: 5}`, maker.make({ name: "keys", output: "Array", - examples: [`Dict.keys({a: 1, b: 2})`], + examples: [makeFnExample(`Dict.keys({a: 1, b: 2})`)], displaySection: "Queries", definitions: [ makeDefinition( @@ -135,7 +140,7 @@ Dict.mergeMany([first, snd]) // {a: 1, b: 3, c: 5}`, maker.make({ name: "values", output: "Array", - examples: [`Dict.values({ foo: 3, bar: 20 }) // [3, 20]`], + examples: [makeFnExample(`Dict.values({ foo: 3, bar: 20 }) // [3, 20]`)], displaySection: "Queries", definitions: [ makeDefinition( @@ -148,7 +153,7 @@ Dict.mergeMany([first, snd]) // {a: 1, b: 3, c: 5}`, maker.make({ name: "toList", output: "Array", - examples: [`Dict.toList({a: 1, b: 2})`], + examples: [makeFnExample(`Dict.toList({a: 1, b: 2})`)], displaySection: "Conversions", definitions: [ makeDefinition( @@ -162,10 +167,12 @@ Dict.mergeMany([first, snd]) // {a: 1, b: 3, c: 5}`, name: "fromList", output: "Dict", examples: [ - `Dict.fromList([ + makeFnExample( + `Dict.fromList([ ["foo", 3], ["bar", 20], - ]) // {foo: 3, bar: 20}`, + ]) // {foo: 3, bar: 20}` + ), ], displaySection: "Conversions", definitions: [ @@ -179,7 +186,7 @@ Dict.mergeMany([first, snd]) // {a: 1, b: 3, c: 5}`, maker.make({ name: "map", output: "Dict", - examples: [`Dict.map({a: 1, b: 2}, {|x| x + 1})`], + examples: [makeFnExample(`Dict.map({a: 1, b: 2}, {|x| x + 1})`)], displaySection: "Transformations", definitions: [ makeDefinition( @@ -239,8 +246,10 @@ Dict.mergeMany([first, snd]) // {a: 1, b: 3, c: 5}`, name: "pick", output: "Dict", examples: [ - `data = { a: 1, b: 2, c: 3, d: 4 } -Dict.pick(data, ["a", "c"]) // {a: 1, c: 3}`, + makeFnExample( + `data = { a: 1, b: 2, c: 3, d: 4 } +Dict.pick(data, ["a", "c"]) // {a: 1, c: 3}` + ), ], description: "Creates a new dictionary that only includes the picked keys.", displaySection: "Queries", @@ -272,8 +281,10 @@ Dict.pick(data, ["a", "c"]) // {a: 1, c: 3}`, name: "omit", output: "Dict", examples: [ - `data = { a: 1, b: 2, c: 3, d: 4 } -Dict.omit(data, ["b", "d"]) // {a: 1, c: 3}`, + makeFnExample( + `data = { a: 1, b: 2, c: 3, d: 4 } +Dict.omit(data, ["b", "d"]) // {a: 1, c: 3}` + ), ], description: "Creates a new dictionary that excludes the omitted keys.", displaySection: "Transformations", diff --git a/packages/squiggle-lang/src/fr/dist.ts b/packages/squiggle-lang/src/fr/dist.ts index 5ae2355bed..846345bd59 100644 --- a/packages/squiggle-lang/src/fr/dist.ts +++ b/packages/squiggle-lang/src/fr/dist.ts @@ -1,7 +1,7 @@ import { argumentError, otherError } from "../dist/DistError.js"; import * as SymbolicDist from "../dist/SymbolicDist.js"; import { REDistributionError } from "../errors/messages.js"; -import { FRFunction } from "../library/registry/core.js"; +import { FRFunction, makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frDict, @@ -63,7 +63,10 @@ export const library: FRFunction[] = [ name: "make", requiresNamespace: true, displaySection: "Distributions", - examples: ["Dist.make(5)", "Dist.make(normal({p5: 4, p95: 10}))"], + examples: [ + makeFnExample("Dist.make(5)"), + makeFnExample("Dist.make(normal({p5: 4, p95: 10}))"), + ], definitions: [ makeDefinition([frDist], frDist, ([dist]) => dist), makeDefinition([frNumber], frDistSymbolic, ([v]) => @@ -75,9 +78,13 @@ export const library: FRFunction[] = [ name: "mixture", displaySection: "Distributions", examples: [ - "mixture(1,normal(5,2))", - "mixture(normal(5,2), normal(10,2), normal(15,2), [0.3, 0.5, 0.2])", - "mixture([normal(5,2), normal(10,2), normal(15,2), normal(20,1)], [0.3, 0.5, 0.1, 0.1])", + makeFnExample("mixture(1,normal(5,2))"), + makeFnExample( + "mixture(normal(5,2), normal(10,2), normal(15,2), [0.3, 0.5, 0.2])" + ), + makeFnExample( + "mixture([normal(5,2), normal(10,2), normal(15,2), normal(20,1)], [0.3, 0.5, 0.1, 0.1])" + ), ], description: `The \`\`mixture\`\` function takes a list of distributions and a list of weights, and returns a new distribution that is a mixture of the distributions in the list. The weights should be positive numbers that sum to 1. If no weights are provided, the function will assume that all distributions have equal weight. @@ -87,7 +94,7 @@ Note: If you want to pass in over 5 distributions, you must use the list syntax. maker.make({ name: "mx", displaySection: "Distributions", - examples: ["mx(1,normal(5,2))"], + examples: [makeFnExample("mx(1,normal(5,2))")], description: "Alias for mixture()", definitions: mixtureDefinitions, }), @@ -95,11 +102,11 @@ Note: If you want to pass in over 5 distributions, you must use the list syntax. name: "normal", displaySection: "Distributions", examples: [ - "normal(5,1)", - "normal({p5: 4, p95: 10})", - "normal({p10: 4, p90: 10})", - "normal({p25: 4, p75: 10})", - "normal({mean: 5, stdev: 2})", + makeFnExample("normal(5,1)"), + makeFnExample("normal({p5: 4, p95: 10})"), + makeFnExample("normal({p10: 4, p90: 10})"), + makeFnExample("normal({p25: 4, p75: 10})"), + makeFnExample("normal({mean: 5, stdev: 2})"), ], definitions: [ makeTwoArgsSamplesetDist( @@ -124,11 +131,11 @@ Note: If you want to pass in over 5 distributions, you must use the list syntax. maker.make({ name: "lognormal", examples: [ - "lognormal(0.5, 0.8)", - "lognormal({p5: 4, p95: 10})", - "lognormal({p10: 4, p90: 10})", - "lognormal({p25: 4, p75: 10})", - "lognormal({mean: 5, stdev: 2})", + makeFnExample("lognormal(0.5, 0.8)"), + makeFnExample("lognormal({p5: 4, p95: 10})"), + makeFnExample("lognormal({p10: 4, p90: 10})"), + makeFnExample("lognormal({p25: 4, p75: 10})"), + makeFnExample("lognormal({mean: 5, stdev: 2})"), ], displaySection: "Distributions", definitions: [ @@ -153,7 +160,7 @@ Note: If you want to pass in over 5 distributions, you must use the list syntax. }), maker.make({ name: "uniform", - examples: ["uniform(10, 12)"], + examples: [makeFnExample("uniform(10, 12)")], displaySection: "Distributions", definitions: [ makeTwoArgsSamplesetDist( @@ -165,7 +172,10 @@ Note: If you want to pass in over 5 distributions, you must use the list syntax. }), maker.make({ name: "beta", - examples: ["beta(20, 25)", "beta({mean: 0.39, stdev: 0.1})"], + examples: [ + makeFnExample("beta(20, 25)"), + makeFnExample("beta({mean: 0.39, stdev: 0.1})"), + ], displaySection: "Distributions", definitions: [ makeTwoArgsSamplesetDist( @@ -180,7 +190,7 @@ Note: If you want to pass in over 5 distributions, you must use the list syntax. }), maker.make({ name: "cauchy", - examples: ["cauchy(5, 1)"], + examples: [makeFnExample("cauchy(5, 1)")], displaySection: "Distributions", definitions: [ makeTwoArgsSamplesetDist( @@ -192,7 +202,7 @@ Note: If you want to pass in over 5 distributions, you must use the list syntax. }), maker.make({ name: "gamma", - examples: ["gamma(5, 1)"], + examples: [makeFnExample("gamma(5, 1)")], displaySection: "Distributions", definitions: [ makeTwoArgsSamplesetDist( @@ -204,7 +214,7 @@ Note: If you want to pass in over 5 distributions, you must use the list syntax. }), maker.make({ name: "logistic", - examples: ["logistic(5, 1)"], + examples: [makeFnExample("logistic(5, 1)")], displaySection: "Distributions", definitions: [ makeTwoArgsSamplesetDist( @@ -216,7 +226,7 @@ Note: If you want to pass in over 5 distributions, you must use the list syntax. }), maker.make({ name: "to", - examples: ["5 to 10", "to(5,10)"], + examples: [makeFnExample("5 to 10"), makeFnExample("to(5,10)")], description: `The "to" function is a shorthand for lognormal({p5:min, p95:max}). It does not accept values of 0 or less, as those are not valid for lognormal distributions.`, displaySection: "Distributions", definitions: [ @@ -246,7 +256,7 @@ Note: If you want to pass in over 5 distributions, you must use the list syntax. }), maker.make({ name: "exponential", - examples: ["exponential(2)"], + examples: [makeFnExample("exponential(2)")], displaySection: "Distributions", definitions: [ makeOneArgSamplesetDist( @@ -257,7 +267,7 @@ Note: If you want to pass in over 5 distributions, you must use the list syntax. }), maker.make({ name: "bernoulli", - examples: ["bernoulli(0.5)"], + examples: [makeFnExample("bernoulli(0.5)")], displaySection: "Distributions", definitions: [ makeOneArgSamplesetDist((p) => SymbolicDist.Bernoulli.make(p), "p"), @@ -265,7 +275,7 @@ Note: If you want to pass in over 5 distributions, you must use the list syntax. }), maker.make({ name: "triangular", - examples: ["triangular(3, 5, 10)"], + examples: [makeFnExample("triangular(3, 5, 10)")], displaySection: "Distributions", definitions: [ makeDefinition( diff --git a/packages/squiggle-lang/src/fr/duration.ts b/packages/squiggle-lang/src/fr/duration.ts index bdca00f71e..f5d264a437 100644 --- a/packages/squiggle-lang/src/fr/duration.ts +++ b/packages/squiggle-lang/src/fr/duration.ts @@ -1,3 +1,4 @@ +import { makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frDuration, frNumber } from "../library/registry/frTypes.js"; import { @@ -19,7 +20,7 @@ const makeNumberToDurationFn = ( ) => maker.make({ name, - examples: [`Duration.${name}(5)`], + examples: [makeFnExample(`Duration.${name}(5)`)], output: "Duration", definitions: [makeDefinition([frNumber], frDuration, ([t]) => fn(t))], isUnit, @@ -33,7 +34,7 @@ const makeDurationToNumberFn = ( ) => maker.make({ name, - examples: [`Duration.${name}(5minutes)`], + examples: [makeFnExample(`Duration.${name}(5minutes)`)], output: "Number", displaySection, definitions: [makeDefinition([frDuration], frNumber, ([t]) => fn(t))], @@ -70,7 +71,7 @@ export const library = [ maker.make({ name: "unaryMinus", output: "Duration", - examples: ["-5minutes"], + examples: [makeFnExample("-5minutes")], displaySection: "Algebra", definitions: [ makeDefinition([frDuration], frDuration, ([d]) => d.multiply(-1)), @@ -79,7 +80,7 @@ export const library = [ maker.make({ name: "add", output: "Duration", - examples: ["5minutes + 10minutes"], + examples: [makeFnExample("5minutes + 10minutes")], displaySection: "Algebra", definitions: [ makeDefinition([frDuration, frDuration], frDuration, ([d1, d2]) => @@ -90,7 +91,7 @@ export const library = [ maker.make({ name: "subtract", output: "Duration", - examples: ["5minutes - 10minutes"], + examples: [makeFnExample("5minutes - 10minutes")], displaySection: "Algebra", definitions: [ makeDefinition([frDuration, frDuration], frDuration, ([d1, d2]) => @@ -101,7 +102,7 @@ export const library = [ maker.make({ name: "multiply", output: "Duration", - examples: ["5minutes * 10", "10 * 5minutes"], + examples: [makeFnExample("5minutes * 10"), makeFnExample("10 * 5minutes")], displaySection: "Algebra", definitions: [ makeDefinition([frDuration, frNumber], frDuration, ([d1, d2]) => @@ -116,7 +117,7 @@ export const library = [ name: "divide", output: "Number", displaySection: "Algebra", - examples: ["5minutes / 2minutes"], + examples: [makeFnExample("5minutes / 2minutes")], definitions: [ makeDefinition([frDuration, frDuration], frNumber, ([d1, d2]) => d1.divideBySDuration(d2) @@ -127,7 +128,7 @@ export const library = [ name: "divide", output: "Duration", displaySection: "Algebra", - examples: ["5minutes / 3"], + examples: [makeFnExample("5minutes / 3")], definitions: [ makeDefinition([frDuration, frNumber], frDuration, ([d1, d2]) => d1.divideByNumber(d2) diff --git a/packages/squiggle-lang/src/fr/input.ts b/packages/squiggle-lang/src/fr/input.ts index d4a125fc30..887214ab9d 100644 --- a/packages/squiggle-lang/src/fr/input.ts +++ b/packages/squiggle-lang/src/fr/input.ts @@ -1,4 +1,5 @@ import { REArgumentError } from "../errors/messages.js"; +import { makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frArray, @@ -34,8 +35,10 @@ export const library = [ name: "text", output: "Input", examples: [ - `Input.text({ name: "First", default: "John" })`, - `Input.text({ name: "Number of X in Y", default: '20 to 300' })`, + makeFnExample(`Input.text({ name: "First", default: "John" })`), + makeFnExample( + `Input.text({ name: "Number of X in Y", default: '20 to 300' })` + ), ], description: "Creates a single-line input. This input can be used for all Squiggle types.", @@ -64,10 +67,10 @@ export const library = [ name: "textArea", output: "Input", examples: [ - `Input.textArea({ name: "people", default: '{ + makeFnExample(`Input.textArea({ name: "people", default: '{ "John": 20 to 50, "Mary": 30 to 90, -}' })`, +}' })`), ], description: "Creates a multi-line input, sized with the provided input. This input can be used for all Squiggle types.", @@ -95,7 +98,9 @@ export const library = [ maker.make({ name: "checkbox", output: "Input", - examples: [`Input.checkbox({ name: "IsTrue?", default: true })`], + examples: [ + makeFnExample(`Input.checkbox({ name: "IsTrue?", default: true })`), + ], description: "Creates a checkbox input. Used for Squiggle booleans.", definitions: [ makeDefinition( @@ -122,7 +127,9 @@ export const library = [ name: "select", output: "Input", examples: [ - `Input.select({ name: "Name", default: "Sue", options: ["John", "Mary", "Sue"] })`, + makeFnExample( + `Input.select({ name: "Name", default: "Sue", options: ["John", "Mary", "Sue"] })` + ), ], description: "Creates a dropdown input. Used for Squiggle strings.", definitions: [ diff --git a/packages/squiggle-lang/src/fr/list.ts b/packages/squiggle-lang/src/fr/list.ts index 28181abe02..0de7db44c7 100644 --- a/packages/squiggle-lang/src/fr/list.ts +++ b/packages/squiggle-lang/src/fr/list.ts @@ -30,6 +30,7 @@ import { Lambda } from "../reducer/lambda.js"; import { shuffle, unzip, zip } from "../utility/E_A.js"; import * as E_A_Floats from "../utility/E_A_Floats.js"; import { uniq, uniqBy, Value, vNumber } from "../value/index.js"; +import { makeFnExample } from "../library/registry/core.js"; export function _map( array: readonly Value[], @@ -146,9 +147,9 @@ export const library = [ name: "make", output: "Array", examples: [ - `List.make(2, 3)`, - `List.make(2, {|| 3})`, - `List.make(2, {|index| index+1})`, + makeFnExample(`List.make(2, 3)`), + makeFnExample(`List.make(2, {|| 3})`), + makeFnExample(`List.make(2, {|index| index+1})`), ], displaySection: "Constructors", description: `Creates an array of length \`count\`, with each element being \`value\`. If \`value\` is a function, it will be called \`count\` times, with the index as the argument.`, @@ -197,7 +198,7 @@ export const library = [ maker.make({ name: "upTo", output: "Array", - examples: [`List.upTo(1,4)`], + examples: [makeFnExample(`List.upTo(1,4)`)], displaySection: "Constructors", definitions: [ makeDefinition( @@ -218,7 +219,7 @@ export const library = [ name: "length", requiresNamespace: true, output: "Number", - examples: [`List.length([1,4,5])`], + examples: [makeFnExample(`List.length([1,4,5])`)], displaySection: "Queries", definitions: [ makeDefinition([frArray(frAny())], frNumber, ([values]) => values.length), @@ -227,7 +228,7 @@ export const library = [ maker.make({ name: "first", requiresNamespace: true, - examples: [`List.first([1,4,5])`], + examples: [makeFnExample(`List.first([1,4,5])`)], displaySection: "Queries", definitions: [ makeDefinition( @@ -243,7 +244,7 @@ export const library = [ maker.make({ name: "last", requiresNamespace: true, - examples: [`List.last([1,4,5])`], + examples: [makeFnExample(`List.last([1,4,5])`)], displaySection: "Queries", definitions: [ makeDefinition( @@ -260,7 +261,7 @@ export const library = [ name: "reverse", output: "Array", requiresNamespace: false, - examples: [`List.reverse([1,4,5]) // [5,4,1]`], + examples: [makeFnExample(`List.reverse([1,4,5]) // [5,4,1]`)], displaySection: "Modifications", definitions: [ makeDefinition( @@ -274,7 +275,7 @@ export const library = [ maker.make({ name: "concat", requiresNamespace: false, - examples: [`List.concat([1,2,3], [4, 5, 6])`], + examples: [makeFnExample(`List.concat([1,2,3], [4, 5, 6])`)], displaySection: "Modifications", definitions: [ makeDefinition( @@ -290,7 +291,7 @@ export const library = [ maker.make({ name: "sortBy", requiresNamespace: true, - examples: [`List.sortBy([{a:3}, {a:1}], {|f| f.a})`], + examples: [makeFnExample(`List.sortBy([{a:3}, {a:1}], {|f| f.a})`)], displaySection: "Modifications", definitions: [ makeDefinition( @@ -310,7 +311,7 @@ export const library = [ maker.make({ name: "minBy", requiresNamespace: true, - examples: [`List.minBy([{a:3}, {a:1}], {|f| f.a})`], + examples: [makeFnExample(`List.minBy([{a:3}, {a:1}], {|f| f.a})`)], displaySection: "Queries", definitions: [ makeDefinition( @@ -336,7 +337,7 @@ export const library = [ maker.make({ name: "maxBy", requiresNamespace: true, - examples: [`List.maxBy([{a:3}, {a:1}], {|f| f.a})`], + examples: [makeFnExample(`List.maxBy([{a:3}, {a:1}], {|f| f.a})`)], displaySection: "Queries", definitions: [ makeDefinition( @@ -362,7 +363,7 @@ export const library = [ maker.make({ name: "append", requiresNamespace: true, - examples: [`List.append([1,4],5)`], + examples: [makeFnExample(`List.append([1,4],5)`)], displaySection: "Modifications", definitions: [ makeDefinition( @@ -377,7 +378,7 @@ export const library = [ description: "Returns a copy of the list, between the selected ``start`` and ``end``, end not included. Directly uses the [Javascript implementation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) underneath.", requiresNamespace: true, - examples: [`List.slice([1,2,5,10],1,3)`], + examples: [makeFnExample(`List.slice([1,2,5,10],1,3)`)], displaySection: "Filtering", definitions: [ makeDefinition( @@ -404,7 +405,7 @@ export const library = [ description: "Filters the list for unique elements. Works on select Squiggle types.", requiresNamespace: true, - examples: [`List.uniq([1,2,3,"hi",false,"hi"])`], + examples: [makeFnExample(`List.uniq([1,2,3,"hi",false,"hi"])`)], displaySection: "Filtering", definitions: [ makeDefinition( @@ -419,7 +420,7 @@ export const library = [ description: "Filters the list for unique elements. Works on select Squiggle types.", requiresNamespace: true, - examples: [`List.uniqBy([[1,5], [3,5], [5,7]], {|x| x[1]})`], + examples: [makeFnExample(`List.uniqBy([[1,5], [3,5], [5,7]], {|x| x[1]})`)], displaySection: "Filtering", definitions: [ makeDefinition( @@ -442,8 +443,8 @@ export const library = [ requiresNamespace: false, displaySection: "Functional Transformations", examples: [ - "List.map([1,4,5], {|x| x+1})", - "List.map([1,4,5], {|x,i| x+i+1})", + makeFnExample("List.map([1,4,5], {|x| x+1})"), + makeFnExample("List.map([1,4,5], {|x,i| x+i+1})"), ], definitions: [ makeAssertDefinition( @@ -475,7 +476,7 @@ export const library = [ displaySection: "Functional Transformations", description: "Applies `f` to each element of `arr`. The function `f` has two main paramaters, an accumulator and the next value from the array. It can also accept an optional third `index` parameter.", - examples: [`List.reduce([1,4,5], 2, {|acc, el| acc+el})`], + examples: [makeFnExample(`List.reduce([1,4,5], 2, {|acc, el| acc+el})`)], definitions: [ makeAssertDefinition( [frNumber, frNamed("fn", frLambdaNand([2, 3]))], @@ -515,7 +516,9 @@ export const library = [ name: "reduceReverse", requiresNamespace: false, displaySection: "Functional Transformations", - examples: [`List.reduceReverse([1,4,5], 2, {|acc, el| acc-el})`], + examples: [ + makeFnExample(`List.reduceReverse([1,4,5], 2, {|acc, el| acc-el})`), + ], description: `Works like \`reduce\`, but the function is applied to each item from the last back to the first.`, definitions: [ makeDefinition( @@ -547,17 +550,17 @@ export const library = [ // Returns the last value that fits the condition. // If even initial value doesn't fit the condition, it will be returned anyway; // So the result isn't guaranteed to fit the condition. - `// Adds first two elements, returns \`11\`. + makeFnExample(`// Adds first two elements, returns \`11\`. List.reduceWhile([5, 6, 7], 0, {|acc, curr| acc + curr}, {|acc| acc < 15}) -`, - `// Adds first two elements, returns \`{ x: 11 }\`. +`), + makeFnExample(`// Adds first two elements, returns \`{ x: 11 }\`. List.reduceWhile( [5, 6, 7], { x: 0 }, {|acc, curr| { x: acc.x + curr }}, {|acc| acc.x < 15} ) -`, +`), ], description: `Works like \`reduce\`, but stops when the condition is no longer met. This is useful, in part, for simulating processes that need to stop based on the process state. `, @@ -591,7 +594,7 @@ List.reduceWhile( maker.make({ name: "filter", requiresNamespace: false, - examples: [`List.filter([1,4,5], {|x| x>3})`], + examples: [makeFnExample(`List.filter([1,4,5], {|x| x>3})`)], displaySection: "Filtering", definitions: [ makeDefinition( @@ -608,7 +611,7 @@ List.reduceWhile( maker.make({ name: "every", requiresNamespace: true, - examples: [`List.every([1,4,5], {|el| el>3 })`], + examples: [makeFnExample(`List.every([1,4,5], {|el| el>3 })`)], displaySection: "Queries", definitions: [ makeDefinition( @@ -625,7 +628,7 @@ List.reduceWhile( maker.make({ name: "some", requiresNamespace: true, - examples: [`List.some([1,4,5], {|el| el>3 })`], + examples: [makeFnExample(`List.some([1,4,5], {|el| el>3 })`)], displaySection: "Queries", definitions: [ makeDefinition( @@ -643,7 +646,7 @@ List.reduceWhile( name: "find", description: "Returns an error if there is no value found", requiresNamespace: true, - examples: [`List.find([1,4,5], {|el| el>3 })`], + examples: [makeFnExample(`List.find([1,4,5], {|el| el>3 })`)], displaySection: "Queries", definitions: [ makeDefinition( @@ -666,7 +669,7 @@ List.reduceWhile( name: "findIndex", description: "Returns `-1` if there is no value found", requiresNamespace: true, - examples: [`List.findIndex([1,4,5], {|el| el>3 })`], + examples: [makeFnExample(`List.findIndex([1,4,5], {|el| el>3 })`)], displaySection: "Queries", definitions: [ makeDefinition( @@ -683,7 +686,7 @@ List.reduceWhile( maker.make({ name: "join", requiresNamespace: true, - examples: [`List.join(["a", "b", "c"], ",") // "a,b,c"`], + examples: [makeFnExample(`List.join(["a", "b", "c"], ",") // "a,b,c"`)], displaySection: "Modifications", definitions: [ makeDefinition( @@ -697,7 +700,7 @@ List.reduceWhile( maker.make({ name: "flatten", requiresNamespace: true, - examples: [`List.flatten([[1,2], [3,4]])`], + examples: [makeFnExample(`List.flatten([[1,2], [3,4]])`)], displaySection: "Modifications", definitions: [ makeDefinition([frArray(frAny())], frArray(frAny()), ([arr]) => @@ -712,7 +715,7 @@ List.reduceWhile( maker.make({ name: "shuffle", requiresNamespace: true, - examples: [`List.shuffle([1,3,4,20])`], + examples: [makeFnExample(`List.shuffle([1,3,4,20])`)], displaySection: "Modifications", definitions: [ makeDefinition( @@ -725,7 +728,7 @@ List.reduceWhile( maker.make({ name: "zip", requiresNamespace: true, - examples: [`List.zip([1,3,4,20], [2,4,5,6])`], + examples: [makeFnExample(`List.zip([1,3,4,20], [2,4,5,6])`)], displaySection: "Modifications", definitions: [ makeDefinition( @@ -748,7 +751,7 @@ List.reduceWhile( maker.make({ name: "unzip", requiresNamespace: true, - examples: [`List.unzip([[1,2], [2,3], [4,5]])`], + examples: [makeFnExample(`List.unzip([[1,2], [2,3], [4,5]])`)], displaySection: "Modifications", definitions: [ makeDefinition( diff --git a/packages/squiggle-lang/src/fr/number.ts b/packages/squiggle-lang/src/fr/number.ts index f049eb2120..3c0c3f40f3 100644 --- a/packages/squiggle-lang/src/fr/number.ts +++ b/packages/squiggle-lang/src/fr/number.ts @@ -1,4 +1,5 @@ import { REArgumentError } from "../errors/messages.js"; +import { makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frArray, @@ -83,7 +84,7 @@ export const library = [ name: "unaryMinus", output: "Number", displaySection: "Functions (Number)", - examples: [`exp(3.5)`], + examples: [makeFnExample(`exp(3.5)`)], fn: (x) => -x, }), maker.n2n({ @@ -91,42 +92,42 @@ export const library = [ output: "Number", displaySection: "Functions (Number)", description: "exponent", - examples: [`exp(3.5)`], + examples: [makeFnExample(`exp(3.5)`)], fn: Math.exp, }), maker.n2n({ name: "log", output: "Number", displaySection: "Functions (Number)", - examples: [`log(3.5)`], + examples: [makeFnExample(`log(3.5)`)], fn: Math.log, }), maker.n2n({ name: "log10", output: "Number", displaySection: "Functions (Number)", - examples: [`log10(3.5)`], + examples: [makeFnExample(`log10(3.5)`)], fn: Math.log10, }), maker.n2n({ name: "log2", output: "Number", displaySection: "Functions (Number)", - examples: [`log2(3.5)`], + examples: [makeFnExample(`log2(3.5)`)], fn: Math.log2, }), maker.n2n({ name: "floor", output: "Number", displaySection: "Functions (Number)", - examples: [`floor(3.5)`], + examples: [makeFnExample(`floor(3.5)`)], fn: Math.floor, }), maker.n2n({ name: "ceil", output: "Number", displaySection: "Functions (Number)", - examples: ["ceil(3.5)"], + examples: [makeFnExample("ceil(3.5)")], fn: Math.ceil, }), maker.n2n({ @@ -134,21 +135,21 @@ export const library = [ output: "Number", displaySection: "Functions (Number)", description: "absolute value", - examples: [`abs(3.5)`], + examples: [makeFnExample(`abs(3.5)`)], fn: Math.abs, }), maker.n2n({ name: "round", output: "Number", displaySection: "Functions (Number)", - examples: [`round(3.5)`], + examples: [makeFnExample(`round(3.5)`)], fn: Math.round, }), maker.make({ name: "not", output: "Bool", displaySection: "Function (Number)", - examples: [`not(3.5)`], + examples: [makeFnExample(`not(3.5)`)], definitions: [ makeDefinition([frNumber], frBool, ([x]) => { // unary prefix ! @@ -160,7 +161,7 @@ export const library = [ name: "sum", output: "Number", displaySection: "Algebra (List)", - examples: [`sum([3,5,2])`], + examples: [makeFnExample(`sum([3,5,2])`)], definitions: [ makeNumberArrayToNumberDefinition((arr) => E_A_Floats.sum(arr), false), ], @@ -169,7 +170,7 @@ export const library = [ name: "product", output: "Number", displaySection: "Algebra (List)", - examples: [`product([3,5,2])`], + examples: [makeFnExample(`product([3,5,2])`)], definitions: [ makeNumberArrayToNumberDefinition( (arr) => E_A_Floats.product(arr), @@ -181,7 +182,7 @@ export const library = [ name: "min", output: "Number", displaySection: "Functions (List)", - examples: [`min([3,5,2])`], + examples: [makeFnExample(`min([3,5,2])`)], definitions: [ makeNumberArrayToNumberDefinition((arr) => Math.min(...arr)), makeDefinition([frNumber, frNumber], frNumber, ([a, b]) => { @@ -193,7 +194,7 @@ export const library = [ name: "max", output: "Number", displaySection: "Functions (List)", - examples: [`max([3,5,2])`], + examples: [makeFnExample(`max([3,5,2])`)], definitions: [ makeNumberArrayToNumberDefinition((arr) => Math.max(...arr)), makeDefinition([frNumber, frNumber], frNumber, ([a, b]) => { @@ -205,7 +206,7 @@ export const library = [ name: "mean", output: "Number", displaySection: "Functions (List)", - examples: [`mean([3,5,2])`], + examples: [makeFnExample(`mean([3,5,2])`)], definitions: [ makeNumberArrayToNumberDefinition((arr) => E_A_Floats.mean(arr)), ], @@ -213,7 +214,7 @@ export const library = [ maker.make({ name: "quantile", output: "Number", - examples: [`quantile([1,5,10,40,2,4], 0.3)`], + examples: [makeFnExample(`quantile([1,5,10,40,2,4], 0.3)`)], displaySection: "Functions (List)", definitions: [ makeDefinition([frArray(frNumber), frNumber], frNumber, ([arr, i]) => { @@ -225,7 +226,7 @@ export const library = [ maker.make({ name: "median", output: "Number", - examples: [`median([1,5,10,40,2,4])`], + examples: [makeFnExample(`median([1,5,10,40,2,4])`)], displaySection: "Functions (List)", definitions: [ makeDefinition([frArray(frNumber)], frNumber, ([arr]) => { @@ -238,7 +239,7 @@ export const library = [ name: "geomean", description: "geometric mean", output: "Number", - examples: [`geomean([3,5,2])`], + examples: [makeFnExample(`geomean([3,5,2])`)], displaySection: "Functions (List)", definitions: [ makeNumberArrayToNumberDefinition((arr) => E_A_Floats.geomean(arr)), @@ -248,7 +249,7 @@ export const library = [ name: "stdev", description: "standard deviation", output: "Number", - examples: [`stdev([3,5,2,3,5])`], + examples: [makeFnExample(`stdev([3,5,2,3,5])`)], displaySection: "Functions (List)", definitions: [ makeNumberArrayToNumberDefinition((arr) => E_A_Floats.stdev(arr)), @@ -257,7 +258,7 @@ export const library = [ maker.make({ name: "variance", output: "Number", - examples: [`variance([3,5,2,3,5])`], + examples: [makeFnExample(`variance([3,5,2,3,5])`)], displaySection: "Functions (List)", definitions: [ makeNumberArrayToNumberDefinition((arr) => E_A_Floats.variance(arr)), @@ -266,7 +267,7 @@ export const library = [ maker.make({ name: "sort", output: "Array", - examples: [`sort([3,5,2,3,5])`], + examples: [makeFnExample(`sort([3,5,2,3,5])`)], displaySection: "Functions (List)", definitions: [ makeNumberArrayToNumberArrayDefinition( @@ -280,7 +281,7 @@ export const library = [ output: "Array", description: "cumulative sum", displaySection: "Algegra (List)", - examples: [`cumsum([3,5,2,3,5])`], + examples: [makeFnExample(`cumsum([3,5,2,3,5])`)], definitions: [ makeNumberArrayToNumberArrayDefinition(E_A_Floats.cumSum, false), ], @@ -290,7 +291,7 @@ export const library = [ description: "cumulative product", output: "Array", displaySection: "Algebra (List)", - examples: [`cumprod([3,5,2,3,5])`], + examples: [makeFnExample(`cumprod([3,5,2,3,5])`)], definitions: [ makeNumberArrayToNumberArrayDefinition(E_A_Floats.cumProd, false), ], @@ -299,7 +300,7 @@ export const library = [ name: "diff", output: "Array", displaySection: "Algebra (List)", - examples: [`diff([3,5,2,3,5])`], + examples: [makeFnExample(`diff([3,5,2,3,5])`)], definitions: [makeNumberArrayToNumberArrayDefinition(E_A_Floats.diff)], }), maker.make({ @@ -307,7 +308,7 @@ export const library = [ requiresNamespace: true, output: "Domain", displaySection: "Utils", - examples: ["Number.rangeDomain(5, 10)"], + examples: [makeFnExample("Number.rangeDomain(5, 10)")], definitions: [ makeDefinition( [frNamed("min", frNumber), frNamed("max", frNumber)], diff --git a/packages/squiggle-lang/src/fr/pointset.ts b/packages/squiggle-lang/src/fr/pointset.ts index 59e8acea60..2155913e2b 100644 --- a/packages/squiggle-lang/src/fr/pointset.ts +++ b/packages/squiggle-lang/src/fr/pointset.ts @@ -2,6 +2,7 @@ import { xyShapeDistError } from "../dist/DistError.js"; import { PointSetDist } from "../dist/PointSetDist.js"; import { PointMass } from "../dist/SymbolicDist.js"; import { REDistributionError } from "../errors/messages.js"; +import { makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frArray, @@ -52,7 +53,10 @@ const fromNumber = makeDefinition([frNumber], frDistPointset, ([num], _) => { export const library = [ maker.make({ name: "make", - examples: [`PointSet.make(normal(5,10))`, `PointSet(3)`], + examples: [ + makeFnExample(`PointSet.make(normal(5,10))`), + makeFnExample(`PointSet(3)`), + ], output: "Dist", displaySection: "Constructors", definitions: [fromDist, fromNumber], @@ -61,21 +65,23 @@ export const library = [ name: "fromDist", description: "Converts the distribution in question into a point set distribution. If the distribution is symbolic, then it does this by taking the quantiles. If the distribution is a sample set, then it uses a version of kernel density estimation to approximate the point set format. One complication of this latter process is that if there is a high proportion of overlapping samples (samples that are exactly the same as each other), it will convert these samples into discrete point masses. Eventually we'd like to add further methods to help adjust this process.", - examples: [`PointSet.fromDist(normal(5,2))`], + examples: [makeFnExample(`PointSet.fromDist(normal(5,2))`)], displaySection: "Conversions", output: "Dist", definitions: [fromDist], }), maker.make({ name: "fromNumber", - examples: [`PointSet.fromNumber(3)`], + examples: [makeFnExample(`PointSet.fromNumber(3)`)], output: "Dist", displaySection: "Conversions", definitions: [fromNumber], }), maker.make({ name: "downsample", - examples: [`PointSet.downsample(PointSet.fromDist(normal(5,2)), 50)`], + examples: [ + makeFnExample(`PointSet.downsample(PointSet.fromDist(normal(5,2)), 50)`), + ], output: "Dist", displaySection: "Conversions", definitions: [ @@ -91,12 +97,12 @@ export const library = [ maker.make({ name: "makeContinuous", examples: [ - `PointSet.makeContinuous([ + makeFnExample(`PointSet.makeContinuous([ {x: 0, y: 0.2}, {x: 1, y: 0.7}, {x: 2, y: 0.8}, {x: 3, y: 0.2} -])`, +])`), ], output: "Dist", displaySection: "Constructors", @@ -117,12 +123,12 @@ export const library = [ maker.make({ name: "makeDiscrete", examples: [ - `PointSet.makeDiscrete([ + makeFnExample(`PointSet.makeDiscrete([ {x: 0, y: 0.2}, {x: 1, y: 0.7}, {x: 2, y: 0.8}, {x: 3, y: 0.2} -])`, +])`), ], output: "Dist", displaySection: "Constructors", @@ -142,7 +148,9 @@ export const library = [ }), maker.make({ name: "mapY", - examples: [`PointSet.mapY(mx(Sym.normal(5,2)), {|x| x + 1})`], + examples: [ + makeFnExample(`PointSet.mapY(mx(Sym.normal(5,2)), {|x| x + 1})`), + ], output: "Dist", displaySection: "Transformations", definitions: [ diff --git a/packages/squiggle-lang/src/fr/sampleset.ts b/packages/squiggle-lang/src/fr/sampleset.ts index 2c9d98aa4f..4a7574a6f7 100644 --- a/packages/squiggle-lang/src/fr/sampleset.ts +++ b/packages/squiggle-lang/src/fr/sampleset.ts @@ -1,4 +1,5 @@ import * as SampleSetDist from "../dist/SampleSetDist/index.js"; +import { makeFnExample } from "../library/registry/core.js"; import { FnDefinition, makeDefinition, @@ -78,9 +79,9 @@ const baseLibrary = [ "Calls the correct conversion constructor, based on the corresponding input type, to create a sample set distribution", output: "Dist", examples: [ - `SampleSet(5)`, - `SampleSet.make([3,5,2,3,5,2,3,5,2,3,3,5,3,2,3,1,1,3])`, - `SampleSet.make({|i| sample(normal(5,2))})`, + makeFnExample(`SampleSet(5)`), + makeFnExample(`SampleSet.make([3,5,2,3,5,2,3,5,2,3,3,5,3,2,3,1,1,3])`), + makeFnExample(`SampleSet.make({|i| sample(normal(5,2))})`), ], displaySection: "Constructors", definitions: [fromDist, fromNumber, fromList, fromFnDefinition], @@ -89,7 +90,7 @@ const baseLibrary = [ name: "fromDist", description: "Converts any distribution type into a sample set distribution.", - examples: [`SampleSet.fromDist(Sym.normal(5,2))`], + examples: [makeFnExample(`SampleSet.fromDist(Sym.normal(5,2))`)], displaySection: "Conversions", definitions: [fromDist], }), @@ -98,21 +99,27 @@ const baseLibrary = [ displaySection: "Conversions", description: "Convert a number into a sample set distribution that contains ``n`` copies of that number. ``n`` refers to the model sample count.", - examples: [`SampleSet.fromNumber(3)`], + examples: [makeFnExample(`SampleSet.fromNumber(3)`)], definitions: [fromNumber], }), maker.make({ name: "fromList", displaySection: "Conversions", description: "Convert a list of numbers into a sample set distribution.", - examples: [`SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5,3,2,3,1,1,3])`], + examples: [ + makeFnExample( + `SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5,3,2,3,1,1,3])` + ), + ], output: "Dist", definitions: [fromList], }), maker.make({ name: "toList", displaySection: "Conversions", - examples: [`SampleSet.toList(SampleSet.fromDist(normal(5,2)))`], + examples: [ + makeFnExample(`SampleSet.toList(SampleSet.fromDist(normal(5,2)))`), + ], description: "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.", output: "Array", @@ -127,14 +134,18 @@ const baseLibrary = [ displaySection: "Conversions", description: "Convert a function into a sample set distribution by calling it ``n`` times.", - examples: [`SampleSet.fromFn({|i| sample(normal(5,2))})`], + examples: [makeFnExample(`SampleSet.fromFn({|i| sample(normal(5,2))})`)], output: "Dist", definitions: [fromFnDefinition], }), maker.make({ name: "map", displaySection: "Transformations", - examples: [`SampleSet.map(SampleSet.fromDist(normal(5,2)), {|x| x + 1})`], + examples: [ + makeFnExample( + `SampleSet.map(SampleSet.fromDist(normal(5,2)), {|x| x + 1})` + ), + ], description: `Transforms a sample set distribution by applying a function to each sample. Returns a new sample set distribution.`, output: "Dist", definitions: [ @@ -155,11 +166,11 @@ const baseLibrary = [ name: "map2", description: `Transforms two sample set distributions by applying a function to each pair of samples. Returns a new sample set distribution.`, examples: [ - `SampleSet.map2( + makeFnExample(`SampleSet.map2( SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), {|x, y| x + y} -)`, +)`), ], output: "Dist", displaySection: "Transformations", @@ -189,12 +200,12 @@ const baseLibrary = [ maker.make({ name: "map3", examples: [ - `SampleSet.map3( + makeFnExample(`SampleSet.map3( SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), {|x, y, z| max([x,y,z])} -)`, +)`), ], output: "Dist", displaySection: "Transformations", @@ -233,14 +244,14 @@ const baseLibrary = [ maker.make({ name: "mapN", examples: [ - `SampleSet.mapN( + makeFnExample(`SampleSet.mapN( [ SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)) ], {|x| max(x)} -)`, +)`), ], output: "Dist", displaySection: "Transformations", @@ -279,9 +290,11 @@ const mkComparison = ( name, requiresNamespace: false, examples: [ - `SampleSet.${name}(SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(6,2)))`, - `SampleSet.${name}(SampleSet.fromDist(normal(5,2)), 3.0)`, - `SampleSet.${name}(4.0, SampleSet.fromDist(normal(6,2)))`, + makeFnExample( + `SampleSet.${name}(SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(6,2)))` + ), + makeFnExample(`SampleSet.${name}(SampleSet.fromDist(normal(5,2)), 3.0)`), + makeFnExample(`SampleSet.${name}(4.0, SampleSet.fromDist(normal(6,2)))`), ], output: "Dist", definitions: [ diff --git a/packages/squiggle-lang/src/fr/scale.ts b/packages/squiggle-lang/src/fr/scale.ts index 1dbb8b6488..fc79161124 100644 --- a/packages/squiggle-lang/src/fr/scale.ts +++ b/packages/squiggle-lang/src/fr/scale.ts @@ -1,4 +1,5 @@ import { REArgumentError, REOther } from "../errors/messages.js"; +import { makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frDate, @@ -53,7 +54,7 @@ export const library = [ maker.make({ name: "linear", output: "Scale", - examples: [`Scale.linear({ min: 3, max: 10 })`], + examples: [makeFnExample(`Scale.linear({ min: 3, max: 10 })`)], displaySection: "Numeric Scales", definitions: [ makeDefinition( @@ -79,7 +80,7 @@ export const library = [ maker.make({ name: "log", output: "Scale", - examples: [`Scale.log({ min: 1, max: 100 })`], + examples: [makeFnExample(`Scale.log({ min: 1, max: 100 })`)], displaySection: "Numeric Scales", definitions: [ makeDefinition( @@ -108,7 +109,7 @@ export const library = [ maker.make({ name: "symlog", output: "Scale", - examples: [`Scale.symlog({ min: -10, max: 10 })`], + examples: [makeFnExample(`Scale.symlog({ min: -10, max: 10 })`)], displaySection: "Numeric Scales", description: `Symmetric log scale. Useful for plotting data that includes zero or negative values. @@ -151,7 +152,9 @@ The default value for \`constant\` is \`${0.0001}\`.`, // I tried to set this to maker.make({ name: "power", output: "Scale", - examples: [`Scale.power({ min: 1, max: 100, exponent: 0.1 })`], + examples: [ + makeFnExample(`Scale.power({ min: 1, max: 100, exponent: 0.1 })`), + ], displaySection: "Numeric Scales", description: `Power scale. Accepts an extra \`exponent\` parameter, like, \`Scale.power({exponent: 2, min: 0, max: 100})\`. @@ -193,7 +196,9 @@ The default value for \`exponent\` is \`${0.1}\`.`, name: "date", output: "Scale", displaySection: "Date Scales", - examples: ["Scale.date({ min: Date(2022), max: Date(2025) })"], + examples: [ + makeFnExample("Scale.date({ min: Date(2022), max: Date(2025) })"), + ], description: "Only works on Date values. Is a linear scale under the hood.", definitions: [ makeDefinition( diff --git a/packages/squiggle-lang/src/fr/scoring.ts b/packages/squiggle-lang/src/fr/scoring.ts index 0f0abe48b8..33e9ddbd32 100644 --- a/packages/squiggle-lang/src/fr/scoring.ts +++ b/packages/squiggle-lang/src/fr/scoring.ts @@ -2,6 +2,7 @@ import { BaseDist } from "../dist/BaseDist.js"; import * as distOperations from "../dist/distOperations/index.js"; import { Env } from "../dist/env.js"; import { REArgumentError, REDistributionError } from "../errors/messages.js"; +import { makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frDict, @@ -57,7 +58,9 @@ export const library = [ maker.make({ name: "klDivergence", output: "Number", - examples: ["Dist.klDivergence(Sym.normal(5,2), Sym.normal(5,1.5))"], + examples: [ + makeFnExample("Dist.klDivergence(Sym.normal(5,2), Sym.normal(5,1.5))"), + ], displaySection: "Scoring", description: `[Kullback–Leibler divergence](https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence) between two distributions. @@ -76,9 +79,13 @@ Note that this can be very brittle. If the second distribution has probability m Note that it is fairly slow.`, examples: [ - "Dist.logScore({estimate: Sym.normal(5,2), answer: Sym.normal(5.2,1), prior: Sym.normal(5.5,3)})", - "Dist.logScore({estimate: Sym.normal(5,2), answer: Sym.normal(5.2,1)})", - "Dist.logScore({estimate: Sym.normal(5,2), answer: 4.5})", + makeFnExample( + "Dist.logScore({estimate: Sym.normal(5,2), answer: Sym.normal(5.2,1), prior: Sym.normal(5.5,3)})" + ), + makeFnExample( + "Dist.logScore({estimate: Sym.normal(5,2), answer: Sym.normal(5.2,1)})" + ), + makeFnExample("Dist.logScore({estimate: Sym.normal(5,2), answer: 4.5})"), ], definitions: [ makeDefinition( diff --git a/packages/squiggle-lang/src/fr/sym.ts b/packages/squiggle-lang/src/fr/sym.ts index a39b776c6f..bb5b24d017 100644 --- a/packages/squiggle-lang/src/fr/sym.ts +++ b/packages/squiggle-lang/src/fr/sym.ts @@ -1,5 +1,5 @@ import * as SymbolicDist from "../dist/SymbolicDist.js"; -import { FRFunction } from "../library/registry/core.js"; +import { FRFunction, makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frDict, @@ -58,11 +58,11 @@ export const library: FRFunction[] = [ maker.make({ name: "normal", examples: [ - "Sym.normal(5, 1)", - "Sym.normal({ p5: 4, p95: 10 })", - "Sym.normal({ p10: 4, p90: 10 })", - "Sym.normal({ p25: 4, p75: 10 })", - "Sym.normal({ mean: 5, stdev: 2 })", + makeFnExample("Sym.normal(5, 1)"), + makeFnExample("Sym.normal({ p5: 4, p95: 10 })"), + makeFnExample("Sym.normal({ p10: 4, p90: 10 })"), + makeFnExample("Sym.normal({ p25: 4, p75: 10 })"), + makeFnExample("Sym.normal({ mean: 5, stdev: 2 })"), ], definitions: [ makeTwoArgsSymDist((mean, stdev) => @@ -85,11 +85,11 @@ export const library: FRFunction[] = [ maker.make({ name: "lognormal", examples: [ - "Sym.lognormal(0.5, 0.8)", - "Sym.lognormal({ p5: 4, p95: 10 })", - "Sym.lognormal({ p10: 4, p90: 10 })", - "Sym.lognormal({ p25: 4, p75: 10 })", - "Sym.lognormal({ mean: 5, stdev: 2 })", + makeFnExample("Sym.lognormal(0.5, 0.8)"), + makeFnExample("Sym.lognormal({ p5: 4, p95: 10 })"), + makeFnExample("Sym.lognormal({ p10: 4, p90: 10 })"), + makeFnExample("Sym.lognormal({ p25: 4, p75: 10 })"), + makeFnExample("Sym.lognormal({ mean: 5, stdev: 2 })"), ], definitions: [ makeTwoArgsSymDist((mu, sigma) => @@ -111,7 +111,7 @@ export const library: FRFunction[] = [ }), maker.make({ name: "uniform", - examples: ["Sym.uniform(10, 12)"], + examples: [makeFnExample("Sym.uniform(10, 12)")], definitions: [ makeTwoArgsSymDist((low, high) => SymbolicDist.Uniform.make({ low, high }) @@ -120,7 +120,10 @@ export const library: FRFunction[] = [ }), maker.make({ name: "beta", - examples: ["Sym.beta(20, 25)", "Sym.beta({ mean: 0.39, stdev: 0.1 })"], + examples: [ + makeFnExample("Sym.beta(20, 25)"), + makeFnExample("Sym.beta({ mean: 0.39, stdev: 0.1 })"), + ], definitions: [ makeTwoArgsSymDist((alpha, beta) => SymbolicDist.Beta.make({ alpha, beta }) @@ -132,7 +135,7 @@ export const library: FRFunction[] = [ }), maker.make({ name: "cauchy", - examples: ["Sym.cauchy(5, 1)"], + examples: [makeFnExample("Sym.cauchy(5, 1)")], definitions: [ makeTwoArgsSymDist((local, scale) => SymbolicDist.Cauchy.make({ local, scale }) @@ -141,7 +144,7 @@ export const library: FRFunction[] = [ }), maker.make({ name: "gamma", - examples: ["Sym.gamma(5, 1)"], + examples: [makeFnExample("Sym.gamma(5, 1)")], definitions: [ makeTwoArgsSymDist((shape, scale) => SymbolicDist.Gamma.make({ shape, scale }) @@ -150,7 +153,7 @@ export const library: FRFunction[] = [ }), maker.make({ name: "logistic", - examples: ["Sym.logistic(5, 1)"], + examples: [makeFnExample("Sym.logistic(5, 1)")], definitions: [ makeTwoArgsSymDist((location, scale) => SymbolicDist.Logistic.make({ location, scale }) @@ -159,20 +162,20 @@ export const library: FRFunction[] = [ }), maker.make({ name: "exponential", - examples: ["Sym.exponential(2)"], + examples: [makeFnExample("Sym.exponential(2)")], definitions: [ makeOneArgSymDist((rate) => SymbolicDist.Exponential.make(rate)), ], }), maker.make({ name: "bernoulli", - examples: ["Sym.bernoulli(0.5)"], + examples: [makeFnExample("Sym.bernoulli(0.5)")], definitions: [makeOneArgSymDist((p) => SymbolicDist.Bernoulli.make(p))], }), maker.make({ name: "pointMass", requiresNamespace: false, - examples: ["pointMass(0.5)"], + examples: [makeFnExample("pointMass(0.5)")], description: "Point mass distributions are already symbolic, so you can use the regular `pointMass` function.", definitions: [ @@ -184,7 +187,7 @@ export const library: FRFunction[] = [ }), maker.make({ name: "triangular", - examples: ["Sym.triangular(3, 5, 10)"], + examples: [makeFnExample("Sym.triangular(3, 5, 10)")], definitions: [ makeDefinition( [frNumber, frNumber, frNumber], diff --git a/packages/squiggle-lang/src/fr/units.ts b/packages/squiggle-lang/src/fr/units.ts index f77c2f931c..d87a4388b6 100644 --- a/packages/squiggle-lang/src/fr/units.ts +++ b/packages/squiggle-lang/src/fr/units.ts @@ -1,3 +1,4 @@ +import { makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frNumber, frWithTags } from "../library/registry/frTypes.js"; import { FnFactory } from "../library/registry/helpers.js"; @@ -18,7 +19,7 @@ const makeUnitFn = ( output: "Number", name: "fromUnit_" + shortName, description: `Unit conversion from ${fullName}.`, - examples: [`3${shortName} // ${3 * multiplier}`], + examples: [makeFnExample(`3${shortName} // ${3 * multiplier}`)], isUnit: true, definitions: [ format diff --git a/packages/squiggle-lang/src/library/registry/core.ts b/packages/squiggle-lang/src/library/registry/core.ts index a7d6377d47..e2b2c0cc94 100644 --- a/packages/squiggle-lang/src/library/registry/core.ts +++ b/packages/squiggle-lang/src/library/registry/core.ts @@ -12,13 +12,27 @@ import { type Shorthand = { type: "infix" | "unary"; symbol: string }; +type example = { + text: string; + isInteractive: boolean; + useForTests: boolean; +}; + +export function makeFnExample( + text: string, + isInteractive = false, + useForTests = true +): example { + return { text, isInteractive, useForTests }; +} + export type FRFunction = { name: string; nameSpace: string; requiresNamespace: boolean; definitions: FnDefinition[]; output?: Value["type"]; - examples?: string[]; + examples?: example[]; interactiveExamples?: string[]; description?: string; isExperimental?: boolean; @@ -27,6 +41,17 @@ export type FRFunction = { displaySection?: string; }; +function organizedExamples(f: FRFunction) { + return [ + ...(f.examples ?? []), + ...(f.interactiveExamples?.map((e) => ({ + text: e, + isInteractive: true, + useForTests: false, + })) ?? []), + ]; +} + type FnNameDict = Map; export type FnDocumentation = Pick< @@ -78,17 +103,10 @@ export class Registry { return new Registry(fns, dict); } - allExamplesWithFns(): { fn: FRFunction; example: string }[] { + allExamplesWithFns(): { fn: FRFunction; example: example }[] { return this.functions .map((fn) => { - const regularExamples = - fn.examples?.map((example) => ({ - fn, - example, - })) ?? []; - const interactiveExamples = - fn.interactiveExamples?.map((example) => ({ fn, example })) ?? []; - return [...regularExamples, ...interactiveExamples]; + return organizedExamples(fn).map((example) => ({ fn, example })); }) .flat(); } From f6f1b8f94a176956ab334b0b9958b5cfcbf19470 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 11 Jan 2024 18:04:31 -0800 Subject: [PATCH 5/9] Removed interactiveExamples --- packages/squiggle-lang/src/fr/calculator.ts | 10 +++-- packages/squiggle-lang/src/fr/common.ts | 8 +++- packages/squiggle-lang/src/fr/danger.ts | 11 ----- packages/squiggle-lang/src/fr/date.ts | 23 ++++++++--- packages/squiggle-lang/src/fr/dict.ts | 7 +++- packages/squiggle-lang/src/fr/plot.ts | 41 ++++++++++++++----- .../squiggle-lang/src/fr/relativeValues.ts | 8 +++- packages/squiggle-lang/src/fr/table.ts | 13 ++++-- packages/squiggle-lang/src/fr/tag.ts | 13 ++++-- .../src/library/registry/core.ts | 16 ++------ 10 files changed, 94 insertions(+), 56 deletions(-) diff --git a/packages/squiggle-lang/src/fr/calculator.ts b/packages/squiggle-lang/src/fr/calculator.ts index 946e508a53..8c0db47253 100644 --- a/packages/squiggle-lang/src/fr/calculator.ts +++ b/packages/squiggle-lang/src/fr/calculator.ts @@ -1,3 +1,4 @@ +import { makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frArray, @@ -34,8 +35,9 @@ export const library = [ maker.make({ name: "make", output: "Calculator", - interactiveExamples: [ - `Calculator.make( + examples: [ + makeFnExample( + `Calculator.make( {|x, y| x * y}, { title: "My great calculator", @@ -47,7 +49,9 @@ export const library = [ sampleCount: 10k, } )`, - "({|x| x * 5}) -> Calculator", + { isInteractive: true } + ), + makeFnExample("({|x| x * 5}) -> Calculator", { isInteractive: true }), ], description: ` \`Calculator.make\` takes in a function, a description, and a list of inputs. The function should take in the same number of arguments as the number of inputs, and the arguments should be of the same type as the default value of the input. diff --git a/packages/squiggle-lang/src/fr/common.ts b/packages/squiggle-lang/src/fr/common.ts index 10320067a7..84c0f69dad 100644 --- a/packages/squiggle-lang/src/fr/common.ts +++ b/packages/squiggle-lang/src/fr/common.ts @@ -1,4 +1,5 @@ import { REThrow } from "../errors/messages.js"; +import { makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frAny, @@ -37,11 +38,14 @@ export const library = [ name: "typeOf", description: "Returns the type of the value passed in as a string. This is useful when you want to treat a value differently depending on its type.", - interactiveExamples: [ - `myString = typeOf("foo") + examples: [ + makeFnExample( + `myString = typeOf("foo") myBool = typeOf(true) myDist = typeOf(5 to 10) myFn = typeOf({|e| e})`, + { isInteractive: true } + ), ], definitions: [ makeDefinition([frAny()], frString, ([value]) => { diff --git a/packages/squiggle-lang/src/fr/danger.ts b/packages/squiggle-lang/src/fr/danger.ts index cf7e5897fc..7e9784622c 100644 --- a/packages/squiggle-lang/src/fr/danger.ts +++ b/packages/squiggle-lang/src/fr/danger.ts @@ -2,14 +2,6 @@ import jstat from "jstat"; -import { - scaleLog, - scaleLogWithThreshold, -} from "../dist/distOperations/index.js"; -import { - scaleMultiply, - scalePower, -} from "../dist/distOperations/scaleOperations.js"; import * as SymbolicDist from "../dist/SymbolicDist.js"; import { REArgumentError, REOther } from "../errors/messages.js"; import { FRFunction, makeFnExample } from "../library/registry/core.js"; @@ -17,8 +9,6 @@ import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frAny, frArray, - frDist, - frDistPointset, frLambda, frNamed, frNumber, @@ -28,7 +18,6 @@ import { FnFactory, makeOneArgSamplesetDist, makeTwoArgsSamplesetDist, - unwrapDistResult, } from "../library/registry/helpers.js"; import { ReducerContext } from "../reducer/context.js"; import { Lambda } from "../reducer/lambda.js"; diff --git a/packages/squiggle-lang/src/fr/date.ts b/packages/squiggle-lang/src/fr/date.ts index 1860f4930b..4977c6a94a 100644 --- a/packages/squiggle-lang/src/fr/date.ts +++ b/packages/squiggle-lang/src/fr/date.ts @@ -38,8 +38,7 @@ export const library = [ `d1 = Date.make("2020-05-12") d2 = Date.make(2020, 5, 10) d3 = Date.make(2020.5)`, - true, - false + { useForTests: false } ), ], displaySection: "Constructors", @@ -100,7 +99,11 @@ d3 = Date.make(2020.5)`, }), maker.make({ name: "subtract", - interactiveExamples: ["Date.make(2020, 5, 12) - Date.make(2000, 1, 1)"], + examples: [ + makeFnExample("Date.make(2020, 5, 12) - Date.make(2000, 1, 1)", { + isInteractive: true, + }), + ], output: "Duration", displaySection: "Algebra", definitions: [ @@ -111,7 +114,11 @@ d3 = Date.make(2020.5)`, }), maker.make({ name: "subtract", - interactiveExamples: ["Date.make(2020, 5, 12) - 20years"], + examples: [ + makeFnExample("Date.make(2020, 5, 12) - 20years", { + isInteractive: true, + }), + ], output: "Date", displaySection: "Algebra", definitions: [ @@ -122,8 +129,12 @@ d3 = Date.make(2020.5)`, }), maker.make({ name: "add", - examples: [makeFnExample("Date.make(2020, 5, 12) + 20years")], - interactiveExamples: ["20years + Date.make(2020, 5, 12)"], + examples: [ + makeFnExample("Date.make(2020, 5, 12) + 20years"), + makeFnExample("20years + Date.make(2020, 5, 12)", { + isInteractive: true, + }), + ], output: "Date", displaySection: "Algebra", definitions: [ diff --git a/packages/squiggle-lang/src/fr/dict.ts b/packages/squiggle-lang/src/fr/dict.ts index 265e909614..910b3d743c 100644 --- a/packages/squiggle-lang/src/fr/dict.ts +++ b/packages/squiggle-lang/src/fr/dict.ts @@ -215,8 +215,11 @@ Dict.mergeMany([first, snd]) // {a: 1, b: 3, c: 5}` maker.make({ name: "mapKeys", output: "Dict", - interactiveExamples: [ - `Dict.mapKeys({a: 1, b: 2, c: 5}, {|x| concat(x, "-foobar")})`, + examples: [ + makeFnExample( + `Dict.mapKeys({a: 1, b: 2, c: 5}, {|x| concat(x, "-foobar")})`, + { isInteractive: true } + ), ], displaySection: "Transformations", definitions: [ diff --git a/packages/squiggle-lang/src/fr/plot.ts b/packages/squiggle-lang/src/fr/plot.ts index d823e9241b..544f663db7 100644 --- a/packages/squiggle-lang/src/fr/plot.ts +++ b/packages/squiggle-lang/src/fr/plot.ts @@ -27,6 +27,7 @@ import { import { Lambda } from "../reducer/lambda.js"; import { clamp, sort, uniq } from "../utility/E_A_Floats.js"; import { LabeledDistribution, Plot, Scale, VDomain } from "../value/index.js"; +import { makeFnExample } from "../library/registry/core.js"; const maker = new FnFactory({ nameSpace: "Plot", @@ -168,11 +169,14 @@ const numericFnDef = () => { return maker.make({ name: "numericFn", output: "Plot", - interactiveExamples: [ - `Plot.numericFn( + examples: [ + makeFnExample( + `Plot.numericFn( {|t|t ^ 2}, { xScale: Scale.log({ min: 1, max: 100 }), points: 10 } )`, + { isInteractive: true } + ), ], definitions: [ makeDefinition( @@ -232,14 +236,17 @@ export const library = [ maker.make({ name: "dist", output: "Plot", - interactiveExamples: [ - `Plot.dist( + examples: [ + makeFnExample( + `Plot.dist( normal(5, 2), { xScale: Scale.linear({ min: -2, max: 6, title: "X Axis Title" }), showSummary: true, } )`, + { isInteractive: true } + ), ], definitions: [ @@ -300,8 +307,9 @@ export const library = [ maker.make({ name: "dists", output: "Plot", - interactiveExamples: [ - `Plot.dists( + examples: [ + makeFnExample( + `Plot.dists( { dists: [ { name: "First Dist", value: normal(0, 1) }, @@ -310,6 +318,8 @@ export const library = [ xScale: Scale.symlog({ min: -2, max: 5 }), } )`, + { isInteractive: true } + ), ], definitions: [ makeDefinition( @@ -406,8 +416,9 @@ export const library = [ maker.make({ name: "distFn", output: "Plot", - interactiveExamples: [ - `Plot.distFn( + examples: [ + makeFnExample( + `Plot.distFn( {|t|normal(t, 2) * normal(5, 3)}, { xScale: Scale.log({ min: 3, max: 100, title: "Time (years)" }), @@ -415,6 +426,8 @@ export const library = [ distXScale: Scale.linear({ tickFormat: "#x" }), } )`, + { isInteractive: true } + ), ], definitions: [ makeDefinition( @@ -483,15 +496,19 @@ export const library = [ maker.make({ name: "scatter", output: "Plot", - interactiveExamples: [ - `xDist = SampleSet.fromDist(2 to 5) + examples: [ + makeFnExample( + `xDist = SampleSet.fromDist(2 to 5) yDist = normal({p5:-3, p95:3}) * 5 - xDist ^ 2 Plot.scatter({ xDist: xDist, yDist: yDist, xScale: Scale.log({min: 1.5}), })`, - `xDist = SampleSet.fromDist(normal({p5:-2, p95:5})) + { isInteractive: true } + ), + makeFnExample( + `xDist = SampleSet.fromDist(normal({p5:-2, p95:5})) yDist = normal({p5:-3, p95:3}) * 5 - xDist Plot.scatter({ xDist: xDist, @@ -499,6 +516,8 @@ Plot.scatter({ xScale: Scale.symlog({title: "X Axis Title"}), yScale: Scale.symlog({title: "Y Axis Title"}), })`, + { isInteractive: true } + ), ], definitions: [ makeDefinition( diff --git a/packages/squiggle-lang/src/fr/relativeValues.ts b/packages/squiggle-lang/src/fr/relativeValues.ts index d918d6ca5f..dd893ac364 100644 --- a/packages/squiggle-lang/src/fr/relativeValues.ts +++ b/packages/squiggle-lang/src/fr/relativeValues.ts @@ -1,4 +1,5 @@ import { sq } from "../index.js"; +import { makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frArray, @@ -29,11 +30,14 @@ export const library = [ maker.make({ name: "gridPlot", output: "Plot", - interactiveExamples: [ - `RelativeValues.gridPlot({ + examples: [ + makeFnExample( + `RelativeValues.gridPlot({ ids: ["foo", "bar"], fn: {|id1, id2| [SampleSet.fromDist(2 to 5), SampleSet.fromDist(3 to 6)]}, })`, + { isInteractive: true } + ), ], definitions: [ makeDefinition([relativeValuesShape], frPlot, ([{ ids, fn, title }]) => { diff --git a/packages/squiggle-lang/src/fr/table.ts b/packages/squiggle-lang/src/fr/table.ts index 619bad0bec..f8f3d63040 100644 --- a/packages/squiggle-lang/src/fr/table.ts +++ b/packages/squiggle-lang/src/fr/table.ts @@ -1,3 +1,4 @@ +import { makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frAny, @@ -20,8 +21,9 @@ export const library = [ maker.make({ name: "make", output: "TableChart", - interactiveExamples: [ - `Table.make( + examples: [ + makeFnExample( + `Table.make( [ { name: "First Dist", value: normal(0, 1) }, { name: "Second Dist", value: uniform(2, 4) }, @@ -36,7 +38,10 @@ export const library = [ ], } )`, - `Table.make( + { isInteractive: true } + ), + makeFnExample( + `Table.make( [ { name: "First Dist", value: Sym.lognormal({ p5: 1, p95: 10 }) }, { name: "Second Dist", value: Sym.lognormal({ p5: 5, p95: 30 }) }, @@ -61,6 +66,8 @@ export const library = [ ], } )`, + { isInteractive: true } + ), ], definitions: [ makeDefinition( diff --git a/packages/squiggle-lang/src/fr/tag.ts b/packages/squiggle-lang/src/fr/tag.ts index 2f87029093..ac52ec9fe0 100644 --- a/packages/squiggle-lang/src/fr/tag.ts +++ b/packages/squiggle-lang/src/fr/tag.ts @@ -1,4 +1,5 @@ import { REArgumentError } from "../errors/messages.js"; +import { makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { frAny, @@ -189,10 +190,13 @@ Different types of values can be displayed in different ways. The following tabl `, displaySection: "Tags", examples: [ - `example1 = {|x| x + 1} -> Tag.showAs(Calculator) + makeFnExample( + `example1 = {|x| x + 1} -> Tag.showAs(Calculator) //... @showAs({|f| Plot.numericFn(f, { xScale: Scale.symlog() })}) example2 = {|x| x + 1}`, + { isInteractive: true, useForTests: false } + ), ], definitions: [ showAsDef(frWithTags(frDist), frPlot), @@ -289,8 +293,9 @@ example2 = {|x| x + 1}`, maker.make({ name: "notebook", description: `Displays the list of values as a notebook. This means that element indices are hidden, and the values are displayed in a vertical list. Useful for displaying combinations of text and values.`, - interactiveExamples: [ - `[ + examples: [ + makeFnExample( + `[ "### This is an opening section Here is more text. @@ -305,6 +310,8 @@ Here is more text.", Here is more text. ", ] -> Tag.notebook`, + { isInteractive: true } + ), ], displaySection: "Tags", definitions: booleanTagDefs( diff --git a/packages/squiggle-lang/src/library/registry/core.ts b/packages/squiggle-lang/src/library/registry/core.ts index e2b2c0cc94..a516c5fcf0 100644 --- a/packages/squiggle-lang/src/library/registry/core.ts +++ b/packages/squiggle-lang/src/library/registry/core.ts @@ -20,9 +20,9 @@ type example = { export function makeFnExample( text: string, - isInteractive = false, - useForTests = true + params: { isInteractive?: boolean; useForTests?: boolean } = {} ): example { + const { isInteractive = false, useForTests = true } = params; return { text, isInteractive, useForTests }; } @@ -33,7 +33,6 @@ export type FRFunction = { definitions: FnDefinition[]; output?: Value["type"]; examples?: example[]; - interactiveExamples?: string[]; description?: string; isExperimental?: boolean; isUnit?: boolean; @@ -42,14 +41,7 @@ export type FRFunction = { }; function organizedExamples(f: FRFunction) { - return [ - ...(f.examples ?? []), - ...(f.interactiveExamples?.map((e) => ({ - text: e, - isInteractive: true, - useForTests: false, - })) ?? []), - ]; + return [...(f.examples ?? [])]; } type FnNameDict = Map; @@ -62,7 +54,6 @@ export type FnDocumentation = Pick< | "definitions" | "name" | "examples" - | "interactiveExamples" | "isExperimental" | "isUnit" | "shorthand" @@ -157,7 +148,6 @@ export class Registry { description: fn.description, definitions: fn.definitions, examples: fn.examples, - interactiveExamples: fn.interactiveExamples, signatures: fn.definitions .filter((d) => showInDocumentation(d)) .map(fnDefinitionToString), From 17eaefd96c54e208649d21c7cafb646e110568e6 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Fri, 12 Jan 2024 08:23:22 -0800 Subject: [PATCH 6/9] Fixed Fn examples for FnDocumentation --- .../src/components/ui/FnDocumentation.tsx | 41 ++++++++++--------- .../FnDocumentation.stories.tsx | 20 ++++++--- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/packages/components/src/components/ui/FnDocumentation.tsx b/packages/components/src/components/ui/FnDocumentation.tsx index dd9c19ef66..0069ae22ae 100644 --- a/packages/components/src/components/ui/FnDocumentation.tsx +++ b/packages/components/src/components/ui/FnDocumentation.tsx @@ -68,7 +68,6 @@ export const FnDocumentation: FC<{ description, definitions, examples, - interactiveExamples, } = documentation; const textSize = size === "small" ? "text-xs" : "text-sm"; const fullName = `${nameSpace ? nameSpace + "." : ""}${name}`; @@ -160,31 +159,35 @@ export const FnDocumentation: FC<{ ) : null} - {examples?.length ?? interactiveExamples?.length ? ( + {examples?.length ? (
Examples
{examples && - examples.map((example, i) => ( - + examples + .filter(({ isInteractive }) => !isInteractive) + .map((example, i) => ( + + ))} + {examples + .filter(({ isInteractive }) => !!isInteractive) + .map((example, i) => ( +
+ +
))} - {(interactiveExamples ?? []).map((example, i) => ( -
- -
- ))}
) : null} diff --git a/packages/components/src/stories/InternalComponents/FnDocumentation.stories.tsx b/packages/components/src/stories/InternalComponents/FnDocumentation.stories.tsx index 77b3baefbf..b825c15c0f 100644 --- a/packages/components/src/stories/InternalComponents/FnDocumentation.stories.tsx +++ b/packages/components/src/stories/InternalComponents/FnDocumentation.stories.tsx @@ -51,23 +51,30 @@ const exampleDocumentation: FnDocumentationType = { requiresNamespace: false, signatures: ["(number, number) => number"], examples: [ - `xDist = SampleSet.fromDist(2 to 5) + { + text: `xDist = SampleSet.fromDist(2 to 5) yDist = normal({p5:-3, p95:3}) * 5 - xDist ^ 2 Plot.scatter({ xDist: xDist, yDist: yDist, xScale: Scale.log({min: 1.5}), })`, - ], - interactiveExamples: [ - `xDist = SampleSet.fromDist(2 to 5) + isInteractive: false, + useForTests: false, + }, + { + text: `xDist = SampleSet.fromDist(2 to 5) yDist = normal({p5:-3, p95:3}) * 5 - xDist ^ 2 Plot.scatter({ xDist: xDist, yDist: yDist, xScale: Scale.log({min: 1.5}), })`, - `xDist = SampleSet.fromDist(normal({p5:-2, p95:5})) + isInteractive: false, + useForTests: false, + }, + { + text: `xDist = SampleSet.fromDist(normal({p5:-2, p95:5})) yDist = normal({p5:-3, p95:3}) * 5 - xDist Plot.scatter({ title: "A Scatterplot", @@ -76,6 +83,9 @@ Plot.scatter({ xScale: Scale.symlog({title: "X Axis Title"}), yScale: Scale.symlog({title: "Y Axis Title"}), })`, + isInteractive: false, + useForTests: false, + }, ], isExperimental: true, definitions: [], From 53ae8ab7e11cb0b6aa44f6b78f02f03837793a3b Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Fri, 12 Jan 2024 11:41:29 -0800 Subject: [PATCH 7/9] Minor fix to examples ordering --- .../src/components/ui/FnDocumentation.tsx | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/packages/components/src/components/ui/FnDocumentation.tsx b/packages/components/src/components/ui/FnDocumentation.tsx index 0069ae22ae..ea12f747e1 100644 --- a/packages/components/src/components/ui/FnDocumentation.tsx +++ b/packages/components/src/components/ui/FnDocumentation.tsx @@ -168,26 +168,24 @@ export const FnDocumentation: FC<{ {examples && examples .filter(({ isInteractive }) => !isInteractive) - .map((example, i) => ( - - ))} - {examples - .filter(({ isInteractive }) => !!isInteractive) - .map((example, i) => ( -
- -
- ))} + .map(({ text, isInteractive }, i) => + isInteractive ? ( +
+ +
+ ) : ( + + ) + )} ) : null} From 06dcaae18de5f6d418a10810bc5d757bd76ebcb0 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Fri, 12 Jan 2024 12:28:59 -0800 Subject: [PATCH 8/9] Better documentation examples --- .../src/components/SquiggleEditor.tsx | 2 +- .../src/components/ui/FnDocumentation.tsx | 36 +++++++++---------- packages/squiggle-lang/src/fr/calculator.ts | 29 ++++++++------- packages/squiggle-lang/src/fr/sampleset.ts | 2 +- packages/squiggle-lang/src/fr/tag.ts | 36 +++++++++++-------- packages/website/templates.mts | 17 ++++++--- 6 files changed, 69 insertions(+), 53 deletions(-) diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index edef0d373b..cb975405c7 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -50,7 +50,7 @@ export const SquiggleEditor: FC = ({ return (
{examples && - examples - .filter(({ isInteractive }) => !isInteractive) - .map(({ text, isInteractive }, i) => - isInteractive ? ( -
- -
- ) : ( - + isInteractive ? ( +
+ - ) - )} +
+ ) : ( + + ) + )} ) : null} diff --git a/packages/squiggle-lang/src/fr/calculator.ts b/packages/squiggle-lang/src/fr/calculator.ts index 8c0db47253..e6a02a9797 100644 --- a/packages/squiggle-lang/src/fr/calculator.ts +++ b/packages/squiggle-lang/src/fr/calculator.ts @@ -38,20 +38,25 @@ export const library = [ examples: [ makeFnExample( `Calculator.make( - {|x, y| x * y}, - { - title: "My great calculator", - inputs: [ - Input.text({ name: "x", default: "20" }), - Input.textArea({ name: "y", default: "50 to 80" }), - ], - autorun: false, - sampleCount: 10k, - } -)`, +{|text, textArea, select, checkbox| text + textArea}, +{ + title: "My example calculator", + inputs: [ + Input.text({ name: "text", default: "20" }), + Input.textArea({ name: "textArea", default: "50 to 80" }), + Input.select({ name: "select", default: "second", options: ["first", "second", "third"] }), + Input.checkbox({ name: "checkbox", default: true }), + ], + sampleCount: 10k, +})`, + { isInteractive: true } + ), + makeFnExample( + `// When a calculator is created with only a function, it will guess the inputs based on the function's parameters. It won't provide default values if it's a user-written function. + +({|x| x * 5}) -> Calculator`, { isInteractive: true } ), - makeFnExample("({|x| x * 5}) -> Calculator", { isInteractive: true }), ], description: ` \`Calculator.make\` takes in a function, a description, and a list of inputs. The function should take in the same number of arguments as the number of inputs, and the arguments should be of the same type as the default value of the input. diff --git a/packages/squiggle-lang/src/fr/sampleset.ts b/packages/squiggle-lang/src/fr/sampleset.ts index 4a7574a6f7..9ba597a4e1 100644 --- a/packages/squiggle-lang/src/fr/sampleset.ts +++ b/packages/squiggle-lang/src/fr/sampleset.ts @@ -250,7 +250,7 @@ const baseLibrary = [ SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)) ], - {|x| max(x)} + max )`), ], output: "Dist", diff --git a/packages/squiggle-lang/src/fr/tag.ts b/packages/squiggle-lang/src/fr/tag.ts index ac52ec9fe0..71896f3ef3 100644 --- a/packages/squiggle-lang/src/fr/tag.ts +++ b/packages/squiggle-lang/src/fr/tag.ts @@ -191,8 +191,7 @@ Different types of values can be displayed in different ways. The following tabl displaySection: "Tags", examples: [ makeFnExample( - `example1 = {|x| x + 1} -> Tag.showAs(Calculator) -//... + `example1 = ({|x| x + 1}) -> Tag.showAs(Calculator) @showAs({|f| Plot.numericFn(f, { xScale: Scale.symlog() })}) example2 = {|x| x + 1}`, { isInteractive: true, useForTests: false } @@ -295,21 +294,28 @@ example2 = {|x| x + 1}`, description: `Displays the list of values as a notebook. This means that element indices are hidden, and the values are displayed in a vertical list. Useful for displaying combinations of text and values.`, examples: [ makeFnExample( - `[ - "### This is an opening section -Here is more text. - -Here is more text.", - Calculator({|f| f + 3}), - "### Distributions", - "#### Distribution 1", + `Calculator.make( + {|f, contents| f ? Tag.notebook(contents) : contents}, + { + description: "Shows the contents as a notebook if the checkbox is checked.", + inputs: [ + Input.checkbox({ name: "Show as Notebook", default: true }), + Input.textArea( + { + name: "Contents to show", + default: "[ + \\"## Distribution 1\\", normal(5, 2), - "#### Distribution 1", + \\"## Distribution 1\\", normal(20, 1), - " #### This is an opening section -Here is more text. -", -] -> Tag.notebook`, + \\"This is an opening section. Here is more text. +\\", +]", + } + ), + ], + } +)`, { isInteractive: true } ), ], diff --git a/packages/website/templates.mts b/packages/website/templates.mts index fd131110b3..79fba75d53 100644 --- a/packages/website/templates.mts +++ b/packages/website/templates.mts @@ -235,7 +235,7 @@ b = '\\'" NUL:\\u0000' "The Tag module handles tags, which allow the additions of metadata to Squiggle variables.", sections: [{ name: "Tags" }, { name: "Functions" }], intro: `Tags are metadata that can be added to Squiggle variables. They are used to add additional information to variables, such as names, descriptions, and visualization options. While tags can be accessed at runtime, they are primarily meant for use with the Squiggle Playground and other visualizations. -Tags can be added to variables either by using their name \`Tag.[name]\` or by using decorators. +Tags can be added to variables either by using their name \`Tag.get[Name]\` or by using decorators. ## List of Tags | Tag Name | Description | @@ -303,10 +303,17 @@ defaultCode={\`sampleSet = 30 to 50 pointSet = Sym.normal(5, 2) plot = Plot.dists([sampleSet, pointSet]) fn(e) = e -{ - json: Danger.json([sampleSet, pointSet, plot, fn]), - jsonString: Danger.jsonString([pointSet, fn]), -}\`}/>`, + +@notebook +result = [ + "### Danger.json()", + Danger.json([sampleSet, pointSet, plot, fn]), + "### Danger.jsonString", + // We don't show sampleSet or plot below because they would be too large, but feel free to try that out + Danger.jsonString([pointSet, fn]), +] +result +\`}/>`, }, { name: "Math" }, { name: "Combinatorics" }, From bd31fea518354e2048b287a796219a516a0c2955 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Fri, 12 Jan 2024 20:47:37 -0800 Subject: [PATCH 9/9] Added lint error --- packages/components/src/components/ui/FnDocumentation.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/components/src/components/ui/FnDocumentation.tsx b/packages/components/src/components/ui/FnDocumentation.tsx index 74089ba165..641cdc939e 100644 --- a/packages/components/src/components/ui/FnDocumentation.tsx +++ b/packages/components/src/components/ui/FnDocumentation.tsx @@ -68,7 +68,6 @@ export const FnDocumentation: FC<{ description, definitions, examples, - interactiveExamples, versionAdded, } = documentation; const textSize = size === "small" ? "text-xs" : "text-sm";