Hare by Example: Functions

Functions are integral to Hare like they do with any other language, but there are some unique features which we'll cover over the next few sections. Hare does not have struct methods like Go or Rust, instead it takes ideas from C where you would pass a reference of a struct as the first argument to a normal function to perform operations on it.

use fmt;
use strings;

// add has 2 int arguments and returns an int.
fn add(a: int, b: int) int = {
	return a + b;
};

// sum takes a starting int and variadic ints to add to it returning an
// int. The variadic arguments must come last in the function arguments.
fn sum(start: int, ints: int...) int = {
	for (let i .. ints) {
		start += i;
	};

	return start;
};

// print's return type is `void` since it does not return anything.
fn print(val: int) void = {
	fmt::println(val)!;

	// This is optional when the return type is `void`.
	return;
};

// The person struct has 2 functions that operate on it by using the
// patter of having a reference to a person as the first argument in a
// normal function.
type person = struct {
	first_name: str,
	last_name: str,
	age: u32,
	country: str,
};

fn full_name(p: *person) str = {
	return strings::concat(p.first_name, " ", p.last_name)!;
};

fn moved(p: *person, country: str) void = {
	p.country = country;
};

fn had_birthday(p: *person) void = {
	p.age += 1u32;
};

export fn main() void = {
	let result = add(10, 20);
	print(result);

	result = sum(100, 10, 20, 30, 40);
	print(result);

	const p = person {
		first_name = "Blain",
		last_name = "Smith",
		age = 43u32,
		country = "US",
	};

	const name = full_name(&p);
	fmt::println(name)!;

	moved(&p, "UK");
	fmt::println(p.country)!;

	had_birthday(&p);
	fmt::printf("{}\n", p.age)!;
};
$ hare run functions.ha
4/4 tasks completed (100%)
30
200
Blain Smith
UK
44