Getting started
The program the guide builds, running Calx with the calx command, values and variables, functions, loops, and the checker's errors.
This guide builds one small, real program: stash, which keeps count of the items a player puts away and takes out. It reads commands, one a line, and answers the way a game server’s console might:
add stone 64add stone 66take stone 5take dirt 20showline 4: there's no dirtstone: 1 stack and 61Each page adds to it, and the last has the whole program. This page covers what it’s made of: values, functions and loops. You’ll need to know some programming already, in any language; the guide says when Calx works differently from what you might expect.
The calx command
Section titled “The calx command”Calx compiles to C, which clang compiles, so you need clang. Until Calx has releases, you build the compiler from source, as Install Calx says. That gives you calx, the one command for checking, building and running programs.
Here’s a whole program:
fn main() { println("Hello, Calx!")}Hello, Calx!
Save it as hello.calx, and run it:
calx run hello.calxcalx runchecks the program, builds it in debug mode, and runs it. Building takes moments, and the next build only redoes what changed.calx check hello.calxchecks it without building, which is what an editor does as you type (editor support).calx build --release hello.calxbuilds an optimized executable,helloorhello.exe.
The // out: comments show what a line prints. They’re also how the guide is tested: every example on these pages is compiled and run by Calx’s test suite, which compares what it prints with the comments.
Values and variables
Section titled “Values and variables”fn main() { let item = "stone" var count = 64 count += 32 println("{count} {item}") let stacks = count / 64 let left = count % 64 println("{stacks} stack and {left}")}96 stone 1 stack and 32
letnames a value that doesn’t change, andvarone that does.- A name in braces in a string is replaced by its value. Any expression can go in the braces, as in
"{count / 64}". countis ani32, a 32-bit integer, which is what a whole-number literal is unless something else is wanted./on integers drops the remainder, and%gives it (integers).
The compiler checks the program before it builds anything, and it’s strict. Changing a let is an error:
fn main() { let count = 64 count += 1error: count can't be changed; declare it with var to change it println("{count}")}So is a var that never changes, since a let would say so more plainly:
fn main() { var count = 64error: count is declared with var but never changed; declare it with let println("{count}")}The checker has more rules like these, such as no unused imports and no names hiding others. They’re all on the strictness page. Each says what’s wrong and how to fix it.
Functions
Section titled “Functions”The stash describes counts the way players do, in stacks of 64:
// Most items stack to 64.const STACK: i32 = 64
// `count` in stacks: "2 stacks and 5".fn describe(count: i32) -> String { let full = count / STACK let left = count % STACK if full == 0 { return "{left}" } let stacks: String = if full == 1 { "1 stack" } else { "{full} stacks" } if left == 0 { return stacks } return "{stacks} and {left}"}
fn main() { for count in [5, 64, 128, 130] { println("{count}: {describe(count)}") }}5: 5 64: 1 stack 128: 2 stacks 130: 2 stacks and 2
- A function names its parameters’ types, and its result’s after
->. It gives the result withreturn. Functions can come in any order in a file. constnames a value fixed when the program compiles. A constant gives its type.ifwith anelsegives a value, so it can go where a value does, as inlet stacks = ....forgoes over a list, an array or a range:for i in 0..10counts from 0 to 9 (control flow).
Calx has two kinds of text: str, fixed text such as a literal in the program, and String, text the program builds, which owns its memory. A string with braces in it builds a String, so "{full} stacks" is one. A plain literal such as "1 stack" is a str, unless a String is wanted where it’s written. The two branches of an if must have the same type, so let stacks: String says a String is wanted, and "1 stack" is one too (strings).
Next: reading the commands.