Built-in types
Every type a file has without an import - the sized numbers, Bool, Char, String, tuples, lists, maps, ranges, Option, function types, Void and Never.
A new file starts with more than nothing: the numeric types, Bool, Char, String, tuples, List, Map,
Range, Option, function types, Void and Never are all in scope without a use. This page is the map of that
set; each type's own page has its rules.
Example#
const someInt = 10
const someFloat = 3.14
const someChar = 'A'
const someString = "Hello"
const someBool = true
const someTuple = (1, "one")
const someList = [1, 2, 3]
const someMap = ["a": 1, "b": 2]
const someRange = 0..10
const someOption: Int? = None
const someFunction = { x: Int => x * 2 }
print "{someInt} {someFloat} {someChar} {someString} {someBool}"
print "{someTuple} {someList} {someMap} {someRange}"
print "{someOption} {someFunction(3)}"Syntax#
Int Int8 Int16 Int32 Int64 signed integers; `Int` is an alias for `Int64`
UInt UInt8 UInt16 UInt32 UInt64 unsigned integers; `UInt` is an alias for `UInt64`
Float Float32 Float64 floating point; `Float` is an alias for `Float64`
Decimal exact base-ten arithmetic
Bool Char String a truth value, a Unicode scalar value, UTF-8 text
Void Never the type with one value, the type with none
(Int, String) a tuple
(lowest: Int, highest: Int) a labelled tuple; the labels are not part of the type
List<Item> Map<Key, Value> Set<Item> the collection traits
Range<Int> `0..10`, `0..=10`
RangeFrom<Int>, RangeTo<Int> `0..`, and `..10`/`..=10`
Value? `Option<Value>`
(value: Int) => Int a function type
Array<Item, const Size: Int> a fixed-size array; the size is part of the typeRules#
A numeric type always carries its width.
Int8throughInt64,UInt8throughUInt64,Float32andFloat64are the widths that exist; there is no platform-dependent integer type. See Integers and Floating-point numbers.Int,UIntandFloatare aliases for the 64-bit width, declared in the prelude like any other alias. An integer literal without an expected type isInt64, and a literal with a fraction or an exponent isFloat64- fixed, and independent of the aliases. See Type aliases.A tuple's label is not part of its type.
(lowest: Int, highest: Int)and(Int, Int)are one type, and either may be used where the other is expected. See Tuples.Value?isOption<Value>, the one way absence is written. There is nonulland nonil; a value where anOptionof its type is expected becomesSome(value)on its own. See Option.Voidhas exactly one value, the keyword literalvoid;Neverhas none and converts to every type. See Void and Never.An empty collection literal needs its element type from an annotation.
[]and[:]carry no element type of their own, soconst empty: List<String> = []needs the annotation andconst empty = []does not type check.Does not compileconst empty = [] print empty // error: Cannot infer the type of this collectionList,MapandSetare traits, not one concrete implementation each. A literal produces the standard implementation, and a signature that only needs the trait should name the trait. Which implementations exist is a different page's subject.
What this is not#
A built-in type is not a keyword. Int, String and List are ordinary names declared in the prelude, the same
way a name from any other package is - they can be shadowed by a file's own type Int = Int32, and they are looked
up the same way a project's own types are.
const count: Int = 5
print counttype Int = Int32
const count: Int = 5
print countThe second block is legal today: shadowing a prelude name is allowed, even though it means integer literals stay
Int64 regardless (rule 2), so Int and the literal type disagree inside that file.
Related#
- Bindings -
constandvar, and how a type annotation changes what a literal is. - Integers - the eight sized integer types, their ranges, and what overflow does.
- Floating-point numbers -
Float32,Float64, and the three ways to compare them. - Tuples - positional and labelled tuples in full.
- Option -
Value?,SomeandNone.