I’m currently in a tough situation because I believe Mojo is the future and I have to start writing a library right now that might be ready in two years from now.
The thing is, that piece of software is supposed to replace part of the ROS 2 stack so it needs to be compatible with as many architectures AND languages as possible (Rust has ffi for practicaly anything).
I don’t know anything about Rust right now, but on paper it fits the bill perfectly while Mojo is still a big bet on the following points:
When will we be able to create a dynamic lib with Mojo so that we can call Mojo code from C/C++?
Will it be easy to write interfaces for languages that are not Mojo (so that the library can be imported and used in C/C++/Rust/Zig etc…)
Will the compiler ever support fancy architectures found in robot MCUs (like Risc-V/MIPS etc…). We will prob first need to get the compiler open sourced, which is also an unknown.
When will the promise of C/C++ interopt materialize? In other words, this:
from "math.h" import cos
print(cos(0))
Is Mojo concurrency model gonna be as mature as the one found in Rust? (outside GPU programming). Currently async is mentionned under the “Sharp edges” part of the documentation for some reason.
The biggest immediate roadblock that I have with Mojo is its inability to compile to a dynamic library and be used by other languages.
I’m looking for guidance on this forum on the following question: Would someone in my position bet on Mojo for a future (2 years) where all those features become available?
Basing this mostly off of just this statement - Rust.
For Mojo to work for what you are describing a lot of things would have to go right (and hopefully they all will!). But Rust will work today, and two years from now.
Was there some feature Mojo currently has that would be an asset for your project compared to Rust?
The obvious choice is definitely Rust, and no, Mojo doesn’t actually have an edge compared to Rust when it comes to this project as of today, excepted for its interoperability with Python.
I guess I have my answer, somehow I was trying to convince myself that when Mojo get to the level of Rust (interoperability-wise) then I’d probably shift my code over because of its interoperability with Python (Rust uses ffi) which is gonna be crucial since that lib will also have some AI capabilities.
I guess I just need to let Mojo cook a little more, there are too many unknowns at the moment.
Thanks!
I’d say that, for robotics which are more likely to need safety critical certs, Rust is the right choice. Mojo is very far away from getting any kind of automotive cert, which I see a lot of robots drawing from. Mojo can speak C ABI, so that’s enough to talk to most languages, but it doesn’t speak it very well. There is some work on a bindgen equivalent for Mojo, but it’s going to be primitive for a while.
The MIPS ISA is functionally dead at this point. MIPS the company makes RISC-V CPU IP now. I would expect a lot of stuff to transition to RISC-V in the coming years, so supporting MIPS is probably not worth the headache for Mojo.
Mojo can absolutely compile a dynamic library with a C ABI and be used by other languages, you just need to bring the Mojo runtime along for the ride. Look at the --emit options for mojo build.
How so? Is there a page that lists the limitations?
That’s fantastic news! Is there an example page that shows how it’s done? I wonder about the “bringing the mojo runtime” along with the dynamic lib. Thanks!
Right, MIPS wasn’t a good example. The NVIDIA Jetson hardware (including upcoming Jetson Thor) would be a better example of hardware that will need to be supported (I guess that’s already the case with aarch64 support but GPU programming is still Tier 3 on those platforms).
I personally got mojo running GREAT on Pi zero 2W (512mb ram),
because that GPIO-supported very affordable pi actually run Linux
(Mojo’s ASAP is excellent for small ram, so keep that thought)
I’d like to suggest that if you use Rust,
just side-develop the equivalent in Mojo if time available,
and so you’ll be able to switch faster when needed.
This will also keep your mojo skills up-to-date
One big part of the mojo idea is to be able to bring it gradually to an existing project,
so you’ll probably be able to offload part of the whole project to mojo as needed.
The limitations are that you need to write the bindings yourself (for both directions) and you need to know what Mojo types map to what types in your C ABI.
You can bring the Mojo runtime by requiring users to supply the correct mojo runtime version to the linker. Right now you can’t distribute those files, but that will likely change once Modular opens up the compiler.
Ok, it pains me to do this in Rust but Mojo is just not there yet. I’ll however make my lib similar to ROS where messages are passed in a pub/sub manner so maybe one day, in a year or two, I’ll be able to fully write a node in Mojo without relying on clever tricks to make it work.
Caveat - I haven’t used Mojo’s Python bindings yet.
Rust has Introduction - PyO3 user guide, which is fantastic. From what I’ve been watching go by in nightly, Mojo bindings for Python look a lot like it. The eventual edge for Mojo on the python bindings front is that it ships with the Mojo stdlib, and, hopefully, packaging is nice and easy for adding Mojo in-project to Python projects.
So even on the bindings front, right now Rust is has the more fully featured option.
On the plus side, if you care careful about how you structure that bindings API, you can do what @rd4com suggests and develop in Mojo on the side and then have a second package that slowly eats the Rust version.
Thanks for this reply. I’m currently learning Rust after this discussion (and many other in other places). Gotta say, I don’t feel like dealing with the borrow checker was as painful with Mojo as it is with Rust. Hopefully my Rust knowledge will flow into Mojo more easily when I use this language someday.
I personally don’t think this is a viable path. Picking a language for a project is really a one way door. That being said, my goal is to reimplement/simplify ROS 2 core but I’m gonna borrow the same concepts, notably “Nodes” (pieces of software that communicate in a pub/sub fashion) so nothing will prevent me from coming up with a node in the future that is fully written in Mojo (as long as I can write an interface for Zenoh for Mojo, or borrow the one that is already written for Python but it feels “patchy”). By the time I get to this part, Mojo might have reached 1.0.
I’m hopeful that Mojo becomes this “do it all” language that does everything Rust does but with a lower learning curve. Going with Mojo at the moment however, is not a wise choice considering the language specifications are still changing (like the recent deprecation of owned ) and the team seem to put the emphasis on GPU programming rather than general purpose functionality such as interoperability (even full compatibility with Python is not there yet as seen on an issue I opened on the Modular repo here).
Time will tell, I’m very hopeful for Mojo and I’ll keep an eye on it, but starting a new project is already a big bet, starting a new project with a language that has yet to implement the basic functionalities for your success is an eˣ bet lol.