Mojo Basics
Mojo Basics
For instance, in a REPL environment or Jupyter notebook, you can run top-level code
just like Python:
print("Hello Mojo!")
However, Mojo is not just a new implementation of Python with syntax sugar. It’s an
entirely new language that takes Python to a new level, with systems programming
features, strong type-checking, memory safety, next-generation compiler
technologies, and more, while still being a simple language useful for general-
purpose programming.
Language Basics:
fn main():
var x: Int = 1
x += 1
print(x)
If you’re familiar with Python, you might have expected the function name to be def
main() instead of fn main(). Both actually work in Mojo, but using fn behaves a bit
differently.
Mojo supports all of Python’s syntax and semantics. Like Python, Mojo uses line
breaks and indentation to define code blocks (not curly braces), and Mojo supports
all of Python’s control-flow syntax such as if conditions and for loops.
However, Mojo is still a work in progress, so there are some things from Python
that aren’t implemented in Mojo yet. All the missing Python features will arrive in
time, but Mojo already includes many features and capabilities beyond what’s
available in Python.
Variables:
You can declare variables with var to create a mutable value, or with let to create
an immutable value. If you change var to let in the main() function and run it,
you’ll get a compiler error because let makes the value immutable, so you can’t
increment it. And if you delete var completely, you’ll get an error because fn
functions require explicit variable declarations.
Functions:
Mojo functions can be declared with either fn or def. The fn declaration enforces
strongly-typed and memory-safe behaviors, while def provides Python-style dynamic
behaviors.
Mojo supports all of Python’s syntax and semantics. Like Python, Mojo uses line
breaks and indentation to define code blocks (not curly braces), and Mojo supports
all of Python’s control-flow syntax such as if conditions and for loops.
Although types aren’t required for variables declared in the function body, they
are required for arguments and return values for an fn function.
You can also specify argument default values (also known as optional arguments),
and pass values with keyword argument names.
Mojo supports full value semantics and enforces memory safety with a robust value
ownership model (similar to the Rust borrow checker). Essentially, that means Mojo
allows you to share references to values (instead of making a copy every time you
pass a value to a function), but doing so requires that you follow Mojo’s ownership
rules (to ensure memory safety).
In Mojo, if you want to give the function ownership of the value and do not want to
make a copy (which can be an expensive operation for some types), then you can add
the ^ “transfer” operator when you pass a variable to the function. The transfer
operator effectively destroys the local variable name—any attempt to call upon it
later causes a compiler error.
Mojo supports full value semantics and enforces memory safety with a robust value
ownership model (similar to the Rust borrow checker). Essentially, that means Mojo
allows you to share references to values (instead of making a copy every time you
pass a value to a function), but doing so requires that you follow Mojo’s ownership
rules (to ensure memory safety) as described in this section.
Structures:
You can build high-level abstractions for types (or “objects”) in a struct. A
struct in Mojo is similar to a class in Python: they both support methods, fields,
operator overloading, decorators for metaprogramming, etc. However, Mojo structs
are completely static—they are bound at compile-time, so they do not allow dynamic
dispatch or any runtime changes to the structure. (Mojo will also support classes
in the future.)
Python Integration:
Although Mojo is still a work in progress and is not a full superset of Python yet,
we’ve built a mechanism to import Python modules as-is, so you can leverage
existing Python code right away. Under the hood, this mechanism uses the CPython
interpreter to run Python code, and thus it works seamlessly with all Python
modules today.
For example, here’s how you can import and use NumPy (you must have Python numpy
installed):
let np = Python.import_module("numpy")
print(ar)
Note that Mojo is not a feature-complete superset of Python yet. So, you can’t
always copy Python code and run it in Mojo. For more details on our plans, please
refer to the Mojo roadmap and sharp edges.
Take care When you install Mojo, the installer searches your system for a version
of Python to use with Mojo, and adds the path to the modular.cfg config file. If
you change your Python version or switch virtual environments, Mojo will then be
looking at the wrong Python library, which can cause problems such as errors when
you import Python packages (Mojo says only An error occurred in Python—this is a
separate known issue). The current solution is to override Mojo’s path to the
Python library, using the MOJO_PYTHON_LIBRARY environment variable.