Skip to content

Commit

Permalink
Apply suggestions from code review
Browse files Browse the repository at this point in the history
Co-authored-by: Cam Swords <[email protected]>
Co-authored-by: Tim Zakian <[email protected]>
  • Loading branch information
3 people authored Jul 19, 2024
1 parent 5ddf8a8 commit ec1f0f9
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 24 deletions.
12 changes: 6 additions & 6 deletions reference/src/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,12 @@ module a::m_test {

### `macro` modifier

Unlike normal functions, `macro` functions do not exist at runtime. Instead, the function is
substituted and inlined at each call site during compilation. Leveraging this, `macro` functions
have additional functionality that is not available to normal functions, namely the ability to
create higher-order functions with lambda arguments. These lambda arguments allow for parts of the
function's body to be passed as an argument by the caller. For example, the following is a simple
loop macro, where the body of the loop is passed as a lambda:
Unlike normal functions, `macro` functions do not exist at runtime. Instead, these functions are
substituted inline at each call site during compilation. These `macro` functions leverage this
compilation process to provide functionality beyond standard functions, such as accepting
higher-order _lambda_-style functions as arguments. These lambda arguments, also expanded
during compilation, allow you to pass parts of the function body to the macro as arguments.
For instance, consider the following simple loop macro, where the loop body is supplied as a lambda:

```move
macro fun ntimes($n: u64, $body: |u64| -> ()) {
Expand Down
23 changes: 7 additions & 16 deletions reference/src/functions/macros.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Macro Functions

Macro functions are a way of defining functions that are expanded at compile time at each call site.
Macro functions are a way of defining functions that are expanded during compilation at each call site.
The arguments of the macro are not evaluated eagerly like a normal function, and instead are
substituted by expression. In addition, the caller can supply code to the macro via
[lambdas](#lambdas).

These expression substitution mechanics make `macro` functions similar
[to macros found in other programming languages](<https://en.wikipedia.org/wiki/Macro_(computer_science)>);
however, they are more constrained in Move than you might expect from other languages. The parametrs
however, they are more constrained in Move than you might expect from other languages. The parameters
and return values of `macro` functions are still typed--though this can be partially relaxed with
the [`_` type](TODO). The upside of this restriction however, is that `macro` functions can be used
anywhere a normal function can be used, which is notably helpful with
Expand Down Expand Up @@ -50,13 +50,13 @@ instead the argument expression will be substituted at each usage.

## Lambdas

Lambdas a new type of expression that can be used only with `macro`s. These are used to pass code
Lambdas are a new type of expression that can only be used with `macro`s. These are used to pass code
from the caller into the body of the `macro`. While the substition is done at compile time, they are
used similarly to [anonymous functions](https://en.wikipedia.org/wiki/Anonymous_function),
[lambdas](https://en.wikipedia.org/wiki/Lambda_calculus), or
[closures](<https://en.wikipedia.org/wiki/Closure_(computer_programming)>) in other languages.

As seen in the example above (`$f: |$T| -> $U`), lambdas types defined with the syntax
As seen in the example above (`$f: |$T| -> $U`), lambda types are defined with the syntax

```text
|<type>,*| (-> <type>)?
Expand All @@ -77,7 +77,7 @@ If the return type is not annotated, it is unit `()` by default.
|&mut vector<u8>, u64| -> ()
```

Lambda expressions then are defined at the call site of the `macro` the syntax
Lambda expressions are then defined at the call site of the `macro` with the syntax

```text
|(<identifier> (: <type>)?),*| <expression>
Expand Down Expand Up @@ -118,21 +118,12 @@ See the [Examples](#iterating-over-a-vector) section for more complicated usages
### Limitations

Currently, lambdas can only be used directly in the call of a `macro` function. They cannot be bound
to a variable.

For example, the following is allowed

```move
let doubled: vector<u64> = map!(vector[1, 2, 3], |x| 2 * x);
```

But binding `|x| 2 * x` to a variable is not allowed
to a variable. For example, the following is code will produce an error:

```move
let f = |x| 2 * x;
// ^^^^^^^^^ Error! Lambdas must be used directly in 'macro' calls
let doubled: vector<u64> = map!(vector[1, 2, 3], f);
```
## Typing
Expand Down Expand Up @@ -341,7 +332,7 @@ In the example above, the `dup` macro had a local variable `a` that was used to
`$x`. You might ask, what would happen if the variable was instead named `x`? Would that conflict
with the `x` in the lambda?

The short answer is, no. `macro` functions [hygienic](https://en.wikipedia.org/wiki/Hygienic_macro),
The short answer is, no. `macro` functions are [hygienic](https://en.wikipedia.org/wiki/Hygienic_macro),
meaning that the expansion of `macro`s and lambdas will not accidentally capture variables from
another scope.

Expand Down
5 changes: 3 additions & 2 deletions reference/src/generics.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,9 @@ let bar = Bar<u64, _> { x: 0, y: vector[b"hello"] };
// ^ vector<u8> is inferred
```

The placeholder `_` cannot be used in any signatures, only in expressions. This means function
signatures, constant signatures, and datatype fields cannot use the `_` type.
The placeholder `_` may only appear in expressions and macro function definitions, not signatures.
This means you cannot use `_` as pat of the definition of a function
parameter, function return type, constant definition type, and datatype field.

## Integers

Expand Down

0 comments on commit ec1f0f9

Please sign in to comment.