Skip to main content

Lea Cheat Sheet

Basics

-- Comments start with --

let x = 10 -- immutable binding
maybe y = 20 -- mutable binding
y = 30 -- reassign mutable

Types

10                      -- Int
3.14 -- Float
"hello" -- String
`Hello {name}` -- Template String
true, false -- Bool
null -- Null
[1, 2, 3] -- List
(1, "a") -- Tuple
{ name: "Max" } -- Record

Operators

+ - * / %               -- arithmetic
== != < > <= >= -- comparison
++ -- string concat (coerces types)
? : -- ternary

Pipes

x /> f                  -- forward pipe: f(x)
x /> f(a) -- with args: f(x, a)
x /> f(a, input) -- placeholder: f(a, x)
x \> f \> g /> h -- parallel: h(f(x), g(x))
x </ f -- reverse pipe
[1,2,3] />>>f -- spread pipe: map f over list

Functions

let f = (x) -> x * 2                    -- single param
let f = (a, b) -> a + b -- multi param
let f = (x = 10) -> x * 2 -- default param
let f = (x, _) -> x -- ignore param

-- Multi-line
let f = (x) ->
let y = x * 2
y + 1

-- Type annotations
let f = (x) -> x * 2 :: Int :> Int
let f = (a, b) -> a + b :: (Int, Int) :> Int

-- Decorators
let f = (x) -> x #log #memo #time

-- Reversible
let f = (x) -> x * 2
and f = (x) <- x / 2

-- Overloading
let f = (a, b) -> a + b :: (Int, Int) :> Int
and f = (a, b) -> a ++ b :: (String, String) :> String

Decorators

DecoratorEffect
#logLog inputs/outputs
#memoMemoize results
#timeLog execution time
#retry(n)Retry n times
#validateRuntime type check
#asyncAsync function
#coerce(Type)Coerce inputs
#parseParse JSON/numbers
#stringifyConvert to string

Lists

let lst = [1, 2, 3]
length(lst) -- 3
head(lst) -- 1
tail(lst) -- [2, 3]
at(lst, 1) -- 2
take(lst, 2) -- [1, 2]
push(lst, 4) -- [1, 2, 3, 4]
concat(a, b) -- join lists
reverse(lst) -- [3, 2, 1]
range(1, 5) -- [1, 2, 3, 4]
[...a, ...b] -- spread

List Transformations

lst /> map((x) -> x * 2)
lst /> filter((x) -> x > 2)
lst /> reduce(0, (acc, x) -> acc + x)

-- With index
lst /> map((x, i) -> `{i}: {x}`)
lst /> filter((x, i) -> i < 2)

Records

let r = { name: "Max", age: 99 }
r.name -- "Max"
let { name, age } = r -- destructure
{ ...r, age: 100 } -- spread with override

Tuples

let t = (10, 20)
let (x, y) = t -- destructure
fst(t) -- 10
snd(t) -- 20

Strings

"a" ++ "b"              -- "ab" (concat)
`Hello {name}` -- template
split(s, ",") -- to list
join(lst, ",") -- to string
length(s) -- char count
trim(s) -- remove whitespace
chars(s) -- ["h","i"]

Pattern Matching

match x
| 0 -> "zero"
| 1 -> "one"
| if input < 0 -> "negative"
| "default"

Pipelines (First-Class)

let p = /> f /> g       -- define pipeline
x /> p -- apply
p.length -- stage count
p.stages -- ["f", "g"]
p.visualize() -- ASCII diagram

-- Algebra
Pipeline.identity
Pipeline.empty
p.prepend(f)
p.append(f)
p.reverse()
p.slice(0, 2)
p.concat(p2)

Bidirectional Pipelines

let p = </> f </> g
x /> p -- forward
x </ p -- reverse

Reactive

maybe src = [1, 2, 3]
let r = src @> map(f) /> reduce(0, add)
r.value -- compute/cache
src = [1, 2, 3, 4] -- marks dirty
r.value -- recompute

Context System

context Logger = { log: print }
provide Logger { log: (m) -> print("[LOG] " ++ m) }

let f = (x) ->
@Logger
Logger.log(x)

Async

let f = () -> delay(100) #async
await f()

await delay(100, "done")
parallel(lst, fn)
parallel(lst, fn, { limit: 2 })
race([promise1, promise2])
p /> then((x) -> x * 2)

I/O

await readFile("path")
await writeFile("path", "content")
await appendFile("path", "more")
await fileExists("path")
await deleteFile("path")
await readDir("path")
await fetch(url)
await fetch(url, { method: "POST", body: data })

Random

random()                -- [0, 1)
randomInt(10) -- [0, 10)
randomInt(5, 10) -- [5, 10)
randomFloat(10) -- [0, 10)
randomChoice(lst) -- random element
shuffle(lst) -- shuffled copy

Math

sqrt(x)  abs(x)  floor(x)  ceil(x)  round(x)
min(a, b) max(a, b)

REPL Commands

.help [topic]           -- help
.examples -- show examples
.example <n> -- run example
.type <expr> -- show type
.bindings -- list bindings
.multiline -- toggle multi-line
.tutorial -- interactive tutorial
.clear -- clear screen
.reset -- reset state
.exit -- quit

CLI

npm run repl                    # REPL
npm run repl -- --strict # strict mode
npm run repl -- --tutorial # start tutorial
npm run lea file.lea # run file
npm run lea file.lea --strict # strict mode
npm run format -- file.lea -w # format
npm run visualize -- file.lea # flowchart