Mojo 🔥 couples Python‑level ergonomics with MLIR‑level performance. This document tracks the Mojo v25.3 manual (published 2025‑05‑06) and includes corrections up to the May 9 2025 errata.
- Language Basics
- Types
- Functions
- Structs
- Traits & Compile‑time Parameters
- Value Ownership & Lifecycle
- Operators & Expressions
- Pointers
- Python Integration
- GPU Programming
Every Mojo program begins with main()
:
def main():
print("Hello, World!")
All executable statements live inside a function—no top‑level code is run implicitly.
Keyword | Mutability | Typical Use |
---|---|---|
var |
mutable | loop counters, accumulators |
(none) | implicit var (discouraged in large code bases) |
quick interactive scripts |
Keyword | Constness (compile‑time) | Typical Use |
---|---|---|
alias |
value and type fixed | mathematical constants, type shims |
alias PI: Float64 = 3.14159 # compile‑time constant
def main():
var counter = 0 # mutable variable
print("Area factor", PI*counter)
All bindings are statically typed; the compiler infers the type when omitted.
# Single‑line comment
fn greet(name: String):
"""
Prints a friendly greeting.
Args:
name: Person to greet.
"""
print("Hello", name)
Bool
Int
,UInt
Float16
,BFloat16
,Float32
,Float64
- Fixed‑width integers:
Int8/16/32/64
,UInt8/16/32/64
String
Category | Examples |
---|---|
Tuple | (Int, Float32) – fixed length, heterogeneous |
List | List[Int] – dynamic array |
Dict | Dict[String, Int] – key/value map |
Variant | Variant[Int32, Float64] – tagged union |
LayoutTensor | LayoutTensor[dtype] – N‑dim array for ML layouts |
Pointer | Pointer[T] – safe, non‑owning, non‑nullable memory handle |
SIMD | SIMD[Int32, 8] – vector lane type |
# Python‑style – copy‑in semantics & implicit errors
def double(x: Int) -> Int:
return x * 2
# Systems‑style – borrow‑in semantics & explicit error list
fn double_safe(read x: Int) -> Int:
return x * 2 # cannot raise unless `raises` is declared
Form | Argument Mode | Error Semantics |
---|---|---|
def |
owned (each param is a copy the callee owns) | may raise implicitly |
fn |
read (immutable borrow) | must list raises |
Qualifier | Meaning (caller → callee) |
---|---|
(default) read |
immutable borrow |
mut |
mutable borrow |
owned |
transfer ownership (copy or move) |
out |
uninitialized buffer the callee will fill |
fn increment(mut x: Int): # caller’s value is modified
x += 1
fn take(owned txt: String): # ownership moves in
print(txt)
fn length(read s: String) -> Int:
return len(s)
fn mk_pair(out dst: Pair[Int, Int]):
dst = Pair(1, 2)
def sum_all(*numbers: Int) -> Int: # homogeneous
var total = 0
for n in numbers:
total += n
return total
def stringify[*Ts: Stringable](*args: *Ts) -> String: # heterogeneous
return ", ".join([str(a) for a in args])
struct Point:
var x: Int
var y: Int
fn __init__(mut self, x: Int, y: Int):
self.x = x
self.y = y
fn distance(self) -> Float64:
return (self.x**2 + self.y**2)**0.5
- Compile‑time layout, no hidden v‑table
- Supports operator overloads, decorators, and traits
@value
auto‑derives __init__
, copy, move, and destructors:
@value
struct Coordinate:
var x: Float64
var y: Float64
trait Quackable:
fn quack(self) ...
struct Duck(Quackable):
fn quack(self):
print("Quack!")
Common library traits: Copyable
, Movable
, Sized
, Stringable
.
fn repeat[count: Int](msg: String):
@parameter
for _ in range(count):
print(msg)
struct Array[Elem: Movable & Copyable]:
var data: Pointer[Elem]
var size: Int
fn consume(owned s: String):
print(s)
def main():
var greet = "hello"
consume(greet^) # `^` moves ownership
# greet is now invalid
struct Demo:
var v: Int
fn __init__(mut self, v: Int):
self.v = v; print("created")
fn __copyinit__(mut self, other: Self):
self.v = other.v; print("copied")
fn __moveinit__(mut self, owned other: Self):
self.v = other.v; print("moved")
fn __del__(owned self):
print("destroyed")
struct Complex:
var r: Float64; var i: Float64
fn __add__(self, rhs: Complex) -> Complex:
return Complex(self.r + rhs.r, self.i + rhs.i)
fn __mul__(self, rhs: Complex) -> Complex:
return Complex(
self.r*rhs.r - self.i*rhs.i,
self.r*rhs.i + self.i*rhs.r)
Supported dunders: arithmetic (__add__
, …), comparison (__eq__
, …), indexing, stringification, etc.
Type | Ownership Model |
---|---|
Pointer[T] |
safe, non‑owning, non‑nullable |
Pointer[T]
replaces the older Reference[T]
alias. It provides borrowing semantics and cannot be null.
Type | Ownership Model |
---|---|
UnsafePointer[T] |
manual alloc/free (shown below) |
OwnedPointer[T] |
RAII – frees when owner drops |
ArcPointer[T] |
atomic reference counted |
fn example():
# allocate unmanaged memory for 10 Ints
var ptr = UnsafePointer[Int].alloc(10)
ptr.store(0, 42)
var v = ptr.load(0) # 42
ptr.free()
Unsafe pointers bypass compile‑time lifetime checks—use with care.
from python import Python
fn use_numpy():
var np: PythonObject = Python.import_module("numpy")
var arr = np.array([1, 2, 3, 4, 5])
print(arr.mean())
PythonObject
encapsulates any CPython value; reference‑counting is automatic.
@adaptivegrid # runs on CPU or GPU
fn add_vecs[
dtype: DType,
tile: Int
](mut out: LayoutTensor[dtype], read a: LayoutTensor[dtype], read b: LayoutTensor[dtype]) -> None:
# implementation elided
Note
@grid
,@adaptivegrid
, and@warp
live ingpu.host
; they remain supported but are considered low‑level and may change.
Tensor intrinsics map to CUDA, HIP, MPS, or CPU fallback depending on target.
For complete details and the latest changelog, see the official manual: https://docs.modular.com/mojo/manual/
I created this concise Mojo language spec markdown document using o3 and claude 3.7 thinking.