I suppose for me it is/was not so much one thing or another, but rather a bit of everything. I’ll admit, I started learning expecting it to be quite similar to Python, but as Owen has pointed out, it’s closer to C++/Rust/systems programming languages but “wears a snakeskin jacket”. So, perhaps for newcomers it’s better to approach it as a new language rather than a “superset of Python”. There are a number of (growing) discrepancies that you need to know about via docs/examples/etc. These range from fairly obvious to more obscure if you don’t keep up with things (ex: List not being able to have mixed types, setting a List to a new variable always performing a deep copy, upcoming changes to Int making division return Int instead of Float). Beyond the slight discrepancies with Python, newcomers from Python really need to get a grasp of a whole slew of new programming paradigms just to be able to code up more than a few lines:
- The strict type system and generics
- Traits and how they interact with the strict type system
- Origins/lifetimes and how they interact with the strict type system
comptime values and parameters, and how they interact with and enhance/limit runtime calculations
This is before getting into features that either are very new or not yet fully implemented such as linear types, how concurrency is handled, etc. The Game of Life intro was nice, but didn’t really introduce any of these concepts, at least not at the time I went through it.
And as far as intros, I’m probably the odd one out on this one, but I didn’t find the GPU programming tutorial as helpful as others made it seem, certainly not the first 10 or so that felt like “can you use 2D numpy indexes and understand what the corresponding index would be if you called .flatten().” I was hoping for more emphasis on/explanation of other fundamental Mojo/Max things like “what’s this whole stack_allocation thing”, “why is there dtype, DType, and then Scalar[dtype] and what’s the difference”, “what if I want some of these comptime values to be runtime instead”, “why are we using UnsafePointer here and not Pointer”, "why are we using MutAnyOrigin, “why can’t we call kernels within other kernels like normal functions”, etc. There are a couple of custom ops examples near the end for using pytorch tensors that are close, but I really was expecting to see a “here’s how you put your numpy array through a GPU kernel”, “here’s the ‘equivalent’ array container/data structure that it’s converted to in Mojo”, and “here’s how to manipulate that data structure”.
Finally, on the “playing around” and debugging side of things, this is where there I probably had the most frustration. I use/used the Mojo extension for VS Code which seems to constantly have issues (though has greatly improved) with crashing and/or giving completely wrong errors. Many of the errors that I come across are relatively vague, cryptic, or confusing for new learners. It takes a bit to get used to Mojo’s ASAP destruction, so I tried to opt for printing out values, but the majority of which don’t conform to the Writable trait so it’s been incredibly frustrating trying to just prove to myself that the things were what I thought they were, see what methods/attributes are available to a struct (without just opening a separate window to the API docs), etc. This was a bit of a shock coming from Python where you can print almost everything as a “poor man’s debugger”. This combined with the lack of a native plotting/graphing library has made “sandbox learning” quite difficult.