DEV Community

Cover image for Understanding Motoko’s Type System: A Beginner-Friendly Guide 🚀
John Benjamin
John Benjamin

Posted on

2

Understanding Motoko’s Type System: A Beginner-Friendly Guide 🚀

Understanding Motoko’s Type System: A Beginner-Friendly Guide 🚀

Introduction

Motoko is the native programming language for building smart contracts on the Internet Computer (ICP). One of its standout features is its strong and flexible type system, which ensures code reliability and security. In this article, we’ll explore Motoko’s type system, covering primitive and non-primitive types, mutability, and function type annotations.


1️⃣ Primitive Types in Motoko

Motoko provides several built-in primitive types, including:

Boolean (Bool) – Represents true or false.

Integer (Int) – Signed whole numbers (e.g., -10, 0, 25).

Natural (Nat) – Unsigned whole numbers (only positive, e.g., 0, 5, 100).

Character (Char) – A single Unicode character (e.g., 'A', '1', '%').

Text (Text) – Strings of characters ("Hello, ICP!").

Example:

let isStudent: Bool = true;  
let age: Int = -25;  
let score: Nat = 100;  
let initial: Char = 'A';  
let greeting: Text = "Welcome to ICP!";
Enter fullscreen mode Exit fullscreen mode

2️⃣ Bounded vs. Unbounded Types

Motoko offers bounded types for performance optimization. These types have fixed sizes and help in memory management:

Bounded Types: Int8, Int16, Int32, Nat8, Nat16, etc.

Unbounded Types: Int, Nat (default for large numbers).

Example:

let smallNumber: Int8 = 127;  // Max value for Int8  
let bigNumber: Int = 1000000; // Unbounded integer  
Enter fullscreen mode Exit fullscreen mode

Use bounded types when you need strict size control (e.g., working with low-memory devices) and unbounded types when dealing with large calculations.


3️⃣ Mutability: let vs. var

In Motoko, variables can be immutable (let) or mutable (var):

let (Immutable) – Once assigned, the value cannot change.

var (Mutable) – The value can be updated using :=.

Example:

let pi: Float = 3.1415;  // Immutable  
var count: Nat = 0;      // Mutable  
count := count + 1;      // Updating a mutable variable  
Enter fullscreen mode Exit fullscreen mode

Using immutable values (let) is recommended for better security and predictability in smart contracts.


4️⃣ Non-Primitive Types: Collections & Data Structures

Motoko supports more complex data structures like Tuples, Arrays, and Objects.

Tuples ((type1, type2, ...)) – Fixed-size collections of different types.

Arrays ([type]) – Collections of the same type.

Objects – Similar to structs/classes in other languages.

Example:

let student: (Text, Int) = ("Alice", 22);  // Tuple  
let scores: [Nat] = [85, 90, 95];          // Array  
Enter fullscreen mode Exit fullscreen mode

Arrays are homogeneous (same type), while Tuples allow multiple types in a single structure.


5️⃣ Function Types & Type Annotations

Motoko functions require explicit type annotations for both parameters and return values:

Query functions (query) – Read-only, faster execution.

Update functions (update) – Modify state, slower due to consensus.

Example:

actor Counter {
    var count: Nat = 0;

    public query func getCount() : async Nat {
        return count;
    };

    public func increment() : async Nat {
        count += 1;
        return count;
    };
};
Enter fullscreen mode Exit fullscreen mode

Why explicit types?

  • Prevents unexpected data issues.
  • Helps the compiler detect errors before execution.
  • Improves code readability and maintainability.

6️⃣ Error Handling & Debugging with Types

Motoko includes built-in error handling features:

assert – Stops execution if a condition is false.

trap – Throws an error if something goes wrong.

Example:

func divide(x: Nat, y: Nat) : Nat {
    assert(y != 0);  // Prevent division by zero  
    return x / y;
};
Enter fullscreen mode Exit fullscreen mode

By enforcing types, Motoko ensures fewer runtime errors, making smart contracts safer and more predictable.


Conclusion

Motoko’s type system is powerful and strict, ensuring security, efficiency, and reliability in smart contracts. Understanding primitive vs. non-primitive types, bounded vs. unbounded numbers, mutability, and function annotations will help you build robust dApps on the ICP blockchain.

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (0)