Did Modular just reinvent Julia?

This specific comment is pretty much exactly what Chris lattner said in regards to both Swift and Julia - “the problem is they’re not python”


Python is a mass market retail product. It is hard to displace it with just better performance. Over 90% of the customer base probably does not feel constrained by GIL or for loop speed with the type of hardware they get to use now. The 10% that care is a different segment altogether.

May be Julia will always be a niche product. But it can try to be a very good niche product.


This is a long time. 40 years ago people claimed: “I don’t know what the language of the future will look like, but I know it will be called Fortran.” —Tony Hoare, winner of the 1980 Turing Award, in 1982.


I think the thorough research of the inquisitive people who posted here shows, Modular invented a new way of extracting money from naive investors. Sure, Mojo will run Python, but Python programmers will have to be prepared for a lot of pain. The complexity that is hiding at the moment in Mojo will be substantial. It will be a completely different language from Python. Buyer beware.


I can’t say if there aren’t any naive investors, and there are certainly people even on this very thread who jumped into speculation without reading the Mojo docs to see the syntax. But I don’t think it’s fair to suggest Modular is intentionally targeting them. They essentially promised inherent CPython integration, even if the idiomatic language ends up 90% Mojothon, and that’s how anybody who paid attention would take it. If people expect to write CPython to run optimally, that’s on them. We’re very used to people coming into Julia thinking that, too, because they read “walks like Python runs like C” somewhere instead of a representative code sample.


Mojo is a language still in development with a lot of details unspecified, as yet unreleased outside the “playground”.

You may have your own guess on what it is going to end up like, but those who disagree with you or simply admit that we cannot know at this point may have based their opinion on as much fact as you did.

Developing a new language is a very complex process, with the devil in the details. A lot of questions only surface once programmers start using the language in their daily work. Until that happens, and we see how Mojo evolves, “paying attention” may tell you about the plans, but not the outcome.

You may want to look at the case of recent languages which were designed pretty much in the open, eg Julia. The syntax had relatively few changes since 2012, but the core language, the standard libraries, compiler internals and the tooling evolved in ways that would have been hard to foresee then. Most importantly, compilation itself turned out to be a performance issue as people started using Julia for complex tasks that involve a lot of types and has been addressed in a lot of incremental steps.


That all is true, there’s a lot about Mojo we can’t possibly know, but I was referring to people who thought Mojo was like PyPy trying to optimize regular CPython syntax, that’s what the rest of my comment was about. The Mojo docs, which could change a lot, already suggests they’ll introduce a lot of unPythonic syntax (struct, fn, let, var). If they backtrack to only CPython syntax, I’d be surprised.


I don’t think it was clear at all; the Modular team is constantly eliding the difference between “we want a language with Python interop” (trivial, but every major language has Python interop?) and “we plan to make Python fast” (impossible without breaking the entire Python ecosystem, thanks to the GIL, reference counting, the C interface, and a dozen other examples of CPython’s internals leaking all over).

From what I can tell they’re blowing a couple million dollars on a new language they just don’t need. MLIR is designed to be easy to retrofit (Julia IR could probably be made into an MLIR dialect with a bit of elbow grease, and in fact, this has been done before). Julia already has the level of Python interop that Mojo is promising. And PythonSyntax.jl already exists, for crying out loud; you don’t need to write a whole new compiler to add semantic whitespace.

That’s not to say Mojo doesn’t have new innovations or features. Mojo isn’t a carbon copy of Julia. But they’re duplicating lots of work, especially in the ecosystem. Bringing the Mojo ecosystem up to par with Julia’s will take years, at which point I don’t think programming languages will even be all that useful a concept. The Mojo devs seem convinced that “just borrow Python’s ecosystem” is a good enough answer–but if Python’s ecosystem was already good enough, why’d you leave it in the first place?


They address all these issues in the docs. If you look at their syntax, their interop is a lot smoother than third party libraries, there are no interop types to interact with separate types in separate languages. This isn’t inherently superior or inferior to typical language interop, it just has different challenges. One example, Mojo still has to figure out how to make Python classes work, but PythonCall.jl already can make Python classes wrapping Julia functions.

They acknowledge this directly, I can’t really say it in a better way than they have. This is their remark on other Python supersets like Cython and Pyrex:

These Python supersets are great for some kinds of applications, and they’ve been applied to great effect by some popular Python libraries. However, they don’t solve Python’s two-world problem and because they rely on CPython for their core semantics, they can’t work without it, whereas Mojo uses CPython only when necessary to provide compatibility with existing Python code. Pure Mojo code does not use any pre-existing runtime or compiler technologies, it instead uses an MLIR-based infrastructure to enable high-performance execution on a wide range of hardware.

If inherent interop is a feature, then the goal isn’t to catch up to Julia’s ecosystem, it’s to use Python’s ecosystem as is. If languages not mattering is a reference to AI, it’s funnily enough one of the major reasons for Mojo’s development. It’s not intended to be fast Python, it’s intended for:

When we started Modular, we had no intention of building a new programming language. But as we were building our platform with the intent to unify the world’s ML/AI infrastructure, we realized that programming across the entire stack was too complicated. Plus, we were writing a lot of MLIR by hand and not having a good time. What we wanted was an innovative and scalable programming model that could target accelerators and other heterogeneous systems that are pervasive in the AI field. This meant a programming language with powerful compile-time metaprogramming, integration of adaptive compilation techniques, caching throughout the compilation flow, and other features that are not supported by existing languages.


IMO this thread should just be closed. There’s tons of messages but not much to base them on, seeing as the product is still unreleased and it’s not even clear what it’s going to be like. For example, is Mojo going to be open-sourced at all? We can’t know. In the FAQ they say they “don’t have a plan for open-sourcing yet”.


Discussion is civil.
It’s in Offtopic.
It’s mainly speculative.

No reason to close. Just don’t read if you are not interested.


Mostly civil anyway. It didn’t surprise me that the few comments that got heated either understated or overstated Mojo’s documented goals very confidently; the patience that goes into forming opinions is the same patience that goes into reading other people’s.


I think the thread is doing fine. Discussion is civil and I have learnt a lot.

1 Like

Then, again, what’s the point, and why leave Python in the first place? You can either:

  1. Use the Python ecosystem, in which case there’s no advantage over any other language with Python interop. You get no performance improvements from Mojo, unless you learn a completely new language (Mojo) and rewrite all your code in it.
  2. Build a new ecosystem. In that case, you have to… build a new ecosystem. Which is hard and takes a very long time.

I’d like it if the Modular team stopped consistently obfuscating about the difference between these two. Just come out and say “Yeah, all your code is going to be just as slow as ever, unless you rewrite all of it in this new language we developed.”


I don’t agree with this. If Mojo does what it says it’s going to do, its Python interop is going to be much smoother than Julia’s.

nothing against PythonCall.jl, it’s a perfectly useful package, but it’s my understanding that the intention of Mojo is to allow Python code to be written directly in Mojo, pass around Python objects natively, etc… Julia does not do this.

1 Like

Chris is pretty much answering the main question on this thread: the main difference is that Julia is not Python, and with Mojo they seem to have a market-first approach where they are trying to build a product for Python users. Python is huge and it has become a big market, so this approach makes sense from a business point of view.

Julia’s approach is different. In my opinion, Julia is way more innovative than Mojo. Julia code will be probably more generic and more concise that what Mojo could ever be (right now, mojo doesn’t even support polymorphism).

Julia also manages to be fast and provide automatic memory managment at the same time, by leveraging a GC, while Mojo will rely on this borrow-checker feature, which can make coding substantially harder. While having a GC is sometimes a problem for writing high-performance code, there are already approaches that require minimal overhead like pre-allocating outside of hot loops, StaticArrays, and so on and so forth.

And of course, as GPU memory works in a completely different way than CPU memory, GPUCompiler usually overhauls the GC and memory gets managed in a different way. So, maybe, the Mojo no-GC approach seems to be sacrificing some of the flexibility of the CPU in order to be more easily run in heterogeneous hardware environments, which is fraknkly an interesting use case, but it could also turn out to be quite a niche use case in the end (although a lucrative one).

I know any opinions at this point are speculative, but my impression is that Mojo will be harder to use, more verbose, and less powerful than Julia, and the only positive trade-off is that it will integrate more easily with Python (albeit, with some more work on static compilation, Julia could also integrate very easily with Python – or any other language for that matter). Maybe thanks to this no-GC approach Mojo will run more easily in heterogeneous hardware environments. But we also don’t know how Mojo is going to be monetized, and I’m betting that that this last feature is going to be behind some sort of paywal.

To me, Julia is beyond the tipping point where adding whatever feature is actually missing would be substantially simpler than adding all the features it already has to a different language.


This is probably a more important reason for their introduction of struct/fn than improved CPU performance. Base Python makes it very difficult to avoid heap allocations, though its reference counting does help by not needing the GC to free some types, and hooking a compiler to a subset of Python and an unorthodox library would be much more restrictive and perhaps not much easier to learn compared to a new half-dynamic-half-static language that falls back to the CPython interpreter for smooth Python integration.

I’m not exactly clear on whether they’d be avoiding heap allocations as strictly as we do when the GC is not an option, they do have borrow checking.


Does anyone know if they allow aliasing mutable objects? My understanding was that Rust specifically disallowed aliasing of mutable objects to make borrow checking tractable, so I’d be interested to know if Mojo has similar restrictions, or if they anticipate that they’d run into trouble due to aliasing concerns.


This is what the docs say about borrow checking in fn now:

  1. The Mojo compiler implements a borrow checker (similar to Rust) that prevents code from dynamically forming mutable references to a value when there are immutable references outstanding, and it prevents multiple mutable references to the same value. You are allowed to have multiple borrows (as the call to use_something_big does above) but you cannot pass something by mutable reference and borrow at the same time. (TODO: Not currently enabled).

fn arguments are all immutable references (borrowed keyword) by default, but there are other keywords to change argument behavior in either fn or def.

It’s extra complicated because not only does Mojo have a def like Python, its arguments use value semantics by default and refers to Python’s def as using reference semantics. That last part is more or less true because of how all objects are reference types, but it’s definitely not coming from a Pythonic (and Julian) perspective of bindings and instance mutability. Due to the changes, Mojo’s def is described as a sugaring of fn; value semantics is considered equivalent to making local mutable copies of immutable references. They’re not just adding syntax to unchanged Python, it all works quite differently. I’m not exactly clear on whether the object mutability model is replaced or somehow combined with this C/Rust-like variable model; for example, what would def incrementfirst(arr): arr[0] += 1 do to the input sequence? I imagine they’ll make sure this doesn’t change the behavior of existing Python code, otherwise it’ll defeat the purpose of seamless integration.

For an accurate understanding, it’s worth a read. Links have been iffy on whether they take you to the exact section so it’s “Argument passing control and memory ownership”.


They are also saying that they’re not making it as hard as Rust