Data types

Rant has 10 built-in 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
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
emptyUnit type representing "null" valueby-value

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

Boolean values

The two boolean values are represented by the keywords true and false. These keywords can still be used as fragments when not used alone, as their string representations are simply "true" and "false"; however, if they are passed on their own and need to be strings, you will need to put them in a string literal.

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 fragments or whitespace

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

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)

Maps

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

<%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