DFINITY Motoko Programming Language

The DFINITY Canister SDK is alpha software from our final development branch that will make it into production. Please be aware that at this time it is less developed than previously-demonstrated prototypes and you should check back regularly to try new features.

Until the production release of the SDK, the Motoko language is under constant development and all features are subject to final security review.

Enjoy!

The Motoko programming language is a new, modern, type-sound language designed for developers who want to build the next generation of apps and services to run directly on the internet. Motoko is specifically designed to support the unique features of the Internet Computer and to provide a familiar yet robust programming environment. As a new language Motoko is constantly evolving with support for new features and improvements. Keep checking back for updates and for the announcement of the Motoko becoming available as an open source project.

Native canister support

Motoko has native support for Internet Computer software canisters, which are expressed as actors, autonomous objects that encapsulate their state and communicate through asynchronous messages.

actor Counter {

  var value = 0;

  public func inc() : async Nat {
    value += 1;
    return value;
  };
}

Code sequentially in direct style

On the Internet Computer, software canisters call into other canisters asynchronously, but Motoko enables you to program your systems sequentially in direct style. Asynchronous messages are function calls that return a future, and the await constructs allows chaining calls as if they were synchronous.

actor Factorial {

  var last = 1;

  public func next() : async Nat {
    last *= await Counter.inc();
    return last;
  }
}

Modern type system

Motoko has been designed to be intuitive to those familiar with Javascript and other popular languages, but offers modern features such as sound structural types, generics, variant types, and checked pattern matching.

type Tree<T> = {
  #leaf : T;
  #branch : {left : Tree<T>; right : Tree<T>};
};

func iterTree<T>(tree : Tree<T>, f : T -> ()) {
  switch (tree) {
    case (#leaf(x)) { f(x) };
    case (#branch{left; right}) {
      iterTree(left, f);
      iterTree(right, f);
    };
  }
}

Autogenerated IDL files

The SDK exports your interface definition in a language neutral format called Candid, so other canisters, browser resident code and smart phone apps that have permission can call into your functions. The Motoko compiler can also read and write interface definition files, allowing Motoko to seamlessly interact with canisters programmed in other languages.

For example, the previous Counter actor produces the following Candid IDL:

service Counter : {
  inc : () -> (nat);
}

Orthogonal persistence

The Internet Computer persists the memory pages in which your canister runs. Thus the state of an actor and all its memory data structures survive indefinitely, they do not need to be “saved” explicitly.

For example, in the following Registry service, that assigns sequential IDs to textual names, the state of the hash table is preserved across calls, even though the state of the canister is replicated across many nodes, and typically not resident in memory.

import Text "mo:base/Text";
import Map "mo:base/HashMap";

actor Registry {

  let map = Map.HashMap<Text, Nat>(10, Text.equal, Text.hash);

  public func register(name : Text) : async () {
    switch (map.get(name)) {
      case null {
        map.put(name, map.size());
      };
      case (?id) { };
    }
  };

  public func lookup(name : Text) : async ?Nat {
    map.get(name);
  };
}

Upgrades

Motoko provides numerous features to help you leverage orthogonal persistence, including language features that allow your heap to self-migrate when you upgrade the software of a canister.

For example, Motoko lets you declare certain variables as stable. The values of stable variables are automatically preserved across software upgrades.

Consider a stable counter:

actor Counter {

  stable var value = 0;

  public func inc() : async Nat {
    value += 1;
    return value;
  };
}

It can be installed, incremented n times, and then upgraded, without interruption, to, for example, the richer implementation:

actor Counter {

  stable var value = 0;

  public func inc() : async Nat {
    value += 1;
    return value;
  };

  public func reset() : async () {
    value := 0;
  }
}

Because value was declared stable, the current state, n, of the service is retained after the upgrade. Counting will continue from n, not restart from 0.

Because the new interface is compatible with the previous one, existing clients referencing the service will continue to work, but new clients will be able to exploit its upgraded functionality (the additional reset function).

For scenarios that can’t be solved using stable variables alone, Motoko provides user-definable upgrade hooks that run immediately before and after upgrade, and allow you to migrate arbitrary state to stable variables.

And more …​

Motoko provides many other developer productivity features, including subtyping, arbitrary precision arithmetic and garbage collection.

Motoko is not, and is not intended to be, the only language for implementing canisters. If it doesn’t suit your needs, we are also working on adding Rust support to the SDK. Our goal is to enable any language (with a compiler that targets WebAssembly) to be able to produce canisters that run on the Internet Computer and interoperate with other, perhaps foreign, canisters through language neutral Candid interfaces.

Its tailored design means Motoko should be the easiest and safest language for coding on the Internet Computer, at least for the forseeable future.