Hello world
# this is a comment and will be ignored by the compiler
# the entry point to every program is the main function
# the main function (and every other function) will implicitly return the last statement
fun main() {
# the built-in dbg function is used for printing during development
dbg("Hello, World!")
}
Assignment
Variables
All variables are immutable and can’t be reassigned.
Assign a variable inside a function with var
:
fun main() {
var greeting = "Hello, James!"
dbg(greeting)
}
Constants
Assign a constant outside a function with const
:
const {
hello = "Hello, "
james = "James!"
}
fun main() {
greeting = hello ++ james
dbg(greeting)
}
const greeting = "Hello, James!"
fun main() {
dbg(greeting)
}
Public constants
Constants can be exported with pb
:
pb const hello = "hello"
pb const {
hello = "Hello, "
james = "James!"
}
const {
pb hello = "Hello, "
james = "James!"
}
Primitives
Strings
Create a string with double quotes:
"Hello, world!"
Create multiline strings with 3 double quotes:
"""
Hello, world!
"""
Concatenate strings with ++
:
"Hello, " ++ "world!"
Interpolate a string with %{}
:
var world = "world"
"Hello, %{world}!"
Escape sequences:
# \" becomes double quote
# \\ becomes backslash
# \n becomes newline
# \t becomes tab
# \% becomes percent
# \- becomes hyphen
Integers
1 - 1
1 * 1
1 / 1
1 % 1
Floats
1.0 +. 1.0
1.0 -. 1.0
1.0 *. 1.0
1.0 /. 1.0
Booleans
Boolean literals are true
and false
:
!true
true and false
false or true
Atoms
Templates
JSON
Modules
Exporting
The following expressions can be exported:
- •
const
- •
fun
- •
struct
- •
temp
Functions
Functions implicitly return the last expression.
Named functions
Create a named function with fun
followed by a function name and arguments:
fun main() {
"Hello, world!"
}
Anonymous functions
Create an anonymous function by omitting the function name:
fun (a,b) {
a - b
}
Functions are first-class citizens, so you can export them just like any other value:
pb const {
add = fun (a,b) {a + b}
square = fun (a) {a * a}
}
Control flow
Match
import std.int
var num = int.random(0, 1)
var res = match num {
0 -> "zero"
_ -> "not zero"
}
import std.int
var num = int.random(0, 10)
var res = match num {
0 -> "Number is 0"
1 -> "Number is 1"
x -> "Number is " ++ int.to_string(x)
}
import std.int
var num = int.random(0, 4)
var res = match num {
0 | 2 | 4 as x -> int.to_string(x) ++ " is even"
x -> int.to_string(x) ++ " is odd"
}
If
if true {
"This will run"
}
Else
var num = 1
if num == 1 {
"This will run"
} else {
"This won't run"
}
Templates
Create templates inside or outside a function with temp
and three hypens:
temp hello_world = ---
<h1>Hello, world!</h1>
---
Any expression can be used inside {}
:
var foo = "foo"
var exclaim = "!"
temp words = ---
<h1>{foo ++ "bar"}baz{"%{exclaim}"}</h1>
---
Use a template inside another template via self-closing tags:
module components
temp words = ---
<h1>foobarbaz</h1>
---
pb temp words_div = ---
<div>
</words>
</div>
---
Testing
fn add_one(a) {
a + 1
}
test {
1
|> add_one
|> expect(2)
}
Follow test
with a string to if a description is needed:
test "adding_one" {
# these two tests are functionally equivalent
expect(add_one(1),2)
1 |> add_one |> expect(2)
}
Web
HTML
Create HTML the same way you always have:
var hello_world = <h1>Hello, world!</h1>
Monorepos
Built-ins
A variety of built-in functions are provided in core
We will only cover a few for brevity’s sake:
# for debugging only, compiler will error if you try to build your project
dbg("foo")
var movie = [name: "Fargo", year: "1996"]
fmt("{} - {}", movie.name, movie.year) # Prints: "Fargo - 1996"
var name = "James"
type_of(name) |> dbg # Prints: string