Version: 1.1.0

Mojo language basics

This page is the short tour of Mojo syntax. Later manual pages repeat each topic with the rules filled in.

If you already write Python, the shape of the code will look familiar. Mojo adds static types, tracked ownership, and compile-time parameters. It also has a lot in common with languages like C++ and Rust.

If you would rather build something, follow Get started with Mojo.

Mojo is still changing. The manual assumes you have written programs before. It does not assume you have used any one language.

Hello world

def main():
    print("Hello, world!")

A program starts at main. print writes its arguments to standard output. Short samples on later pages omit main. Put them inside one when you run them.

Variables

def main():
    var message = "Hello"
    var count: Int = 3
    print(message, count)

var declares the name. If you leave the type off, Mojo uses the type of the first value. That type does not change later. See variables.

Blocks and statements

A block is a header, a colon, and indented lines. Four spaces is the style the tools expect.

def main():
    var total = 0
    for n in range(4):
        total += n
    print(total)

A statement ends at the newline. Parentheses let it continue. Adjacent string literals are joined. Loops and conditions are covered in control flow.

Functions

def greet(name: String) -> String:
    return "Hello, " + name

def names the function, the parentheses name the arguments, and -> names the result. More forms, including fn and raises, are on the functions page.

Code comments

# One line.
var n = 1  # beside the code

A docstring is a triple-quoted string as the first statement of a function. mojo doc collects those strings. They are described with types and the docstring reference.

Structs

A struct packages fields and methods. The compiler knows every field.

@fieldwise_init
struct Pair:
    var first: Int
    var second: Int

def main():
    var pair = Pair(1, 2)
    print(pair.first)

@fieldwise_init writes the constructor. Lifecycle methods such as copy and destroy are generated for this simple type. Details are on the structs page.

Traits

A trait lists methods a struct must have.

trait Greeting:
    def hello(self) -> String:
        ...

struct Bot(Greeting):
    def hello(self) -> String:
        return "beep"

def run[T: Greeting](value: T):
    print(value.hello())

The square brackets are compile-time parameters, not arguments. Traits explains both the declaration and the call.

Parameterization

A parameter is fixed before the program runs.

def repeat[count: Int](text: String):
    comptime:
        for _ in range(count):
            print(text)

def main():
    repeat[3]("mojo")

The compiler can then specialize repeat for count == 3. The metaprogramming section is the full story.

Python integration

from python import Python

def main() raises:
    var np = Python.import_module("numpy")
    print(np.arange(3))

The Python module has to be installed in the environment you use to run Mojo. See Python interoperability.

Next steps

Continue with functions, or go back to the tutorial.