Mojo is crazy! Its goal is very ambitious: "As easy to use as Python, but as powerful and fast as Rust."
The newly launched Mojo language is billed as the best of several worlds: the ease of use and clean syntax of Python, and the speed and memory safety of Rust. These are somewhat exaggerated. Since Mojo is still in the early stages of development, it will be a while before users see for themselves how the language meets their needs.
Mojo's creators, a company called Modular, offered an early online runtime: a Jupyter Notebook environment where users could run Mojo code and learn about the language's capabilities and behavior.
Because Mojo hasn't been downloaded as an end user yet, our first focus is on what Mojo looks like as a language. We'll examine how it's similar to Python, how it's different, and what it can offer programmers familiar with Python or other languages.
Mojo: a superset of Python
Mojo can be described as a "superset" of Python. Programs written in Python are valid Mojo programs, although some Python behaviors are not yet implemented. Some examples of Python behavior not currently found in Python include, keyword arguments to functions, the global keyword, and list and dict comprehensions. It is also possible to use the actual Python runtime to process existing Python modules, although this has a performance cost.
When Mojo introduces new syntax, it's used for system-level programming features, mostly manual memory handling. In other words, it is possible to write Python code (or almost exactly similar code) for casual use cases, and then use Mojo for more advanced, performance-intensive programming scenarios. In both cases, existing Python libraries can be leveraged, but at a higher performance cost.
Another big difference between Mojo and Python is that Mojo is not interpreted through runtime like Python. Mojo is compiled ahead of time, using the LLVM toolchain to process native code. For this, the best performance comes from using Mojo-specific features. Python features are likely at the expense of mimicking Python's dynamic behavior, which is inherently slow, or simply achieved by using the Python runtime.
Mojo vs. Python syntax
Many of Mojo's native features serve two purposes. They are either entirely new features that simply don't exist in Python, or extensions of Python's functionality that make it more performant, despite Python's less dynamic nature.
Many of Mojo's native features serve two purposes. They're either completely new features that don't exist in Python at all, or they're extensions of Python's functionality that make it more performant (despite Python's less dynamic nature).
In Python, for example, there is no way to formally declare a variable reference to be immutable at runtime, although type hints and other mechanisms can mimic this at edit time. In Mojo, you can use the keywords let and var to declare Mojo-specific variables, which is very similar to the method used in Rust. The let keyword indicates that the variable is immutable; var indicates that it is mutable. These restrictions are enforced at compile time, so programs that try to mutate immutable references won't even compile.
Mojo's syntax is very similar to Python, but new keywords are provided to enable Mojo-specific features such as mutable behavior.
Mojo also has its own struct keyword, in contrast to Python's class. Classes are just Python classes, with all the dynamic behavior one would expect. However, struct types are more like their C/C++ and Rust counterparts, with a fixed layout determined at compile time but optimized for machine native speed. Another Mojo keyword designed to differentiate Mojo's behavior from Python's is fn. If you use def to define a function, you get a Python function, and all the dynamics associated with those functions. The fn keyword also defines a function, but as a Mojo function. This means that parameters are immutable by default and must be explicitly typed, and all local variables must be declared (among other things).
If you want to know how cool it is to use Mojo, you still need to queue up for a number. Modular provided early access to Mojo through the Modular Playground, a web-based Jupyter Notebook environment that runs on Modular's servers. Currently, Mojo does not have a runtime available for download on its own system. On the plus side, this means you can run Mojo from any computer with a web browser.
The Mojo online environment comes with some notebook examples, as well as detailed inline notes about using Mojo in certain tasks. One example of this is a common programmer presentation drawing the Mandelbrot set algorithm. At first glance, the code is very similar to Python. Even the new Mojo-specific keywords integrate nicely with existing Python syntax, so it's possible to take a closer look at the code and get a general idea of what's going on.
Mojo Playground in action, running the Mandelbrot episode demo. The code used to generate this demo is a mix of native Mojo code and Python libraries, called through Mojo's Python runtime interface.
The notebook demo also illustrates how Mojo code can be accelerated through parallelism, vectorization, and "tiling" (increasing the cache locality of operations). One of the demos is the 128x128 matrix multiplication demo, which is claimed to be 17 times faster than Python (using the Python runtime in the Mojo playground) by simply running it as-is without special modification.
Mojo adds 1866x speedup by adding type annotations, 8500x speedup by adding vectorized operations and 15000x speedup by adding parallelization.
Again, the best way to verify these claims is to have Mojo available locally, but it's worth experimenting with both the Python runtime and the Mojo compiler in the same code to see what happens.
Can Mojo replace Python?
Mojo's first public talk proved that it is a language for data science and machine learning. These two topics make up a large portion of Python's modern use cases, not because Python itself is fast, but because it provides a convenient programming interface to hard-to-use fast things.
Mojo is clearly intended to provide a default express version of this use case where it doesn't have to be done via an external library. Mojo isn't targeting Python's broader set of use cases: web backends, process automation, etc., at least not in the early days. This might come when Mojo is more complete and has better third-party libraries, but it's clearly not a priority.
Even though Mojo is faster by default, it's hard to replace Python's place in machine learning and data science. Python's user community, existing software culture, and convenience all make it a mainstay in these fields. Mojo has to do more than quickly replace Python to do the job. Still, it will be interesting to see how Mojo continues to develop along its path of Python compatibility and fast use cases.