The final feature that we will be taking a look at is one is arguably one of the most unique: **macros**. Be aware that a macro in Nessa is not the same as a macro in other languages such as C, C++ or even Rust, even though they are close to Rust's. The main difference between Rust's macros and Nessa's is that there is no restriction on the syntax that you can match. Let's take a look at how they work by diving into the first kind of macros Nessa has: **function macros**. ## Syntax A function macro can be created in Nessa using this syntax: ``` syntax macro_name from NDL_Pattern { [...] } // This is also allowed syntax fn macro_name from NDL_Pattern { [...] } ``` When you define a macro of this kind you can "invoke" it by using the syntax anywhere in your code where an expression is legal. Just be aware that macros are internally compiled to a different representation. In the case of function macros, they are converted to **do blocks**: ``` syntax macro_name from "Macro" Arg(n, 1{d}) { return $n; } // This macro ... print(Macro5); // ... is compiled to this print(do { return 5; }); ``` You may have noticed that the syntax inside a macro body is not the same as a function. This is because the body of a macro is composed of **patterns** that use `Arg`s in order to generate code by concatenation. There are a few different types of patterns with varying complexities, but they all generate a piece of text that is concatenated to the one generated by the previous pattern. ## Macro patterns These are the patterns that you can use inside a macro's body: | Pattern | Syntax | Description | | -------- | -------------------- | -------------------------------------------------------------------- | | Variable | `$Var` | Pastes the value of the `Arg` named `Var` into the macro result | | Index | `$Var.i` | Pastes the `i`th value of the `Arg` named `Var` into the macro result. `i` must also be an `Arg` | | Loop | `@Var.i {Pat}` | Pastes the result of the `Pat` subpattern creating a variable `i` with its corresponing index for each element in `Var` | | Code | `{| Pat |}` | Gets the result of the `Pat` subpattern and executes the resulting code. Pastes anything that is passed to `emit` (more information in its own section) | | Text | Anything else | Pastes the given text into the macro result | In order to be able to write these patterns and disambiguate where the macro ends you may have to **escape braces or dots**. This is common when writing code patterns, since loops, lambdas and do blocks use braces. ## Example Let's see an example where we try to create a macro to initialize an `Array` statically: ``` syntax array_initialization from "<" Arg(, type) ">[" [{Arg(, elems) "," [s]} Arg(, elems)] "]" { let res = arr<$type>(); @elems.i { res.push($elems.i); } return move(res); } ``` This macro allows you to write code such as this: ``` let array = [1, 2, 3, 4, 5]; ``` Which will then be compiled to this: ``` let array = do { let res = arr(); res.push(1); res.push(2); res.push(3); res.push(4); res.push(5); return *res; }; ``` As you can imagine, this allows you to create very complex behaviours transparently. You can see more complex examples in the *Learn by example* section.