An Intro to Mojo ๐Ÿ”ฅ

Mojo ๐Ÿ”ฅ is an emerging language that aims to combine the simplicity of Python with the speed of C.

ยท

3 min read

Why use Mojo?

The execution speed / speed-up speaks for itself.

Getting Started

For setting the environment, you can either go to the Modular or go to Playground to run mojo in the cloud.

Similarity to python

Mojo utilizes Python's syntax and semantics, such as indentation instead of curly braces. It also fully supports Python's control-flow syntax, including if conditions and for loops. Below, we will explore how Mojo offers a few other functionalities.

Main Function

Similar to many other programming languages, Mojo has a main function as the entry point to the program.

fn main():
    print("Hello world")

Variables

There are two types of variables in mojo

  1. Let - These are immutable so the value can't be changed

  2. Var - These are mutable type

In mojo you can assign type to the variable, if you do not assign any mojo will automatically assign the type.

let x: Int = 1

Functions

A function declaration can be of 2 types: one is the same as Python function declaration def and works similarly to Python.

Another type of declaration is fn enforces strongly-typed and memory-safe behavior. Strong Typing: This means that variables and data types must be explicitly defined Memory Safety: It ensures that your program doesn't access or modify memory locations it shouldn't ( prevents buffer overflow)

Another thing to note here is parameters' type and return type should be explicitly defined for fn

fn mul(x: Int, y: Int) -> Int:
    return x * y

Arguments Mutability

There are broadly 3 types of ownership in mojo.

  1. borrowed - This is assigned to the params by default but we can explicitly mention this as well. In this params are immutable, we can only read them but can't modify them.

     fn mul(borrowed x: Int, borrowed y: Int) -> Int:
         return x * y
    
  2. inout - This allows the function to modify the params' values, which means it makes params mutable.

     fn mul(inout x: Int, inout y: Int) -> Int:
         x += 1
         y += 1
         return x * y
    
     var a = 1
     var b = 2
     c = mul(a, b)
     print(a) # here a = 2 as mul incremented it
     print(c)
    
  3. owned - This will make the parameter value mutable, but any changes made inside the function will not affect the original variable.

     fn mul(owned x: Int, owned y: Int) -> Int:
         x += 1
         y += 1
         return x * y
    
     var a = 1
     var b = 2
     c = mul(a, b)
     print(a) # here a = 1 as changes inside mul are not reflected on a
     print(c)
    

Transfer operator ( ^)

If you wish to transfer ownership of the value to the function without making a copy, you can use the '^' transfer operator when passing 'a' to the function. The transfer operator effectively destroys the local variable name.

fn add_fire(owned text: String) -> String:
    text += "๐Ÿ”ฅ"
    return text

fn start():
    let a: String = "Ash"
    let b = add_fire(a^)
    # from this point we can't access varible 'a'
start()

Python integration

Mojo allows to import Python modules as-is.

from python import Python

let np = Python.import_module("numpy")

ar = np.arange(15).reshape(3, 5)
print(ar)
print(ar.shape)
# Source : https://docs.modular.com/mojo/

Did you find this article valuable?

Support Aryan Sri harsha by becoming a sponsor. Any amount is appreciated!

ย