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

Standard library