### Built in functions

Built-ins are polymorphic functions (i.e. they can take a variety of input types) that are built into the language and that you can invoke with a syntax similar to a method call. For example:

a.sqrt()

returns the square root of a.

Built-ins apply not only to variables and constant but also to expressions:

(100 + 100).sqrt()

In the rest of this document we describe all the functions and for each one we provide the signature.

We conventionally call "argument" the value at the left of the dot operator and we call its type T.
If the argument is a vector or map T.Element is the type of the stored element.
If the argument is a map, T.Key is the type of the keys.
For complex types T.Component is the type of the single (imaginary or real) component.

For example:

T.abs() T;

returns the same type he receives as argument, has no parameters.

T.reserve(in count i64) void;

doesn't return a value, accepts an i64 as input parameter.

## scalar numbers functions

The functions below apply to integer and float arguments.

T.abs() T;
T.sqrt() T;
T.sgn() i32;

abs and sqrt return the absolute and square root values of the argument.
sgn returns -1, 0, 1 according to the sign of the argument (negative, zero, positive respectively).

## float functions

apply to f32 and f64 arguments.
If the argument is out of range, all the built-ins return nan (not a number).

Trigonometric functions. All angles are in radians.

T.sin() T;
T.cos() T;
T.tan() T;
T.asin() T;
T.acos() T;
T.atan() T;

Logaritm and exponentiation in base e (natural), 2, 10 respectively.

T.log() T;
T.exp() T;
T.log2() T;
T.exp2() T;
T.log10() T;
T.exp10() T;

Rounding functions, respectively to the lower, higher, nearest integer

T.floor() T;
T.ceil() T;
T.round() T;

## complex functions

imag and real return the imaginary and real parts.
abs and arg are the magnitude and the angle between the real axis and the vector represented by the complex number.
norm is the squared magnitude.

T.imag() T.Component;
T.real() T.Component;
T.abs() T.Component;
T.arg() T.Component;
T.norm() T.Component;

Trigonometric, logaritmic, exponentiation functions.

T.sin() T;
T.cos() T;
T.tan() T;
T.asin() T;
T.acos() T;
T.atan() T;
T.log() T;
T.exp() T;

## static arrays

T.size() i32;

Returns the array elements count.

## dynamic vectors

mut T.reserve(in count i64) void;

Forces the vector to allocate memory space in view of future expansions. Note that this doesn't change the actual size of the vector.
count is the number of elements we want to be able to store in the vector.

T.capacity() i32;

Returns the space pre-allocated with reserve (or as an effect of vector size growth). The returned value is the maximum number of elements the vector can store without reallocating.

mut T.shrink_to_fit() void;

It trims the memory allocation to that strictly needed for the current vector size.

mut T.resize(in size i64);

Resizes the vector to the wanted size.
If the size parameter is more than the current size, new elements are default initialized and appended.
If the size parameter is less than the current size, elements at the top of the vector are finalized. No memory is freed.

mut T.clear() void;

Cuts vector length to 0 without deallocating memory.

T.size() i32;

Returns the current vector length.

T.empty() bool;

Returns true if the vector length is 0.

mut T.push_back(in e T.Element) void;

Appends a new element to the vector making it one unit longer.

mut T.pop_back() void;

Deletes the last element and makes te vector one unit shorter.

mut T.insert(in idx i64, in count i64, in e T.Element) void;

Inserts count elements, all identical to e (the last parameter) after the position idx.
The vector increases its length by count.

mut T.erase(in idx i64, in top i64) void;

Erases the elements from position idx included to top (excluded).
The vector decreases its length by top - idx.

mut T.insert_v(in idx i64, in to_insert T) void;

Inserts vector to_insert inside the argument at position idx.

mut T.append(in to_append T) void;

Appends vector to_append to the argument.

## Maps

The following apply if the argument is a map:

mut T.reserve(in count i64) void;

Forces the map to allocate memory space in view of future expansions. Note that this doesn't change the actual content of the map.
count is the number of elements we want to be able to store in the map.

T.capacity() i32;

Returns the space allocated with reserve (or as an effect of map insertions). The returned value is the
maximum number of elements the map can store without reallocating.

mut T.shrink_to_fit() void;

It trims the memory allocation to that strictly needed for the current map content.

mut T.clear() void;

Clears all the map entries.

T.size() i32;

Returns the number of values stored in the map.

T.empty() bool;

Returns true if the map is empty.

mut T.insert(in key T.Key, in value T.Element) void;

Assigns a value to a key. If the key already has a value, it is replaced.

mut T.erase(in key T.Key) void;

Deletes the key and its value from the map.

T.get(in key T.Key) T.Element;

Retrieves the value of a key. Can throw an exception if the key doesn't exist in the map (was never assigned)

T.get_safe(in key T.Key, in default T.Element) T.Element;

Retrieves the value of a key. If the key doesn't exist in the map (was never assigned), returns the default value.

T.has(in key T.Key) bool;

Checks if key has a value.

T.key_at(in idx i64) T.Element;
T.value_at(in idx i64) T.Element;

Respectively read the key and value at the idx-th position.
valid idx values are from 0 to size()-1. No order is guaranteed. A key and its value are guaranteed to have the same index.