Hare Cheat Sheet
March 28, 2025
So I wrote a Hare cheat sheet. Why? For starters, I’ve long known that I’m the kind of person that learns well through examples. And why now? Well, it’s been over a year since I last wrote any Hare, and my grasp of the syntax has dulled after such a hiatus. It seemed like a good deal to create a reference for myself that would also give me a refresher in the process.
The code is shown at the end of this post and is also present as fizzbuzz.ha
in this
git repository. As the file name suggests, it’s a convoluted fizz buzz solution that takes a meandering walk through a number of Hare’s language features found in the
intro tutorial.
Features touched on:
- Constants
- Functions
- Arrays & slices
- For & for-each loops
- If/else, match, switch statements
- Structs
- Enums
- Command line arguments
use fmt;
use math;
use os;
use strconv;
use strings;
const DEFAULT_MAX = 100u;
const RANGE: [2]uint = [1, 1024];
type fbzsymbol = enum {
NONE,
FIZZ,
BUZZ,
FIZZBUZZ,
};
type params = struct {
numbers: []uint,
debug: bool,
};
export fn main() void = {
let max: uint = DEFAULT_MAX;
if (len(os::args) >= 2) {
max = match (strconv::stou(os::args[1])) {
case let i: uint =>
yield if (i >= RANGE[0] && i <= RANGE[1]) {
yield i;
} else {
fmt::fatalf("value is out valid of range [{}, {}]\n", RANGE[0], RANGE[1]);
};
case let err: (strconv::invalid | strconv::overflow) =>
fmt::fatalf("not a uint: {}\n", os::args[1]);
};
};
let numbers: []uint = [];
for (let i = 0z; i <= max; i += 1) {
append(numbers, i: uint);
};
delete(numbers[0..2]);
insert(numbers[0], 1);
defer free(numbers);
const fizzes = fizzbuzz(params { numbers = numbers, debug = true });
free(fizzes);
};
fn fizzbuzz(p: params) []fbzsymbol = {
let fizzes: []fbzsymbol = alloc([fbzsymbol::NONE...], len(p.numbers));
let i = 0;
for (let n .. p.numbers) {
if (n % 3 == 0 && n % 5 == 0) {
fizzes[i] = fbzsymbol::FIZZBUZZ;
} else if (n % 3 == 0) {
fizzes[i] = fbzsymbol::FIZZ;
} else if (n % 5 == 0) {
fizzes[i] = fbzsymbol::BUZZ;
};
if (p.debug) {
fmt::println(fbzstr(n, fizzes[i]))!;
};
i += 1;
};
return fizzes;
};
fn fbzstr(n: uint, fbz: fbzsymbol) str = {
switch (fbz) {
case fbzsymbol::NONE =>
return strconv::utos(n);
case fbzsymbol::FIZZ =>
return "FIZZ";
case fbzsymbol::BUZZ =>
return "BUZZ";
case fbzsymbol::FIZZBUZZ =>
return "FIZZBUZZ";
};
};