Functions

Functions are the primary unit of compiled code in Mojo. The fn keyword declares a function with strict type checking. Arguments must have explicit types, and the return type must be declared. This gives the compiler everything it needs to generate optimized machine code.

Code

fn add(a: Int, b: Int) -> Int:
    return a + b

fn main():
    let result = add(5, 3)
    print(result)  # 8

Argument Passing

By default, fn arguments are immutable references. Use mut to pass by mutable reference, owned to take ownership:

fn increment(mut x: Int):
    x += 1

fn main():
    var val = 10
    increment(val)
    print(val)  # 11

Mojo have replaced inout with mut. Right now, using inout will through an error.

Inlining

Use @always_inline to force the compiler to inline a function, eliminating call overhead:

@always_inline
fn square(x: Int) -> Int:
    return x * x

Inlining means the compiler copies the body of the function directly into the caller, instead of generating a separate function call. This eliminates call overhead (pushing arguments, jumping, returning) for that function, so square(x) becomes effectively as cheap as writing x * x directly.

Constraint

Write a function that takes two Int arguments by value and one by mut. Store the sum in the mut parameter. Verify the caller sees the mutation.

Why It Matters

Explicit argument passing semantics let the compiler avoid unnecessary copies. Inlining eliminates function call overhead entirely — critical in tight loops and compute kernels.