Lake

Getting started

If you have not installed the toolchain yet, see Installation — one command gets you lakec, house and the standard library.

§A project in thirty seconds

house new hello
cd hello
house run

house new scaffolds a project with a lake.house manifest and a src/main.lake. house run resolves dependencies, compiles the entry point with lakec, and runs the resulting native binary.

§A first program

The smallest useful program writes a line using the standard library's println and exits.

+std.io.{ println }

main is {
  _ -> {
    println("hello, lake!")
  }
}

main is a machine with one branch (_ matches no arguments). The +std.io.{ println } line imports println from the standard library. Anywhere a code fence is marked run, press Run to compile and execute it here in the browser.

§Doing a little more

The standard library gives you real data structures. Here we build a vector, sum it, and print the total — using generics (Vec[i64]) and the [] protocol operator:

lake
+std.io.{ println }
+std.vec.{ Vec vec_new vec_push vec_len vec_get }
+std.strings.{ int_to_buf }

sum is {
  v Vec[i64] i i64 acc i64 -> ret i64 {
    when i >= vec_len(v) {
      true  -> { ret acc }
      false -> { self(v i + 1 acc + v[i]) }
    }
  }
}

main is {
  _ -> {
    let v0 Vec[i64] = vec_new()
    let v1 = vec_push(v0 10)
    let v2 = vec_push(v1 20)
    let v3 = vec_push(v2 30)
    println(int_to_buf(sum(v3 0 0)))    # 60
  }
}

Notice there is no loop keyword: sum recurses through a state transition (self(...)), and the two when arms replace an if.

§Program structure

A Lake program is a sequence of:

  1. Imports+std.module.{ names } pull names from other modules.
  2. Directives — compiler attributes such as @rt(...) that bind names to runtime functions.
  3. Type declarationsrecords, enums, protocols.
  4. Machines — named blocks of branches.

Machines and types may be declared in any order; forward references are resolved at compile time.

§Where to go next