Skip to main content

Types

Flame types are sets whose elements are values.

Built-in Types

These are the built-in language types:

TypeRepresentsExamples
NilThe lack of a valueonly nil
Boolbooleantrue or false
Int64-bit integer1, 2, 32, 122
Float64-bit floating point number64.5, 32.9
Charunicode scalar value'a', 'z'
Stringsequence of characters"Pharaoh", "Beagle"
Symbolimmutable interned stringRED, EVENT, NAME

As you may have noticed, all types above are capitalized. That's not an accident. In fact, while constants and variables always start with a lowercase letter, types always start with an uppercase letter. Symbols, on the other hand, use exclusively uppercase letters.

Declaring New Types

To declare a type we write Name: Type:

StatusCode: Int

To create a list type we surround the list's element type with square brackets:

Numbers: [Int]
Messages: [String]

To create an object type we specify its properties' names and types inside parentheses:

Person: (
name: String
age: Int
)

To create a function type we specify the types of the arguments (in order) and the returned type:

Summation: (Int, Int) -> Int
ToString: () -> String
Effect: () -> Nil

Here is an example of a complex type:

EventList: (
events: [(
eventCode: Int
eventMessage: String
)]
lastEventCode: () -> Int
)

Methods

A method is a function that can be called on any instance of a type. Inside a method's body we can access the instance via &. For example:

Vec2.sum: (other: Vec2) -> {
&.x += other.x
&.y += other.y
}
EventList.clear: () -> {
&.events = []
}

We can then call the methods:

someVec2.sum((x: 1, y: 5))
someEventList.clear()

Type Unions

A type union is a combination of two or more types. We can denote a type union by using | between types. A type of A|B means “any value which is either an A or a B (or both)”.

To illustrate, let's declare a type that is either a String or a Bool:

StringOrBool: String|Bool

You can also use values in type unions. Here are more examples of type unions:

DiceRoll: 1|2|3|4|5|6
Num: Int|Float
Crud: CREATE|READ|UPDATE|DELETE

Type Intersections

A type intersection is a combination of two or more object types. We can denote a type intersection by using + between types. A type of A+B means “any value which satisfies both A and B”.

For example let's say we have the following types:

Named: (name: String)
Position: (x: Int, y: Int)

We can declare a new intersection type NamedPosition like so:

NamedPosition: Named+Position

And use it like this:

north := NamedPosition(name: "North", x: 0, y: 10)

Optionals

An optional is a type union between some type and nil. Flame has a shorthand for optionals - simply append a ? at the end of a type:

OptionalInt: Int? # equivalent to Int|nil
OptionalString: String? # equivalent to String|nil

Results

A result is a type union between some type and Err, where Err is the type of all Flame errors:

Err: (err: String)

Flame has a shorthand for results - simply append a ! at the end of a type:

IntOrErr: Int! # equivalent to Int|Err
StringOrErr: String! # equivalent to String|Err