Skip to main content
Version: 1.0

v0.4.0 (2023-10-05)

⭐️ New

  • Mojo now supports default parameter values. For example:

    fn foo[a: Int = 3, msg: StringLiteral = "woof"]():
    print(msg, a)

    fn main():
    foo() # prints 'woof 3'
    foo[5]() # prints 'woof 5'
    foo[7, "meow"]() # prints 'meow 7'

    Inferred parameter values take precedence over defaults:

    @value
    struct Bar[v: Int]:
    pass

    fn foo[a: Int = 42, msg: StringLiteral = "quack"](bar: Bar[a]):
    print(msg, a)

    fn main():
    foo(Bar[9]()) # prints 'quack 9'

    Structs also support default parameters:

    @value
    struct DefaultParams[msg: StringLiteral = "woof"]:
    alias message = msg

    fn main():
    print(DefaultParams[]().message) # prints 'woof'
    print(DefaultParams["meow"]().message) # prints 'meow'
  • The new file module adds basic file I/O support. You can now write:

    var f = open("my_file.txt", "r")
    print(f.read())
    f.close()

    or

    with open("my_file.txt", "r") as f:
    print(f.read())
  • Mojo now allows context managers to support an __enter__ method without implementing support for an __exit__ method, enabling idioms like this:

    # This context manager consumes itself and returns it as the value.
    fn __enter__(owned self) -> Self:
    return self^

    Here Mojo cannot invoke a noop __exit__ method because the context manager is consumed by the __enter__ method. This can be used for types (like file descriptors) that are traditionally used with with statements, even though Mojo's guaranteed early destruction doesn't require that.

  • A very basic version of pathlib has been implemented in Mojo. The module will be improved to achieve functional parity with Python in the next few releases.

  • The memory.unsafe module now contains a bitcast function. This is a low-level operation that enables bitcasting between pointers and scalars.

  • The input parameters of a parametric type can now be directly accessed as attribute references on the type or variables of the type. For example:

    @value
    struct Thing[param: Int]:
    pass

    fn main():
    print(Thing[2].param) # prints '2'
    let x = Thing[9]()
    print(x.param) # prints '9'

    Input parameters on values can even be accessed in parameter contexts. For example:

    fn foo[value: Int]():
    print(value)

    let y = Thing[12]()
    alias constant = y.param + 4
    foo[constant]() # prints '16'
  • The Mojo REPL now supports code completion. Press Tab while typing to query potential completion results.

  • Error messages from Python are now exposed in Mojo. For example the following should print No module named 'my_uninstalled_module':

    fn main():
    try:
    let my_module = Python.import_module("my_uninstalled_module")
    except e:
    print(e)
  • Error messages can now store dynamic messages. For example, the following should print "Failed on: Hello"

    fn foo(x: String) raises:
    raise Error("Failed on: " + x)

    fn main():
    try:
    foo("Hello")
    except e:
    print(e)

🦋 Changed

  • We have improved and simplified the parallelize function. The function now elides some overhead by caching the Mojo parallel runtime.

  • The Mojo REPL and Jupyter environments no longer implicitly expose Python, PythonObject, or Pointer. These symbols must now be imported explicitly, for example:

    from python import Python
    from python.object import PythonObject
    from memory.unsafe import Pointer
  • The syntax for specifying attributes with the __mlir_op prefix have changed to mimic Python's keyword argument passing syntax. That is, = should be used instead of :, e.g.:

    # Old syntax, now fails.
    __mlir_op.`index.bool.constant`[value : __mlir_attr.false]()
    # New syntax.
    __mlir_op.`index.bool.constant`[value=__mlir_attr.false]()
  • You can now print the Error object directly. The message() method has been removed.

🛠️ Fixed

  • #794 - Parser crash when using the in operator.
  • #936 - The Int constructor now accepts other Int instances.
  • #921 - Better error message when running mojo on a module with no main function.
  • #556 - UInt64s are now printed correctly.
  • #804 - Emit error instead of crashing when passing variadic arguments of unsupported types.
  • #833 - Parser crash when assigning module value.
  • #752 - Parser crash when calling async def.
  • #711 - The overload resolution logic now correctly prioritizes instance methods over static methods (if candidates are an equally good match otherwise), and no longer crashed if a static method has a Self type as its first argument.
  • #859 - Fix confusing error and documentation of the rebind builtin.
  • #753 - Direct use of LLVM dialect produces strange errors in the compiler.
  • #926 - Fixes an issue that occurred when a function with a return type of StringRef raised an error. When the function raised an error, it incorrectly returned the string value of that error.
  • #536 - Report More information on python exception.