Skip to content

A tour in five minutes

Brackets each have one job:

Bracket Job
[ ] sets and lists: permissions, lists, paths
{ } blocks of code and records; {name} inside a string interpolates
( ) calls and grouping; the condition of if, for, match
< > type parameters only, as in Secret<String>
needs [ read [./src], run ["npm test"] ] // 1. the file starts with needs
let name = "world" // 2. let is fixed, mut changes
mut count = 0
let msg = "hello {name}" // {} interpolates
let files = [./a.ts, ./b.ts] // [] is a list; paths are bare
let cfg = { port: 8080, host: "x" } // {} is a record
let t = run("npm test")? // 3. calls; ? passes a failure up
let n = read(./count.txt) or { "0" } // or { } handles it here
if (t.failed) { log("failing") } else { log("ok") }
for (f in files) { log(f) }
let token: Secret<String> = env("TOKEN") // 4. a secret can be used, never printed

Five things to remember:

  1. The file starts with needs [ ... ].
  2. let is fixed, mut is changeable.
  3. Paths are written bare: ./src.
  4. Failure is a value: ? passes it up, or { } handles it.
  5. A secret can be used but never printed.

Statements end at the newline: no semicolons. Comments start with //.