Syntax
Kex borrows Ruby’s do … end blocks and identifier conventions, layers
on type annotations with :, and uses ->
for return types and = for expression-bodied functions.
Comments
# this is a line comment Bindings
let binds an immutable name. var opts into local mutation.
The ! suffix rebinds a var to a method’s updated return
value.
let name = "kex" # immutable
var count = 0 # mutable
count = count + 1 # reassign
var list = [1, 2, 3]
list.push!(4) # list := list.push(4) A binding may carry a type annotation. Inference covers most code, so an annotation is for when you want to pin the type down rather than discover it.
let count : Integer = 3
var total : Float = 0.0
foul config : [String] = FS.File.lines("app.conf").or([]) Functions
A function is either a single expression after =, or a
do … end block ending in return.
let double(n: Integer) = n * 2
let greet(name: String) -> String do
return "Hello, ${name}!"
end
let add(a, b) = a + b # types can be inferred Blocks and lambdas
[1, 2, 3].map { |x| x * 2 }
[1, 2, 3].each do |x|
IO.printLine(x.to(String))
end Records and construction
record Point do
x : Float
y : Float
end
let p = Point { x: 1.0, y: 2.0 }
A bare field name is shorthand for name: name, mirroring how
record patterns destructure with { x, y }. The two forms mix
freely.
let x = 1.0
let y = 2.0
let p = Point { x, y } # Point { x: x, y: y }
let q = Point { x, y: 5.0 } Spread
... splices a collection into the one being built. It is a
spread, not an operator — it is only valid inside a list or map literal, or
as a statement in a do block body. In a map, later entries win,
so a spread overrides what precedes it and is overridden by what follows.
let xs = [1, 2]
[0, ...xs, 5] # [0, 1, 2, 5]
let base = { "host": "localhost", "port": 80 }
{ ...base, "port": 8080 } # port becomes 8080 Control flow
Branching is if / elif / else, optionally with a trailing
if guard. Rich dispatch lives in match.
return Error(EmptyInput) if s.empty?
if n > 0
"positive"
elif n < 0
"negative"
else
"zero"
end String interpolation
let name = "world"
"Hello, ${name}!"
"${(1..3).sum}" # "6"