The type list
Threadon has eight built-in types.
| Type | What it holds | Notes |
|---|---|---|
Int8 | 8-bit signed integer | wraps, range -128 to 127 |
Int16 | 16-bit signed integer | wraps, range -32,768 to 32,767 |
Int32 | 32-bit signed integer | the default integer, wraps, range -2,147,483,648 to 2,147,483,647 |
Int64 | 64-bit signed integer | wraps, range -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
UInt8 | 8-bit unsigned integer | wraps, range 0 to 255 |
UInt16 | 16-bit unsigned integer | wraps, range from 0 to 65,535 |
UInt32 | 32-bit unsigned integer | wraps, range from 0 to 4,294,967,295 |
UInt64 | 64-bit unsigned integer | wraps, range from 0 to 18,446,744,073,709,551,615 |
Float16 | 16-bit float | prints like a normal float, half precision |
Float32 | 32-bit float | the default float, single precision |
Float64 | 64-bit float | If you want more precision and a bigger range, double precision |
Bool | boolean value | true or false (prints contextually based on language) |
String | text | sequence of characters, no concatenation yet |
NoneType | no value | only used for return types or representing absence of value |
Besides these, you can define your own struct types. See Structs.
Integers
A plain number in your code, like 42, is an Int32. Use the cast syntax to store it in a smaller type:
a: Int8 = Int8(10)
b: Int16 = Int16(300)
c: Int32 = 70000
If you go past the range of an integer you'll get an error if you've enabled --debug and if you're using floats you will get an error if you use the flag --flag-inf.
Look at what happens as an Int8 climbs past its maximum of 127:
def main() -> Int32
print(Int8(127))
print(Int8(128))
print(Int8(255))
return 0
It won't even compile. But if you let the user input a number you've still that risk
def main() -> Int32
print(Int8(input("input a number")))
return 0
Floats
A number with a decimal point, like 2.5, is a Float32. Float16 is the smaller sibling and Float64 the bigger sibling.
Floats print with six decimals, always. There is no formatting control yet.
def main() -> Int32
print(Float32(2.5))
print(Float64(0.1))
print(Float16(1.5))
return 0
Note that print(2.5) and print(Float32(2.5)) print the same thing. The literal is already a float.
Bools
Bool holds true or false. The literals are True and False. Conditions must be bools, so comparisons return bools.
def main() -> Int32
print(True)
print(False)
print(3 < 5)
print(3 == 5)
return 0
Strings
A String is a piece of text, written with double quotes.
name: String = "John"
Strings have no tools yet. You can't concatenate them, you can't take their length, you can't convert a number into a string. The two things you can do with a string are pass it to print or input, and convert it into a number. All of that is on the Limits page.
NoneType
NoneType means "no value". It is used as the return type of functions that don't return anything.
Always have a return in a function. You can type just returnWithout a value but the program needs to return something on every path
This
def main() -> Int32:
if 1 == 1:
return 0
else:
print()
is illegal.
def say_hi() -> NoneType
print("hi")
return
Values that were never set
If you declare a variable without giving it a value, it starts at zero. Integers start at 0, floats at 0.0, bools at false.
def main() -> Int32
n: Int32
f: Float32
b: Bool
print(n)
print(f)
print(b)
return 0
It's still a good idea to set a value yourself. The zero behavior is a convenience, not a promise, and relying on it makes code harder to read.
One exception: struct fields you leave out of an initializer are not zeroed. They hold garbage. See Structs.
Strict type checking
Threadon checks types at compile time and is strict about it. Two things you will hit immediately:
- You can't mix integer and float in the same expression.
1 + 2.5is a compile error. Convert first:Float32(1) + 2.5. - You can't compare different types.
1 == 1.0is a compile error. - You can't assign a value to a variable of a different type.
x: Int32 = 3.5is a compile error.
The one lenient case: an integer literal can adapt to the type of the variable you assign it to. x: Int8 = 5 works, even though 5 on its own is an Int32. The literal is retyped to fit. See Variables.
Everything else has to match exactly, or you convert it with a cast.