IMPORTANT: To view this page as Markdown, append `.md` to the URL (e.g. /docs/manual/basics.md). For the complete Mojo documentation index, see llms.txt.
Skip to main content
Version: Nightly
For the complete Mojo documentation index, see llms.txt. Markdown versions of all pages are available by appending .md to any URL (e.g. /docs/manual/basics.md).

Mojo types & literals cheat sheet

Numbers, SIMD, conversions, and how to write values.
v1.2.0.dev

Mojo numbers are SIMD vectors​

SIMD is the foundation

Every fixed-width number is a 1-lane SIMD. A Float32 is a Scalar[DType.float32] is a SIMD[DType.float32, 1].

Operations on SIMD (such as cast()) work on Scalar and items declared with named type aliases (like Float64, Int16):

var float: Float64 = 42.0 # 64b 42.0
var float32 = float.cast[.float32]() # 32b 42.0
var scalar = Scalar[.float64](float)
var scalar16 = scalar.cast[.float16]() # 16b 42.0
SIMD vectors have fixed widths

Widths must be powers of two and are part of the type (SIMDLength).

var vec = SIMD[.float32, 4](1.0, 2.0, 3.0, 4.0)
var double = vec * 2.0 # [2.0, 4.0, 6.0, 8.0], all lanes
vec[0] = 5.0 # write one lane [5.0, 2.0, 3.0, 4.0]
print(vec.reduce_add()) # sum of lanes (14.0)

DType: what a SIMD lane holds

SIMD[DType.float32, 4] # DType picks the lane type
SIMD[.float32, 4] # the same; DType inferred from context
Scalar[.int] # == Int

Names mirror the types: DType.float32 ↔ Float32, DType.int8 ↔ Int8, DType.bool ↔ Bool. A DType is a name, not a type. It parameterizes SIMD, which stores the data.

SIMD construction

var broadcast = SIMD[.float64, 2](42.0) # broadcast all lanes
var specific = SIMD[.float64, 2](1.0, 2.0) # specific values
var zeros = SIMD[.float64, 2]() # zero-initialized vector

Numbers​

Integers

var n = 42 # Int: machine width
var u: UInt = 42 # machine width
var small: UInt8 = 255
var big: Int64 = -9_000_000_000
TypeMeaning
Int and UIntmachine word (typically 64-bit)
Int8 … Int256sized signed
UInt8 … UInt256sized unsigned
Bytealias for UInt8

Use Int for counts and indices; sized types when bit width is part of the contract. Each is an alias for a 1-lane SIMD.

Floating point

TypeMeaning
Float64IEEE double (default)
Float32IEEE single
Float16IEEE half
BFloat16brain float (ML training)
Float8_e4m3fn …8-bit (GPU, ML)
Float4_e2m1fn4-bit (Blackwell+)

No bare Float type. Each is an alias for a 1-lane SIMD.

Operations​

Element operations

TypeOperations
Arithmetic+, -, *, /, %, //
Comparison==, !=, <, <=, >, >=
Math functionssqrt(), sin(), cos(), fma(), etc.
Bit operations&, |, ^, ~, <<, >>

Vector operations

TypeOperations
Horizontal reductionsreduce_add(), reduce_mul(), reduce_min(), reduce_max()
Vector manipulationshuffle(), slice(), join(), split()

Number facts​

Bounds & special values

NameMeaning
bit_width_of[Int]()64 on most platforms (from std.sys.info)
UInt8.MAX255
Int8.MIN-128
Float32.MAX_FINITElargest finite
Float32.MAXinf

IEEE floats carry inf, -inf, nan, -0.0. Make them with inf[DType.float64]() and nan[DType.float64]() from std.math.

Number conversions are explicit

In addition to cast(), you can use named type aliases:

var int = 42 # Int
var f64 = Float64(int) # Int -> Float64
var i8 = Int8(int) # Int -> Int8
var back = Int(Int64(int)) # round trip
  • Without explicit typing, integer literals are Int.
  • Without explicit typing, float literals are Float64.
  • Float literals can't become integers, even with explicit typing.

Number literals

LiteralMeaning
42decimal Int
0xFF 0o52 0b1010hex, octal, binary
1_000_000underscores group digits
3.14 .5 2. 2.5e-3floats
2 ** 200comptime IntLiteral, comptime arbitrary precision

Leading zeros on base-10 integers are rejected. At runtime literals materialize to Int / Float64.

Collections​

Collection literals

Collection types
[1, 2, 3] # Array, length in the type
{"id": 1, "qty": 9} # Dict
(1, "a", 2.0) # Tuple, mixed types
{1, 2, 3} # Set

Bracket literals default to Array. For lists, use: var x: List = [ ... ] or var x: List[Type] = [ ... ].

Empty collections
For empty collections, specify explicit types before the literal.

  • var list: List[ElementType] = []
  • var dict: Dict[KeyType, ValueType] = {}
  • var set: Set[ElementType] = {}

An empty Array has no use; arrays are fixed size.

You must import for the empty Set: from std.collections import Set

Optionals

Optionals represent values that may or may not be present.

# Initialize
var foo: Optional[Int] = None
var bar: Optional[Int] = 42

# Access with default fallback
print(foo.or_else(0))
print(bar.or_else(0))

# Check then access the value
if foo:
print(foo.value())
if bar:
print(bar.value())

Strings​

String literals

Mojo strings use UTF-8 encoding. A String is mutable.

"double" 'single'

# triple quotes: newlines and indentation included
"""line one
line two"""

r"C:\raw\path" # raw: no escape processing

"\u20AC" # lowercase \u, 4 digits: € (EURO)
"\U0001F44B" # uppercase \U, 8 digits: 👋 (above U+FFFF)

# adjacent literals join, same line or across lines:
"Hello" " world!" # -> "Hello world!"
"Content of line 1. "
"Content of line 2."

Escapes:

EscapeMeaning
\n \t \" \\newline, tab, quote, backslash
\xHHbyte (2 hex digits)
\uHHHHUnicode (4 hex digits)
\UHHHHHHHHUnicode (8 hex digits)

\u and \U reject surrogate code points (U+D800 to U+DFFF).

Code points above U+FFFF need \U, not a surrogate pair.

String length

var s = "héllo"
s.byte_length() # 6: UTF-8 bytes
len(s.codepoints()) # 5: Unicode code points
len(s.graphemes()) # 5: user-visible characters

len(string) won't compile. Name the strategy you mean:

var text = "café"
text.byte_length() # 5, é is 2 bytes
text.count_codepoints() # 4, é is 1 codepoint
text.count_graphemes() # 4, é is 1 user-visible character

Counting codepoints and graphemes are O(n) operations, where n is the string length in bytes.

TStrings

TStrings are not strings. They are templates that generate strings at runtime by interpolating expressions within curly braces:

var who = "Mojo"
t"Hi, {who}!" # interpolation
t"sum = {1 + 2}" # any expression
t"{{literal braces}}" # -> {literal braces}
rt"raw\path {who}" # raw TString: \ literal
# still interpolates
String(t"x = {who}") # cast to String

Other than print(), cast to String for any context expecting a string value.

Takeaways​

Other things

NameMeaning
True Falseboolean values
Nonethe only NoneType value
Selfthe enclosing type
_discard a value in assignment
...marks a required trait method

Worth knowing

No character type

'A' is a one-letter string, the same as "A". Use ord("A") (65) and chr(66) ("B") for code points.

Formatting

TStrings don't take format specifiers: t"{x:.2f}" won't compile. Use std.math utilities like round() or String utilities like ascii_rjust() instead.

Division

/ is true division on floats and truncates toward zero on integer values.

// floors for all numbers. With a = -7, a / 2 is -3 and a // 2 is -4.

The literal expression 7 / 2 is 3.5.

Sharp edges

Int width is platform-dependent: use Int64 for a fixed width.

Integer overflows wrap: Int8(127) + 1 is -128. Shifts at or above the bit width are undefined. Integer literals wrap silently: var b: Int8 = 300 is 44, and var u: UInt8 = -1 is 255.

Float-to-integer truncates toward zero: Int(Float64(3.9)) is 3.

Int128 / Int256 are software-emulated.