Basic LLM Prompt
LLM Prompt Example
The following is a prompt that we use to help LLMs, like GPT and Claude, write Squiggle code. This would ideally be provided with the full documentation, for example with this document.
You can read this document in plaintext here.
Write Squiggle code, using the attached documentation for how it works.
Squiggle is a very simple language. 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.
Syntax and Structure
- Variable Expansion: Not supported. Don't use syntax like |v...| or |...v|.
- All pipes are "->", not "|>".
- Dict keys and variable names must be lowercase.
- The last value in a block/function is returned (no "return" keyword).
- Variable declaration: Directly assign values to variables without using keywords. For example, use
foo = 3
instead oflet foo = 3
. - 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. - There's no mod operator (%). Use
Number.mod()
instead.
Function Definitions and Use
- Anonymous Functions: Use {|e| e} syntax for anonymous functions.
- 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 ofnormal({mean: 0.3, sd: 0.1})
. - There's no recursion.
- You can't call functions that accept ranges, with distributions. No,
({|foo: [1,20]| foo}) (4 to 5)
.
Data Types and Input Handling
- Input Types: Use Input.text for numeric inputs instead of Input.number or Input.slider.
- 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.
- Only use Inputs directly inside calculators. They won't return numbers, just input types.
Looping, Conditionals, and Data Operations
- Conditional Statements: There are no case or switch statements. Use if/else for conditional logic.
- There aren't for loops or mutation. Use immutable code, and List.map / List.reduce / List.reduceWhile.
List and Dictionary Operations
- You can't do "(0..years)". Use List.make or List.upTo.
- There's no "List.sort", but there is "List.sortBy", "Number.sort".
Randomness and Distribution Handling
- There's no random() function. Use alternatives like sample(uniform(0,1)).
- The
to
syntax only works for >0 values. "4 to 10", not "0 to 10".
Units and Scales
- The only "units" are k/m/n/M/t/B, for different orders of magnitude, and "%" for percentage (which is equal to 0.01).
Documentation and Comments
- Tags like @name and @doc apply to the following variable, not the full file.
- If you use a domain for Years, try to use the Date domain, and pass in Date objects, like Date(2022) instead of 2022.
Dictionaries and Blocks
In Squiggle, you can create dictionaries using two different syntaxes, each with distinct capabilities:
Simple Dictionaries
Use this syntax for basic key-value pairs without internal calculations:
For single-value dictionary returns, add a trailing comma. However, this pattern should be done rarely. It's often better to either return all the components inside a components dictionary or similar, or just return the value directly.
Example with trailing comma:
Prefer this instead:
Or, if you really want to return a single value:
Blocks
Use blocks when you need to:
- Perform calculations with dictionary values
- Add metadata tags
- Reference values within the dictionary
Basic block example:
Adding Tags
The recommended way to add tags is using block syntax:
Don't add tags to variables that are only used internally. The tags are only useful when variables are externally accessible.
Common Mistakes to Avoid
- Missing return value in blocks:
- Internal references in simple dictionaries:
While you can use arrow syntax for tags in dictionary blocks (->Tag.format("$,.0f")
), it's generally clearer to use the @tag
syntax shown above.
Regular Examples
Here's are some simple example Squiggle programs: