This Week in Mojo 2023-05-12

Mojo Playground Release

The changes from week ending 2023-05-01open in new window and week ending 2023-05-08open in new window have been released to the Mojo Playground with highlights:


The inout keyword replaces & postfix to declare a mutable reference, self& is now inout self:

struct MyVal:
    var val: Int

    fn __init__(inout self, val: Int):
        self.val = val

inout will be familiar to Swift programmers, any mutations in the function will persist out of the function.

See justification for the naming of the keyword hereopen in new window and hereopen in new window. To summarize & is a heavily overloaded character, while inout describes exactly what's happening.

Generic parameters

Generic parameters would previously crash notebooks, this now works:

struct Multi[T: AnyType]:
    var x: T

    fn __init__(inout self, x: T):
        self.x = x

let x = Multi(10)
let y = Multi("string")

Mojo Team Content

Community Content

New Mojo Team Answers

Thread Safety

A borrowed argument is safe to share. It isn't enforced yet, but the model is that a borrowed argument can never alias a mutable reference.

Mojo provides the same model as Rust, which is mutable XOR sharing model. If you have a mutable reference to something, it is known to be unique. You can have many immutable references though.

Actor Model

We only have "ideas" not "plans" here. I'm a fan of actors, having designed/built out a system for swift a few years ago. I think an evolved version of that would compose well and will fit nicely into our system. I think we'll want a Mutex abstraction and classes first though. See Swift Concurrency Manifestoopen in new window and Swift Concurrency Docsopen in new window

You don't need to convince me of the value of actors, Carl Hewitt already did 🙂

Leading underscore _foo for private members

This is a very clear extension we could consider, highly precedented of course. In the immediate future we are focusing on building the core systems programming features in the roadmap. When that is complete, we can consider "general goodness" features like this.

WASM Support

The Mojo stack is perfectly set up to do this. It doesn't use garbage collection, supports very small installed binaries etc. It'll be great, we just need to make a bit more progress 😄

Global Variables

Both def and fn cannot access variables outside their scope because Mojo as a language doesn't have proper global variables yet, this is a known missing feature.

Float Literals

FloatLiteral is backed by Float64 but the Mojo Playground is currently only printing to 6 decimal places. Feature request added hereopen in new window to print all significant digits.

Type Erasure for Python Support

This currently doesn't work in Mojo as it does in Python:

a = 9
a = "Hello"

I agree we need to decide what the model is. This must work, at least in a def, for python compatibility. def currently allows implicit declaration, but infer the type from the first assignment. The above implies that implicitly declared variables in a def should default to having object type (which type erases the concrete type and will allow the above).

I think this is the right/unavoidable thing to do, but I have two concerns:

We don't really have the language features in place to implement object correctly (notably need the basics of classes), so I'd like to avoid switching to this model until we can make it work right.

This push us to define/create the "type erasure of structs to object" model so that user defined struct types can be used here. We may or may not want to do this, it isn't clear to me. There is a lot of precedent in this in the Swift world where Swift classes can be typed erased to AnyObject (aka id in ObjC) and that allow dynamic dispatch in various waysopen in new window

These are super nuanced issues and I'd like to get more experience with the core language before touching into this. There is a big difference between bringing up something simple and building it really great.

Compile to Shared Library

Yes, it can be compiled as a shared library, no problem. We're not prioritizing this right now, but we'll enable this at some point

Mutable Reference vs Mutable Referee

An immutable reference can still have a mutable referee, this is equivalent to the difference between const int* and int* const in C.