llms.txt
Skip to main content

Functions

Functions are the building blocks of Move programs. They are called from user transactions and from other functions and group executable code into reusable units. Functions can take arguments and return a value. They are declared with the fun keyword at the module level. Just like any other module member, by default they're private and can only be accessed from within the module; making them visible to other modules is the topic of the Visibility Modifiers section, later in this chapter.

module book::math;

#[test_only]
use std::unit_test::assert_eq;

/// Function takes two arguments of type `u64` and returns their sum.
/// The `public` visibility modifier makes the function accessible from
/// outside the module.
public fun add(a: u64, b: u64): u64 {
a + b
}

#[test]
fun test_add() {
let sum = add(1, 2);
assert_eq!(sum, 3);
}

In this example, we define a function add that takes two arguments of type u64 and returns their sum. The test_add function, located in the same module, is a test function that calls add. The test uses the assert_eq! macro to compare the result of add with the expected value. If the two values differ, the execution is aborted automatically.

Function Declaration

In Move, functions are typically named using the snake_case convention. This means function names should be all lowercase, with words separated by underscores. Examples include do_something, add, get_balance, is_authorized, and so on.

A function is declared with the fun keyword followed by the function name (a valid Move identifier), a list of arguments in parentheses, and a return type. The function body is a block, and, like in any block, the last expression without a semicolon is the function's return value. The return keyword allows returning early - it is covered with the other control flow expressions.

fun return_nothing() {
// empty expression, function returns `()`
}

Accessing Functions

Just like other module members, functions can be imported and accessed using a path. The path consists of the module path and the function name, separated by ::. For example, if you have a function named add in the math module within the book package, its full path would be book::math::add. If the module has already been imported - imports are covered in the Importing Modules section - you can access it directly as math::add, as in the following example:

module book::use_math;

use book::math;

fun call_add() {
// function is called via the path
let sum = math::add(1, 2);
}

Multiple Return Values

Move functions can return multiple values, which is particularly useful when you need to return more than one piece of data from a function. The return type is specified as a tuple of types, and the return value is provided as a tuple of expressions:

fun get_name_and_age(): (vector<u8>, u8) {
("John", 25)
}

The result of a function call with a tuple return has to be unpacked into variables via the let (tuple) syntax:

// Tuple must be destructured to access its elements.
// Name and age are declared as immutable variables.
let (name, age) = get_name_and_age();
assert_eq!(name, "John");
assert_eq!(age, 25);

If any of the declared values need to be declared as mutable, the mut keyword is placed before the variable name:

// declare name as mutable, age as immutable
let (mut name, age) = get_name_and_age();

If some of the returned values are not needed, they can be ignored with the _ symbol:

// ignore the name, only use the age
let (_, age) = get_name_and_age();

Further Reading

llms.txt