Skip to content

Hello world

This page walks through your first Beans program from an empty file to a native binary.

Save this as hello.b:

import std.io
fn main() {
let name: string = "beans"
io.println("hello from {name}")
}

A few things to notice:

  • import std.io pulls in the standard I/O package. io.println lives there.
  • fn main() is where the program starts.
  • let name: string = "beans" declares a value. let means it does not change. The type, string, is written out. Beans does not infer it for you.
  • "hello from {name}" is an interpolated string. {name} is replaced with the value of name.

Type-check the program without running it:

Terminal window
beansc check hello.b
hello.b: ok

check catches type errors and other mistakes fast. It does not run anything.

Run the program on the reference interpreter, with no build step:

Terminal window
beansc run hello.b
hello from beans

run is the quickest way to see output while you work.

Compile to a real executable through LLVM:

Terminal window
beansc build hello.b -o hello
./hello
hello from beans

The interpreter (run) and the native binary (build) produce the same output. The two backends behave identically.

For a release build, turn on optimizations, link-time optimization, and tuning for your own CPU:

Terminal window
beansc build --release --lto --cpu native hello.b -o hello

Beans requires a function with a return type to return on every path. This program is intentionally wrong. The docs example checker confirms it fails to compile:

fn total() -> int {
var sum: int = 0
sum // a trailing expression is discarded, not returned
}
error: 'total' must return int — the body can finish without a return

The fix is to write return sum. See Functions and closures.

To grow past a single file, create a project. For more on the commands used here, see Checking and running and Building.