The BoaC Programming Guide - Built-In Types

This page describes the basic types built into the Boa language.

Basic Types
TypeDescription
boolBoolean values (true, false)
float64-bit IEEE floating point values
int64-bit signed integer values
stringArray of Unicode characters
timeUnix-like timestamp, unsigned integer representing number of microseconds since 00:00:00 UTC 1 January 1970
Array Types This section not completed yet.
array of basic_type

Arrays are containers that hold values all of the same type. They are fixed size. There are some built-in functions for working with arrays.

To allocate an array, you must either initialize it when declaring the variable or use the new function. Here are some examples:
# allocate an directly initialize a1: array of int = { 1, 2, 3 }; # allocate an initialize to the same empty string a2: array of string; a2 = new(a2, 30, "");
Map Types @since 2013-05 - This section not completed yet.
map[basic_type] of basic_type

Maps are containers that associate keys of a given type with values of another type. They are can grow dynamically. There are some built-in functions for working with maps.

To allocate a map, you simply declare a variable of that type. Note that you can not initialize maps with any data, they are always created empty. Here are some examples:
# allocate an directly initialize m1: map[string] of int; m1["k1"] = 3; m1["k2"] = 7; if (haskey(m1, "k1") && m1["k1"] > 2) remove(m1, "k2"); vs := values(m1); ks := keys(m1);
Stack Types @since 2013-05 - This section not completed yet.
stack of basic_type

Stacks are containers that have a last in first out (LIFO) behavior to them. They are can grow dynamically. There are some built-in functions for working with stacks.

To allocate a stack, you simply declare a variable of that type. Note that you can not initialize stacks with any data, they are always created empty. Here are some examples:
# allocate an directly initialize s1: stack of int; push(s1, 5); push(s1, 2); push(s1, 9); vs := values(s1); # all values in stack, without removing them v1 := pop(s1); # v1 gets 9 v2 := pop(s1); # v2 gets 2 v3 := peek(s1); # v2 gets 5 if (len(s1) > 0) v4 := pop(s1); # v4 gets 5
Set Types @since 2013-05 - This section not completed yet.
set of basic_type

Sets are containers that only store the unique values they have seen. They are can grow dynamically. There are some built-in functions for working with sets.

To allocate a set, you simply declare a variable of that type. Note that you can not initialize sets with any data, they are always created empty. Here are some examples:
# allocate an directly initialize s1: set of int; s2: set of int; add(s1, 5); add(s1, 2); add(s1, 5); add(s2, 5); s3 := union(s1, s2); # has 5 and 2 in it s4 := intersect(s1, s2); # has 5 in it vs := values(s1); # all values in set, without removing them if (len(s1) == 3) # false clear(s1); else if (contains(s1, 5)) remove(s1, 5);
Queue Types @since 2019-10 - This section not completed yet.
queue of basic_type

Queues are containers that have a first in first out (FIFO) behavior to them. They are can grow dynamically. There are some built-in functions for working with queues.

To allocate a queue, you simply declare a variable of that type. Note that you can not initialize queues with any data, they are always created empty. Here are some examples:
# allocate an directly initialize q1: queue of int; offer(q1, 5); offer(q1, 2); offer(q1, 9); vs := values(q1); # all values in queue, without removing them v1 := poll(q1); # v1 gets 5 v2 := poll(q1); # v2 gets 2 v3 := peek(q1); # v2 gets 9 if (len(q1) > 0) v4 := poll(q1); # v4 gets 9
Enum Types @since 2019-10 - This section not completed yet.
Enumerated types allow providing a fixed set of named values. Variables can take on any of the named values, and can be compared against each other.
type T1 = enum { A = "true", B = "false" }; e1: T1 = T1.A; e2: T1 = T1.B; type T2 = enum { A = "true", C = "false" }; e3: T2 = T2.A; if (e1 == e2) # false .. if (e1 == e3) # compile error - not the same types! ..
Tuple Types
Tuples are containers of other basic types. They are declared by listing the types they contain, optionally with names to access each component. Tuple fields can also be accessed positionally with an underscore and the offset, starting from 0.

# declare a tuple type named t, that holds an int, string, and bool value type t = { i: int, s: string, b: bool }; # create an instance of the tuple type t, and initialize it with some data # you must initialize all fields if assigning directly to a tuple tup: t = { 5, "string", false }; # set the value of individual fields tup._1 = "foo"; # by position tup.b = true; # or by name

Type Conversions

Each basic type can be converted to each other using built-in functions with the same name as the destination type. For example, to convert a string to an int: int("123") or to convert a string to a time: time("Wed Jul 30 23:49:55 PDT 2003").

Note that these are type conversions and not type casts. Not only will the type change, but the value might change in the conversion as well.

Type Synonyms

Boa allows declaring type synonyms, similar to the type keyword in Haskell or typedef in C/C++. The syntax is to use the keyword type followed by the new name, then an equals and the type you are creating a synonym for.

type foo = int; v: foo = 3; type myfunc = function(i: int, j: bool) : bool; f := myfunc { if (j && i < 5) return true; return false; };

This can be useful to both avoid having to type out complex types (such as set of map[string] of int) repeatedly, and also to provide a semantic name for the type to make your code more readable.