This Week in Mojo 2023-07-07

Playground Update

Full Changelog Hereopen in new window

⭐️ New

  • Tuple expressions now work without parentheses. For example a, b = b, a works as you’d expect in Python.
  • Chained assigments a = b = 42 and the walrus operator some_function(b := 17) are now supported.

🦋 Changed

  • The simd_width and dtype_simd_width functions in the TargetInfo module have been renamed to simdwidthof.

  • The dtype_ prefix has been dropped from alignof, sizeof, and bitwidthof. You can now use these functions with any argument type, including DType.

  • The inf, neginf, nan, isinf, isfinite, and isnan functions were moved from the Numerics module to the Math module, to better align with Python’s library structure.

🛠️ Fixed

Community Content

Mojo Team Answers

Using async fn

async fn and coroutines are a fairly powerful mechanism, and though at this time the only public way we're exposing to invoke them is directly on the same thread, the underlying mechanism is quite powerful and allows running in thread pools, etc. However, for the time being, you'll have to use our wrappers like parallelize, as the underlying functionality isn't otherwise public right now.

ML Compiler optimization projects

We believe that programmability and extensibility is actually the problem to be solved here, not just providing yet-another-special-case-ml-compiler

WASM Target

Our first downloadable deliverable won't support WASM. This is a super interesting target for sure, but we're prioritizing getting things out with a first release, rather than blocking until we solve all the problems 🙂


The weirder thing to me about the rust approach with autoderef is how it handles smart pointers etc. The safe default is to start without autoderef and we can see what that does for ergonomics of the resultant libraries. Any time there has to be a stumper "quiz" about a language feature, it is a sign there is something wrong 😀. In Rust, allowing impl traits on borrows themselves is "interesting". I'm not sure about why that was chosen vs just allowing nominal types to implement traits, but there is probably a good reason.

Init uninitialized objects in fn

This is effectively how the Mojo compiler works internally, and we fudge a couple of things for sake of simplicity of model. For example, the self member of a __del__ destructor is a reference, but it is "magic" in that it is required to be live-in and uninit-out. The self for a memory-only __init__ has the opposite polarity, being uninit on entry and init on exit.

Multiple Moves with ^

The ^ operator kills a lifetime or invokes the stealing moveinit, producing a new owned RValue, so ^^^ is just repeatedly moving 🙂. It is probably a noop in the implementation because we do move elision, I haven't checked though.

Docs Internationalization

We have no plans to translate our content at this time or in the near future. Our products and documentation are still in their infancy and there's a long way to go before curated translation becomes a priority.

String UInt8 implementation

It makes sense to use UInt8 instead of Int8, although users should not be working directly with the bytes within a string 😀. Also, we try to match C semantics here which uses char * for strings. There is a plan to perform optimizations on strings for example small string optimizations, so you should never depend on its layout.