Mojo🔥 roadmap & sharp edges
This document captures the broad plan about how we plan to implement things in Mojo, and some early thoughts about key design decisions. This is not a full design spec for any of these features, but it can provide a “big picture” view of what to expect over time. It is also an acknowledgement of major missing components that we plan to add.
Overall priorities
Mojo is still in early development and many language features will arrive in the coming months. We are highly focused on building Mojo the right way (for the long-term), so we want to fully build-out the core Mojo language features before we work on other dependent features and enhancements.
Currently, that means we are focused on the core system programming features that are essential to Mojo’s mission, and as outlined in the following sections of this roadmap.
In the near-term, we will not prioritize “general goodness” work such as:
- Adding syntactic sugar and short-hands for Python.
- Adding features from other languages that are missing from Python (such as public/private declarations).
- Tackling broad Python ecosystem challenges like packaging.
If you have encountered any bugs with current Mojo behavior, please submit an issue on GitHub.
If you have ideas about how to improve the core Mojo features, we prefer that you first look for similar topics or start a new conversation about it in our GitHub Discussions.
We also consider Mojo to be a new member of the Python family, so if you have suggestions to improve the experience with Python, we encourage you to propose these “general goodness” enhancements through the formal PEP process.
Why not add syntactic sugar or other minor new features?
We are frequently asked whether Mojo will add minor features that people love in other languages but that are missing in Python, such as “implicit return” at the end of a function, public/private access control, fixing Python packaging, and various syntactic shorthands. As mentioned above, we are intentionally not adding these kinds of features to Mojo right now. There are three major reasons for this:
First, Mojo is still young: we are still “building a house” by laying down major bricks in the type system and adding system programming features that Python lacks. We know we need to implement support for many existing Python features (compatibility a massive and important goal of Mojo) and this work is not done yet. We have limited engineering bandwidth and want focus on building essential functionality, and we will not debate whether certain syntactic sugar is important or not.
Second, syntactic sugar is like mortar in a building—its best use is to hold the building together by filling in usability gaps. Sugar (and mortar) is problematic to add early into a system: you can run into problems with laying the next bricks because the sugar gets in the way. We have experience building other languages (such as Swift) that added sugar early, which could have been subsumed by more general features if time and care were given to broader evaluation.
Third, the Python community should tackle some of these ideas first. It is important to us that Mojo be a good member of the Python family (a “Python++”), not just a language with Pythonic syntax. As such, we don’t want to needlessly diverge from Python evolution: adding a bunch of features could lead to problems down the road if Python makes incompatible decisions. Such a future would fracture the community which would cause massively more harm than any minor language feature could offset.
For all these reasons, “nice to have” syntactic sugar is not a priority, and we will quickly close such proposals to avoid cluttering the issue tracker. If you’d like to propose a “general goodness” syntactic feature, please do so with the existing Python PEP process. If/when Python adopts a feature, Mojo will also add it, because Mojo’s goal is to be a superset. We are happy with this approach because the Python community is better equipped to evaluate these features, they have mature code bases to evaluate them with, and they have processes and infrastructure for making structured language evolution features.
Mojo SDK known issues
The Mojo SDK is still in early development and currently only available for Ubuntu Linux and macOS (Apple silicon) systems. Here are some of the notable issues that we plan to fix:
Missing native support for Windows, Intel Macs, and Linux distributions other than Ubuntu. Currently, we support Ubuntu systems with x86-64 processors only. Support for more Linux distributions (including Debian and RHEL) and Windows is in progress.
Python interoperability might fail when running a compiled Mojo program, with the message
Unable to locate a suitable libpython, please set MOJO_PYTHON_LIBRARY
. This is because we currently do not embed the Python version into the Mojo binary. For details and the workaround, see issue #551.Mojo programs that import NumPy might fail with the following error:
Importing the numpy C-extensions failed. This error can happen for many reasons, often due to issues with your setup or how NumPy was installed.
This may occur because the version of NumPy doesn’t match the Python interpreter Mojo is using. As a workaround, follow the instructions in issue #1085 to install a Python virtual environment using Conda. This can solve many issues with Python interoperability.
Modular CLI install might fail and require
modular clean
before you re-install.If it asks you to perform auth, run
modular auth <MODULAR_AUTH>
and use theMODULAR_AUTH
value shown for thecurl
command on the download page.modular install mojo
is slow and might appear unresponsive (as the installer is downloading packages in the background). We will add a progress bar in a future release.If you attempt to uninstall Mojo with
modular uninstall
, your subsequent attempt to install Mojo might fail with an HTTP 500 error code. If so, runmodular clean
and try again.Mojo REPL might hang (become unresponsive for more than 10 seconds) when interpreting an expression if your system has 4 GiB or less RAM. If you encounter this issue, please report it with your system specs.
Additionally, we’re aware of some issues that we might not be able to solve, but we mention them here with some more information:
When installing Mojo, if you receive the error,
failed to reach URL https://cas.modular.com
, it could be because your network connection is behind a firewall. Try updating your firewall settings to allow access to these end points:https://packages.modular.com
andhttps://cas.modular.com
. Then retry withmodular clean
andmodular install mojo
.When installing Mojo, if you receive the error,
gpg: no valid OpenGPG data found
, this is likely because you are located outside our supported geographies. Due to US export control restrictions, we are unable to provide access to Mojo to users situated in specific countries.If using Windows Subsystem for Linux (WSL), you might face issues with WSL 1. We recommend you upgrade to WSL 2. To check the version, run
wsl -l -v
. If you’re running WSL 1, refer to the WSL upgrade instructions.When installing on macOS (Apple silicon), the Modular CLI install might fail with the message:
modular: The arm64 architecture is required for this software.
This occurs because Apple’s Rosetta x86 emulation is active. Check the following:
Right click on the terminal application you use (for example,
Terminal.app
), click Get Info, and make sure the Open in Rosetta checkbox is not selected.Run the following command:
brew config | grep Rosetta
If the output shows
Rosetta 2: True
, the x86 version of Homebrew is installed. Uninstall and reinstall Homebrew before retrying the Modular installation.Note: Before uninstalling Homebrew, verify that you don’t have other projects specifically depending on the x86 version of Homebrew.
You can see other reported issues on GitHub.
Small independent features
There are a number of features that are missing that are important to round out the language fully, but which don’t depend strongly on other features. These include things like:
- Improved package management support.
- Many standard library features, including canonical arrays and dictionary types, copy-on-write data structures, etc.
- Support for “top level code” at file scope.
- Algebraic data types like
enum
in Swift/Rust, and pattern matching. - Many standard library types, including
Optional[T]
andResult[T, Error]
types when we have algebraic datatypes and basic traits. - Support for keyword-only arguments and variadic keyword arguments (
**kwargs
). - Support for passing keyword arguments when calling Python functions.
Ownership and Lifetimes
The ownership system is partially implemented, and is expected to get built out in the next couple of months. The basic support for ownership includes features like:
- Capture declarations in closures.
- Borrow checker: complain about invalid mutable references.
The next step in this is to bring proper lifetime support in. This will add the ability to return references and store references in structures safely. In the immediate future, one can use the unsafe Pointer
struct to do this like in C++.
Traits support
As of v0.6.0 Mojo has basic support for traits. Traits allow you to specify a set of requirements for types to implement. Types can implement those requirements to conform to the trait. Traits allow you to write generic functions and generic containers, which can work with any type that conforms to a given trait, instead of being hard-coded to work with a specific type.
Currently, the only kind of requirements supported by traits are required method signatures. The trait can’t provide a default implementation for its required methods, so each conforming type must implement all of the required methods.
A number of built-in traits are already implemented in the standard library.
We plan to expand traits support in future releases. Planned features include:
More traits built in to the standard library, and expanded use of traits throughout the standard library.
Support for default implementations of required methods.
Support for a feature like Swift’s extensions, allowing you to add a trait to a preexisting type.
Classes
Mojo still doesn’t support classes, the primary thing Python programmers use pervasively! This isn’t because we hate dynamism - quite the opposite. It is because we need to get the core language semantics nailed down before adding them. We expect to provide full support for all the dynamic features in Python classes, and want the right framework to hang that off of.
When we get here, we will discuss what the right default is: for example, is full Python hash-table dynamism the default? Or do we use a more efficient model by default (e.g. vtable-based dispatch and explicitly declared stored properties) and allow opt’ing into dynamism with a @dynamic
decorator on the class. The latter approach worked well for Swift (its @objc
attribute), but we’ll have to prototype to better understand the tradeoffs.
C/C++ Interop
Integration to transparently import Clang C/C++ modules. Mojo’s type system and C++’s are pretty compatible, so we should be able to have something pretty nice here. Mojo can leverage Clang to transparently generate a foreign function interface between C/C++ and Mojo, with the ability to directly import functions:
from "math.h" import cos
print(cos(0))
Full MLIR decorator reflection
All decorators in Mojo have hard-coded behavior in the parser. In time, we will move these decorators to being compile-time metaprograms that use MLIR integration. This may depend on C++ interop for talking to MLIR. This completely opens up the compiler to programmers. Static decorators are functions executed at compile-time with the capability to inspect and modify the IR of functions and types.
fn value(t: TypeSpec):
= # synthesize dunder copyinit automatically
t.__copyinit__
@value
struct TrivialType: pass
fn full_unroll(loop: mlir.Operation):
# unrolling of structured loop
fn main():
@full_unroll
for i in range(10):
print(i)