Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: minor tweaks to comptime doc #6357

Merged
merged 2 commits into from
Oct 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions docs/docs/noir/concepts/comptime.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ keywords: [Noir, comptime, compile-time, metaprogramming, macros, quote, unquote
sidebar_position: 15
---

# Overview
## Overview
jzaki marked this conversation as resolved.
Show resolved Hide resolved

Metaprogramming in Noir is comprised of three parts:
1. `comptime` code
Expand All @@ -21,7 +21,7 @@ for greater analysis and modification of programs.

---

# Comptime
## Comptime

`comptime` is a new keyword in Noir which marks an item as executing or existing at compile-time. It can be used in several ways:

Expand All @@ -32,11 +32,11 @@ for greater analysis and modification of programs.
- `comptime let` to define a variable whose value is evaluated at compile-time.
- `comptime for` to run a for loop at compile-time. Syntax sugar for `comptime { for .. }`.

## Scoping
### Scoping

Note that while in a `comptime` context, any runtime variables _local to the current function_ are never visible.

## Evaluating
### Evaluating

Evaluation rules of `comptime` follows the normal unconstrained evaluation rules for other Noir code. There are a few things to note though:

Expand All @@ -62,7 +62,7 @@ For example, using globals to generate unique ids should be fine but relying on
function itself was called at compile-time previously, it will already be resolved and cannot be modified. To prevent accidentally calling functions you wish to modify
at compile-time, it may be helpful to sort your `comptime` annotation functions into a different crate along with any dependencies they require.

## Lowering
### Lowering

When a `comptime` value is used in runtime code it must be lowered into a runtime value. This means replacing the expression with the literal that it evaluated to. For example, the code:

Expand Down Expand Up @@ -102,7 +102,7 @@ comptime fn get_type() -> Type { ... }

---

# (Quasi) Quote
## (Quasi) Quote

Macros in Noir are `comptime` functions which return code as a value which is inserted into the call site when it is lowered there.
A code value in this case is of type `Quoted` and can be created by a `quote { ... }` expression.
Expand All @@ -121,7 +121,7 @@ Calling such a function at compile-time without `!` will just return the `Quoted
For those familiar with quoting from other languages (primarily lisps), Noir's `quote` is actually a _quasiquote_.
This means we can escape the quoting by using the unquote operator to splice values in the middle of quoted code.

# Unquote
## Unquote

The unquote operator `$` is usable within a `quote` expression.
It takes a variable as an argument, evaluates the variable, and splices the resulting value into the quoted token stream at that point. For example,
Expand Down Expand Up @@ -160,7 +160,7 @@ comptime {

---

# Annotations
## Annotations

Annotations provide a way to run a `comptime` function on an item in the program.
When you use an annotation, the function with the same name will be called with that item as an argument:
Expand Down Expand Up @@ -188,7 +188,7 @@ For example, this is the mechanism used to insert additional trait implementatio

#include_code derive-field-count-example noir_stdlib/src/meta/mod.nr rust

## Calling annotations with additional arguments
### Calling annotations with additional arguments

Arguments may optionally be given to annotations.
When this is done, these additional arguments are passed to the annotation function after the item argument.
Expand All @@ -201,13 +201,13 @@ We can also take any number of arguments by adding the `varargs` annotation:

---

# Comptime API
## Comptime API

Although `comptime`, `quote`, and unquoting provide a flexible base for writing macros,
Noir's true metaprogramming ability comes from being able to interact with the compiler through a compile-time API.
This API can be accessed through built-in functions in `std::meta` as well as on methods of several `comptime` types.

The following is an incomplete list of some `comptime` types along with some useful methods on them.
The following is an incomplete list of some `comptime` types along with some useful methods on them. You can see more in the standard library [Metaprogramming section](../standard_library/meta).

- `Quoted`: A token stream
- `Type`: The type of a Noir type
Expand Down Expand Up @@ -238,7 +238,7 @@ The following is an incomplete list of some `comptime` types along with some use
There are many more functions available by exploring the `std::meta` module and its submodules.
Using these methods is the key to writing powerful metaprogramming libraries.

## `#[use_callers_scope]`
### `#[use_callers_scope]`

Since certain functions such as `Quoted::as_type`, `Expression::as_type`, or `Quoted::as_trait_constraint` will attempt
to resolve their contents in a particular scope - it can be useful to change the scope they resolve in. By default
Expand All @@ -251,7 +251,7 @@ your attribute function and a helper function it calls use it, then they can bot

---

# Example: Derive
## Example: Derive

Using all of the above, we can write a `derive` macro that behaves similarly to Rust's but is not built into the language.
From the user's perspective it will look like this:
Expand Down
Loading