freest-lang.github.io
Jekyll site (just-the-docs theme) for the FreeST documentation.
Indentation in FreeST code snippets
These rules apply to every ` ```freest ` fenced block in the Markdown sources.
1. Break the line after = when the body spans more than one line
Put nothing after the = of a definition whose body needs several lines; start the body on the next line, indented two spaces.
_ =
let (j, a) = channel @ForkJoin in
fork (\_ -> put2Chars 'a' 'b' ; join j) ;
await 2 a
Not _ = let (j, a) = channel @ForkJoin in with the rest below it.
A definition that fits on one line stays on one line — _ = print 1, _ = forkWith writeFive |> readInt. There is nothing to indent, so rule 1 does not apply.
2. Two spaces per level of indentation
Never four. Each nesting level adds two spaces to the level that encloses it:
marshall : forall a -> Tree a -> TreeC a; Close -> ()
marshall t c = mars t c |> close
where
mars : forall a b -> Tree a -> TreeC a; b -> b
mars Leaf c = c |> select Leaf
3. Alignment is not indentation — leave it alone
Some leading whitespace lines a token up with a token on an earlier line. It is not a nesting level and must not be rounded to a multiple of two. When the line it aligns with moves, it moves by the same amount, preserving the column.
FreeST’s layout rule makes this load-bearing for let: misaligning a binding changes what the code means. The same care applies to the other cases even where only readability is at stake.
_ =
let (c1, d1) = channel @Forward -- `let` is a nesting level: 2
(c2, d2) = channel @Forward -- aligned under `(c1, d1)`: 6, not 4
in fork (\_ -1-> relay c1 d2) ;
fork (\_ -1-> relay c2 d3) ; -- aligned under the first `fork`: 5
Other alignment to preserve as-is:
,under+{in a choice type, and the closing}|under=in adatadeclaration, and|guards under each other- a
|>chain continued on following lines - padding that lines up displayed laws, e.g. ` Wait ; T ≡ Wait
underClose ; T ≡ Close` (one leading space, deliberately not a level)
Notation in FreeST code snippets
These rules apply to every ` ```freest ` fenced block in the Markdown sources, and to prose that quotes a type.
1. Abbreviate -*-> to ->
Write the unrestricted arrow as its abbreviation ->, not the full -*->, except:
- inside verbatim tool output — a
freest -itranscript, or a compiler error message copied from a realfreest -trun — where the text must match exactly what the tool prints; - when the surrounding prose is explaining the
-*->notation for the first time, or contrasting it against the linear arrow-1->(e.g. two otherwise identical signatures shown side by side, one linear, one unrestricted). Most oflinearity.md, and the “Multiplicity polymorphism” section ofkinds-and-types.md, fall under this exception, since contrasting-*->against-1->is their entire point.
2. Space the colon in a kind/type-qualified variable
Write (a : 1T), not (a:1T) — a space on both sides of the colon. This applies to forall-bound variables and type abstractions (\(a : k) -> U). It does not apply to choice-type labels (+{l: T, ...}), which keep their own established convention: no space before the colon, one space after.
3. Space the type-variable binder dot in !type/?type
Write !type a. T and ?type a. T (and the matching pattern ?type a. p): no space before the dot, one space after. Same for the kinded form, ?type (a : k). T. This mirrors the choice-type label convention above.
4. Space function composition (.)
Write f . g, not f.g — a space on both sides, the same as any other binary operator.
Checking a snippet after editing it
freest -t <file>.fst type-checks without running. Re-indenting must not change the result: line:column numbers in messages shift, but the diagnostics themselves must be identical before and after.
Many snippets are fragments that use definitions introduced earlier in the same page, so Variable out of scope / Type constructor out of scope is the expected outcome for them and is not evidence of a problem. A parse error is — that is what a broken re-indent produces.
Scope note
tutorial/ and libraries/ both follow every rule on this page — indentation, notation, and the freest -t correctness check. freest3/ is the only exception: it targets a previous FreeST dialect and has not been normalised; match its surrounding style when editing it, or normalise the whole file.