# Variables & Data Types

Variables enable you to store and retrieve values.

Rant is a dynamically-typed language, which means that variables don't have to contain a specific type; for example, you can initialize a variable with an integer, and later change it to a string (and vice versa).

Rant has the following data types:

Type nameDescriptionPass type
stringSequence of UTF-8 charactersby-value
int64-bit signed integerby-value
float64-bit double-precision floatby-value
boolBoolean valueby-value
rangeIndexable range of integers with optional intervalby-value
emptyUnit type representing "null" valueby-value
functionFunction/closureby-ref
listList of valuesby-ref
mapString-keyed collection of valuesby-ref
blockStored blockby-ref
specialHandle to internal runtime data, such as a selectorby-ref

## The empty type

To represent the lack of a value, Rant has the empty type, which has only one possible value, represented by the token ~.

<$nothing = ~> # i.e. <$nothing>
[type:<nothing>]  # empty


## The bool type

The two boolean values are represented by the keywords @true and @false.

## Type inference for expressions

In order to resolve type ambiguities, Rant makes a few basic assumptions:

### Integers

Any number token without a decimal place becomes an int.

[type:123]  # int


### Floats

Any number token with a decimal place becomes a float.

[type:123.0]  # float


### Top-level text

Any expression containing top-level text (i.e. not in a collection) evaluates to a string.

Whitespace at the start or end of an expression is ignored.

# Since there are fragments and whitespace, it's a string
[type:99 bottles of beer]  # string

# Since there is whitespace between the numbers, the value is still a string
[type:99 99]  # string


### Multiple values in a sequence

A sequence will evaluate to a string if the following are true:

1. There are multiple values in the expression
2. At least one value is non-empty
3. The sequence is not all lists or all maps

When these conditions are met, all values printed by the sequences are converted to their string representations and concatenated.

# Even though they are all integer tokens, they are treated as text
[type:10 20 30 40 50]  # string


#### Multiple lists

A sequence that is entirely made of lists will return a single list containing the concatenation of the input lists.

(1; 2) (3; 4) # same as (1; 2; 3; 4)


This rule also applies when the sequence contains any expression that returns a list:

[rep:10] {
([step])
}
# returns (1; 2; 3; 4; 5; 6; 7; 8; 9; 10)


#### Multiple maps

A sequence that is entirely made of maps will return a single map containing the key/value pairs of the input maps. Duplicate keys are overwritten by newer values.

<%my-map =
@(a = 1)
@(b = 2)
>
# returns @(a = 1; b = 2)


As with list sequences, this also applies with expressions that return maps:

[rep:3]{
@( {item_[step]} = [step] )
}
# returns @(item_1 = 1; item_2 = 2; item_3 = 3)


#### Empties

Expressions containing only empties evaluate to the empty value.

Expressions containing nothing also evaluate to the empty value.

[type:~~]       # empty
[type:~]        # empty
[type:]         # empty