Copied


Move 2024 Beta Unveils New Macro Functions for Developers

Rongchai Wang   Aug 28, 2024 19:45 0 Min Read


The Move 2024 beta edition introduces a significant enhancement for developers with the addition of macro functions, according to The Sui Blog. This new feature allows developers to replace common loops with macro functions, offering a more efficient way to write and execute code.

Understanding Macro Functions

Macro functions in Move are similar to regular functions but with notable differences. Developers can define parameters, return types, and logic for macro functions, which can then be called from anywhere in the code. However, unlike regular functions, the compiler expands these functions in place, executing the defined operations inline.

Key distinctions of macro functions include:

  • Macro function syntax extensions
  • Move compiler expansion and call semantics
  • Lambda parameters

Syntax Extensions

Move syntax specifies how to define and invoke macro functions, helping the compiler distinguish them from normal functions. These rules also provide visual differentiation during usage.

Compiler Expansion and Call Semantics

Normal function arguments are fully evaluated at runtime, regardless of whether they are necessary for the function logic. In contrast, macro functions substitute the expressions for their arguments during expansion, meaning arguments are not evaluated if the macro body code with the argument is never reached.

Lambda Parameters

Macro functions allow for parameterized code as higher-order function arguments via the lambda type, enabling the creation of powerful and flexible macros. This functionality is similar to anonymous functions, lambdas, or closures in other programming languages.

Anatomy of Macro Functions

During compilation, the Move compiler expands macro functions, allowing for expressiveness not available in normal functions. Macro functions have their type and expression parameters prefixed with a $ character.

For example, consider a macro function my_assert:

macro fun my_assert($cond: bool, $code: u64) {
  if (!$cond) abort $code.
}

This macro checks the condition passed to it and aborts the program if the condition resolves to false with the provided code.

Macros with Lambda Arguments

Macro functions can include lambda arguments, allowing code to be passed from the caller into the macro body. For instance, a loop that executes a lambda on each number from 0 to a specified number can be written as:

public macro fun do($n: u64, $f: |u64| -> ()) {
  let mut i = 0;
  let stop = $n;
  while (i < stop) {
    $f(i);
    i = i + 1;
  }
}

This macro can be used to sum numbers from 0 to 10:

let mut sum = 0;
do!(10, |i| sum = sum + i);

Macros in the Move Standard Library

The move-stdlib library introduces several macro functions to capture common programming patterns. For example, the do macro for u64 types simplifies common loops:

10u64.do!(|i| foo(i));

Other macros include range_do_eq for more complex loops:

1u64.range_do_eq!(8, |i| foo(10u64.pow(i)));

Vector Macros

Vector macros allow for iteration over elements of a vector, such as:

vector[1, 2, 3, 4, 5].do!(|x| foo(x));

Expanded, this is equivalent to:

let mut v = vector[1, 2, 3, 4, 5];
v.reverse();
while (!v.is_empty()) {
  foo(v.pop_back());
}

Option Macros

Macros for the Option type simplify access to its value if it is some:

fun maybe_transfer(coin: Option<Coin<SUI>>, recipient: address) {
  coin.do!(|c| transfer::public_transfer(c, recipient))
}

Additional macros like destroy_or provide default expressions evaluated only if the Option is none.

Conclusion

Macro functions in Move 2024 beta aim to simplify code by converting common patterns into reusable macros. Developers are encouraged to explore these new tools to enhance their coding efficiency. More macro functions are expected to be added to the move-stdlib library and the Sui framework.

For detailed information on macro functions, refer to the Move book.


Read More