Hare is relative simple and straight forward language. This is no accident. It does have some interesting ideas never the less around tagged unions. Error handling is in the style of many modern languages.
It is an expression orientated-language
where if
can be used as an expression. Blocks can also evaluate and yield
is used to return
.
let
for variable introductionyield
. I think I prefer the {| |}
with return
of C3defer
is the only propCan declare out of order.
Has sum types (tagged unions).
Uses const
for constant, and let
to introduce a mutable variable. Uses a version of the name : type = value
syntax.
let i: int = 1337, j: int = 42;
j = i;
Introduce a struct with.
type coords = struct { x: int, y: int };
Can have anonymous structs. Supports tuples.
Uses the prefix type style ie [5]int
.
Has defer
.
Error handling is pretty typical for non-exception style languges. !
and ?
are used to simplify use. match
can be used to determine how to handle error cases. Has a somewhat unusual use of yield
to return an result.
Introduce an error type. !
means this is an error type.
// An invalid number was provided.
type invalid = !(strconv::invalid | strconv::overflow);
Can use in match
. Errors hold arbitrary data. Should implement strerror
to turn into a reasonable string.
if
acts as an expression.
Uses yield
to yield a result from a block (or "compound expression").
continue
and break
are "Terminating expressions".
Has is
and as
for type testing/conversion.as
is diffent in so far as it works iff the item is the type, if not it panics.
It looks like you can cast/define a literal type via :
.
This becomes more important when you consider that Hare is an expression-oriented language.
type index = size;
type offs = size;
export fn main() void = {
let z: (index | offs) = 1337: offs;
assert(z is offs);
};
Has struct subtyping
.
Pointers to structs enjoy a special feature in Hare: automatic sub-typing. Essentially, a pointer to one type can be automatically cast to a pointer of another type so long as the second type appears at the beginning of the first type. This is useful for implementing abstract interfaces in Hare programs.
Tagged unions.
Tagged union types have three important properties: they are commutative, associative, and reductive.
Can 'reduce' with embedded tagged unions if using ...
prefix.
Has attributes @init
and @fini
that cause function/s to be called at program startup and shutdown.
Type aliases define distinct types.
Rune constants define unicode code points. Defined via single quotes (ie not a byte).
Hare is a boring programming language. It has relatively few features, exhaustively detailed in a short 67-page language specification. There are no macros, generics, or metaprogramming features. You just write the code and it does what you said to. Hare aims to never surprise you.
Read Hare Introduction