Skip to content

Instantly share code, notes, and snippets.

@den-run-ai
Last active May 10, 2025 04:53
Show Gist options
  • Save den-run-ai/cd26394dd3b108b31d1c6381fba0fa7b to your computer and use it in GitHub Desktop.
Save den-run-ai/cd26394dd3b108b31d1c6381fba0fa7b to your computer and use it in GitHub Desktop.
Mojo Language Specification  - May 2025 Edition

Mojo Language Specification  · May 2025 Edition

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.


Table of Contents

  1. Language Basics
  2. Types
  3. Functions
  4. Structs
  5. Traits & Compile‑time Parameters
  6. Value Ownership & Lifecycle
  7. Operators & Expressions
  8. Pointers
  9. Python Integration
  10. GPU Programming

Language Basics

Program Structure

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.

Variables & Constants

Variables

Keyword Mutability Typical Use
var mutable loop counters, accumulators
(none) implicit var (discouraged in large code bases) quick interactive scripts

Constants

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.

Comments

# Single‑line comment

fn greet(name: String):
    """
    Prints a friendly greeting.

    Args:
        name: Person to greet.
    """
    print("Hello", name)

Types

Primitive & Fixed‑Width

  • Bool
  • Int, UInt
  • Float16, BFloat16, Float32, Float64
  • Fixed‑width integers: Int8/16/32/64, UInt8/16/32/64
  • String

Compound & Collection

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

Functions

Declaration Forms

# 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

Argument Qualifiers

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)

Variadic Parameters

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])

Structs

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

Traits and Parameters

Traits

trait Quackable:
    fn quack(self) ...

struct Duck(Quackable):
    fn quack(self):
        print("Quack!")

Common library traits: Copyable, Movable, Sized, Stringable.

Compile‑time Parameters

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

Value Ownership & Lifecycle

Ownership Transfer

fn consume(owned s: String):
    print(s)

def main():
    var greet = "hello"
    consume(greet^)          # `^` moves ownership
    # greet is now invalid

Lifecycle Hooks

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")

Operators & Expressions

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.


Pointers

Safe Pointer

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.

Unsafe & Owning Families

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.


Python Integration

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.


GPU Programming

@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 in gpu.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/

@den-run-ai
Copy link
Author

I created this concise Mojo language spec markdown document using o3 and claude 3.7 thinking.

@den-run-ai
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment