Skip to main content

July 2023

2023-07-26

⭐️ New

  • Types that define both __getitem__ and __setitem__ (i.e. where sub-scripting instances creates computed LValues) can now be indexed in parameter expressions.

  • Unroll decorator for loops with constant bounds and steps:

    • @unroll: Fully unroll a loop.
    • @unroll(n): Unroll a loop by factor of n, where n is a positive integer.
    • Unroll decorator requires loop bounds and iteration step to be compiler time constant value, otherwise unrolling will fail with compilation error. This also doesn't make loop induction variable a parameter.
    # Fully unroll the loop.
    @unroll
    for i in range(5):
        print(i)
    
    # Unroll the loop by a factor of 4 (with remainder iterations of 2).
    @unroll(4)
    for i in range(10):
        print(i)
  • The Mojo REPL now prints the values of variables defined in the REPL. There is full support for scalars and structs. Non-scalar SIMD vectors are not supported at this time.

🛠️ Fixed

  • Issue #437 - Range can now be instantiated with a PythonObject.

  • Issue #288 - Python strings can now be safely copied.

2023-07-20

⭐️ New

  • Mojo now includes a Limits module, which contains functions to get the max and min values representable by a type, as requested in Issue #51. The following functions moved from Math to Limits: inf(), neginf(), isinf(), isfinite().

  • Mojo decorators are now distinguished between "signature" and "body" decorators and are ordered. Signature decorators, like @register_passable and @parameter, modify the type of declaration before the body is parsed. Body decorators, like @value, modify the body of declaration after it is fully parsed. Due to ordering, a signature decorator cannot be applied after a body decorator. That means the following is now invalid:

    @register_passable # error: cannot apply signature decorator after a body one!
    @value
    struct Foo:
        pass
  • Global variables can now be exported in Mojo compiled archives, using the @export decorator. Exported global variables are public symbols in compiled archives and use the variable name as its linkage name, by default. A custom linkage name can be specified with @export("new_name"). This does not affect variable names in Mojo code.

  • Mojo now supports packages! A Mojo package is defined by placing an __init__.mojo or __init__.🔥 within a directory. Other files in the same directory form modules within the package (this works exactly like it does in Python). Example:

    main.🔥
    my_package/
      __init__.🔥
      module.🔥
      my_other_package/
        __init__.🔥
        stuff.🔥
    # main.🔥
    from my_package.module import some_function
    from my_package.my_other_package.stuff import SomeType
    
    fn main():
        var x: SomeType = some_function()
  • Mojo now supports direct module and package imports! Modules and packages can be imported and bound to names. Module and package elements, like functions, types, global variables, and other modules, can be accessed using attribute references, like my_module.foo. Note that modules lack runtime representations, meaning module references cannot be instantiated.

    import builtin.io as io
    import SIMD
    
    io.print("hello world")
    var x: SIMD.Float32 = 1.2

🦋 Changed

  • Reverted the feature from 2023-02-13 that allowed unqualified struct members. Use the Self keyword to conveniently access struct members with bound parameters instead. This was required to fix Issue #260.

  • Updated the RayTracing notebook: added step 5 to create specular lighting for more realistic images and step 6 to add a background image.

🛠️ Fixed

  • Issue #260 - Definitions inside structs no longer shadow definitions outside of struct definitions.

2023-07-12

⭐️ New

  • Mojo now has support for global variables! This enables var and let declaration at the top-level scope in Mojo files. Global variable initializers are run when code modules are loaded by the platform according to the order of dependencies between global variables, and their destructors are called in the reverse order.

  • The Mojo programming manual is now written as a Jupyter notebook, and available in its entirety in the Mojo Playground (programming-manual.ipynb). (Previously, HelloMojo.ipynb included most of the same material, but it was not up-to-date.)

  • As a result, we've also re-written HelloMojo.ipynb to be much shorter and provide a more gentle first-user experience.

  • Coroutine module documentation is now available. Coroutines form the basis of Mojo's support for asynchronous execution. Calls to async fns can be stored into a Coroutine, from which they can be resumed, awaited upon, and have their results retrieved upon completion.

🦋 Changed

  • simd_bit_width in the TargetInfo module has been renamed to simdbitwidth to better align with simdwidthof, bitwidthof, etc.

🛠️ Fixed

  • The walrus operator now works in if/while statements without parentheses, e.g. if x := function():.

  • Issue #428 - The FloatLiteral and SIMD types now support conversion to Int via the to_int or __int__ method calls. The behavior matches that of Python, which rounds towards zero.

2023-07-05

⭐️ New

  • Tuple expressions now work without parentheses. For example, a, b = b, a works as you'd expect in Python.
  • Chained assignments (e.g. a = b = 42) and the walrus operator (e.g. 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 (e.g. alignof) 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

  • Issue #253 - Issue when accessing a struct member alias without providing parameters.

  • Issue #404 - The docs now use snake_case for variable names, which more closely conforms to Python's style.

  • Issue #379 - Tuple limitations have been addressed and multiple return values are now supported, even without parentheses.

  • Issue #347 - Tuples no longer require parentheses.

  • Issue #320 - Python objects are now traversable via for loops.

Was this page helpful?