You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit bf1d3fb
Browse filesBrowse the repository at this point in the historyBrowse files
## Summary
Automated bump of `.sources/motoko` from `v1.7.0` to `v1.8.0`.
- Ran `npm run sync:motoko` — synced docs from the new release
- Build passed ✓
## Checklist
- [ ] Review synced content for breaking changes
- [ ] Check [release
notes](https://github.com/caffeinelabs/motoko/releases/tag/1.8.0) for
API or syntax changes that affect hand-written docs
- [ ] Verify any new sections or renamed files are handled correctly
## Sync recommendation
`sync from caffeinelabs/motoko doc/md`
Co-authored-by: pr-automation-bot-public[bot] <pr-automation-bot-public[bot]@users.noreply.github.com>
**Version 3.0.0 — Pre/Post.** Used when the actor declares a single migration function via `(with migration = ...)`. The signature contains a pre-signature (the fields the migration function consumes from the old actor) and a post-signature (the new actor's stable fields):
258
+
**Version 3.0.0: Pre/Post.** Used when the actor declares a single migration function via `(with migration = ...)`. The signature contains a pre-signature (the fields the migration function consumes from the old actor) and a post-signature (the new actor's stable fields):
Fields marked `in` are required inputs that must be present in the previous actor. Fields marked `stable` are carried through or newly declared.
264
264
265
-
**Version 4.0.0 — Multi (enhanced).** Used with `--enhanced-migration`. The signature contains the full migration chain followed by the actor's stable fields. Each entry in the chain records a migration module's name and function signature:
265
+
**Version 4.0.0: Multi (enhanced).** Used with `--enhanced-migration`. The signature contains the full migration chain followed by the actor's stable fields. Each entry in the chain records a migration module's name and function signature:
Copy file name to clipboardExpand all lines: docs/languages/motoko/fundamentals/actors/enhanced-multi-migration.md
+14-14Lines changed: 14 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ title: "Enhanced multi-migration"
6
6
7
7
Enhanced multi-migration lets you manage canister state changes over time through a series of migration modules, each stored in its own file. Instead of writing a single inline migration function, one builds up a chain of small, self-contained migrations that the compiler and runtime apply in order.
8
8
9
-
This approach is especially useful for long-lived canisters whose data shape evolves across many deployments. Each migration captures one logical change — adding a field, renaming a field, changing a type — and the compiler verifies that the entire chain is consistent.
9
+
This approach is especially useful for long-lived canisters whose data shape evolves across many deployments. Each migration captures one logical change: adding a field, renaming a field, changing a type: and the compiler verifies that the entire chain is consistent.
10
10
11
11
## Overview
12
12
@@ -17,7 +17,7 @@ With enhanced multi-migration you:
17
17
3. Each migration module exports a `public func migration({...}) : {...}` that transforms a subset of stable fields.
18
18
4. Pass `--enhanced-migration ./migrations` to `moc` when compiling.
19
19
20
-
The compiler reads all migration modules in lexicographic order, checks that they compose correctly, and compiles them into the actor. At runtime, only migrations that have not yet been applied are executed — already-applied migrations are skipped automatically.
20
+
The compiler reads all migration modules in lexicographic order, checks that they compose correctly, and compiles them into the actor. At runtime, only migrations that have not yet been applied are executed: already-applied migrations are skipped automatically.
21
21
22
22
:::note
23
23
Enhanced multi-migration requires enhanced orthogonal persistence. It cannot be combined with the inline `(with migration = ...)` syntax used for [single migration functions](/languages/motoko/fundamentals/actors/compatibility#explicit-migration-using-a-migration-function).
@@ -52,7 +52,7 @@ module {
52
52
}
53
53
```
54
54
55
-
The input record describes which stable fields this migration reads from the current state. The output record describes which fields this migration produces. The input field types must be compatible with the state at that point in the chain, and the output field types must ultimately be compatible with the new actor's declared stable fields. A migration only needs to mention the fields it cares about — all other stable fields are carried through unchanged.
55
+
The input record describes which stable fields this migration reads from the current state. The output record describes which fields this migration produces. The input field types must be compatible with the state at that point in the chain, and the output field types must ultimately be compatible with the new actor's declared stable fields. A migration only needs to mention the fields it cares about: all other stable fields are carried through unchanged.
56
56
57
57
### The actor
58
58
@@ -71,7 +71,7 @@ actor {
71
71
}
72
72
```
73
73
74
-
The initial value of each uninitialized variable is determined entirely by the migration chain. When the canister is first deployed, every migration runs in order and the final state provides the values. On subsequent upgrades, only newly added migrations execute, but the result is the same: the migration chain — not the actor source — is the single source of truth for stable variable values.
74
+
The initial value of each uninitialized variable is determined entirely by the migration chain. When the canister is first deployed, every migration runs in order and the final state provides the values. On subsequent upgrades, only newly added migrations execute, but the result is the same: the migration chain: not the actor source: is the single source of truth for stable variable values.
75
75
76
76
The compiler rejects any stable variable that carries an initializer when `--enhanced-migration` is enabled. This prevents ambiguity about whether the value comes from the migration chain or from the inline expression.
Because the migration chain is the sole source of stable variable values, the top-level code in the actor body must be **static** — it must evaluate without immediate side effects. Arbitrary function calls, mutable updates to non-stable state, and other effectful expressions at the top level of the actor are rejected by the compiler.
84
+
Because the migration chain is the sole source of stable variable values, the top-level code in the actor body must be **static**: it must evaluate without immediate side effects. Arbitrary function calls, mutable updates to non-stable state, and other effectful expressions at the top level of the actor are rejected by the compiler.
85
85
86
86
The one exception is calls to functions that require `<system>` capability, such as setting up ICP timers or configuring Candid decoding limits. These calls are permitted because they do not alter stable variable state; their effects are confined to system-level configuration.
87
87
@@ -118,13 +118,13 @@ moc --enhanced-orthogonal-persistence \
118
118
119
119
Each migration's `migration` function declares which fields it reads (input) and which fields it produces (output). The relationship between input and output fields determines what happens to the state:
120
120
121
-
-**Input and output** — the migration transforms this field. It reads the old value and produces a new one, potentially with a different type. The output value replaces the old one in the state.
121
+
-**Input and output**: the migration transforms this field. It reads the old value and produces a new one, potentially with a different type. The output value replaces the old one in the state.
122
122
123
-
-**Output only** — the migration introduces a new field. The field is added to the state with the value and type returned by the migration.
123
+
-**Output only**: the migration introduces a new field. The field is added to the state with the value and type returned by the migration.
124
124
125
-
-**Input only** — the migration consumes and removes this field. The field is dropped from the state. Later migrations can no longer reference it.
125
+
-**Input only**: the migration consumes and removes this field. The field is dropped from the state. Later migrations can no longer reference it.
126
126
127
-
-**Neither input nor output** — the field is untouched by this migration and carried through to the next migration (or the final actor) as-is.
127
+
-**Neither input nor output**: the field is untouched by this migration and carried through to the next migration (or the final actor) as-is.
128
128
129
129
For example, given the state `{a : Nat; b : Text; c : Bool}` and a migration:
130
130
@@ -272,7 +272,7 @@ module {
272
272
273
273
Here is how an actor's state might evolve across several deployments:
Copy file name to clipboardExpand all lines: docs/languages/motoko/fundamentals/basic-syntax/comments.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,7 @@ Use `//` for comments that extend to the end of a line.
14
14
// This is a single-line comment
15
15
```
16
16
17
-
Use `///` for function or module documentation (also known as "doc comments"). Module documentation can be exported into documentation files such as Markdown or HTML using [mo-doc](../../../../developer-tools/index.md#mo-doc).
17
+
Use `///` for function or module documentation (also known as "doc comments"). Module documentation can be exported into documentation files such as Markdown or HTML using [mo-doc](/developer-tools/#mo-doc).
18
18
19
19
```motoko no-repl
20
20
/// Returns the sum of two integers.
@@ -46,5 +46,5 @@ Multi-line comments can be nested within each other.
Unlike option types, the Result type includes a second type parameter `Err` which allows you to specify exactly what kind of error occurred. This makes error handling more informative and flexible.
Copy file name to clipboardExpand all lines: docs/languages/motoko/fundamentals/implicit-parameters.md
+58-12Lines changed: 58 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,25 +6,25 @@ description: "Motoko language documentation"
6
6
## Overview
7
7
8
8
Implicit parameters allow you to omit frequently-used function arguments at call sites when the compiler can infer them from context. This feature is particularly useful when working with ordered collections like `Map` and `Set` from the `core` library, which require comparison functions but where the comparison logic is usually obvious from the key type.
9
-
Other exampes are `equal` and `toText` functions.
9
+
Other examples are `equal` and `toText` functions.
10
10
11
11
## Basic usage
12
12
13
13
### Declaring implicit parameters
14
14
15
15
When declaring a function, any function parameter can be declared implicit using the `implicit` type constructor:
16
16
17
-
For example, the core Map library, declares a function:
17
+
For example, the core `Map` library declares a function:
The `implicit` marker on the type of parameter `compare` indicates the call-site can omit it the `compare` argument, provided it can be inferred the call site.
25
+
The `implicit` marker on the type of parameter `compare` indicates the call-site can omit the `compare` argument, provided it can be inferred at the call site.
26
26
27
-
A function can declare more than on implicit parameter, even of the same name.
27
+
A function can declare more than one implicit parameter, even of the same name.
28
28
29
29
30
30
```motoko
@@ -58,7 +58,7 @@ Map.add(map, 5, "five");
58
58
```
59
59
The compiler automatically finds an appropriate comparison function based on the type of the key argument.
60
60
61
-
The availabe candidates are:
61
+
The available candidates are:
62
62
* Any value named `compare` whose type matches the parameter type.
63
63
64
64
If there is no such value,
@@ -69,7 +69,7 @@ An ambiguous call can always be disambiguated by supplying the explicit argument
69
69
70
70
### Contextual dot notation
71
71
72
-
Implicit parameters dovetail nicely with the [contextual dot notation](contextual-dot).
72
+
Implicit parameters dovetail nicely with [contextual dot notation](/languages/motoko/fundamentals/contextual-dot).
73
73
The dot notation and implicit arguments can be used in conjunction to shorten code.
74
74
75
75
For example, since the first parameter of `Map.add` is called `self`, we can both use `map` as the receiver of `add` "method" calls
@@ -84,7 +84,7 @@ let map = Map.empty<Nat, Text>();
84
84
// Using contextual dot notation, without implicits - must provide compare function explicitly
85
85
map.add(Nat.compare, 5, "five");
86
86
87
-
// Using contextual dot nation together with implicits - compare function inferred from key type
87
+
// Using contextual dot notation together with implicits - compare function inferred from key type
88
88
map.add(5, "five");
89
89
```
90
90
@@ -150,7 +150,7 @@ let scores = Map.empty<Text, Nat>();
150
150
// Add player scores
151
151
scores.add("Alice", 100);
152
152
scores.add("Bob", 85);
153
-
scores.add("Charlie", 92);
153
+
scores.add("Charlie", 92);
154
154
155
155
// Update a score
156
156
scores.add("Bob", 95);
@@ -161,7 +161,7 @@ if (scores.containsKey("Alice")) {
161
161
};
162
162
163
163
// Get size
164
-
let playerCount = scores.size()
164
+
let playerCount = scores.size();
165
165
```
166
166
167
167
## How inference works
@@ -170,13 +170,57 @@ The compiler infers an implicit argument by:
170
170
171
171
1. Examining the types of the explicit arguments provided.
172
172
2. Looking for all candidate values for the implicit argument in the current scope that match the required type and name.
173
-
3. From these, selecting the best unique candidate based on type specifity.
173
+
3. From these, selecting the best unique candidate based on type specificity.
174
174
175
175
If there is no unique best candidate the compiler rejects the call as ambiguous.
176
176
177
-
If a callee takes several implicits parameter, either all implicit arguments must be omitted, or all explicit and implicit arguments must be provided at the call site,
177
+
If a callee takes several implicit parameters, either all implicit arguments must be omitted, or all explicit and implicit arguments must be provided at the call site,
178
178
in their declared order.
179
179
180
+
### Resolution order
181
+
182
+
The compiler searches for implicit arguments in the following order, stopping at the first tier that produces a unique match:
183
+
184
+
1.**Direct**: values whose type directly matches:
185
+
1. Local values in the current scope.
186
+
2. Module fields of modules in scope (e.g., `Nat.compare`).
187
+
3. Fields of unimported modules (requires `--implicit-package`).
188
+
2.**Derived**: functions with implicit parameters that, after stripping their own implicits and instantiating type parameters, match the required type (see [Implicit derivation](#implicit-derivation) below):
189
+
1. Local values in the current scope.
190
+
2. Module fields (e.g., `Array.compare<T>`).
191
+
3. Fields of unimported modules (requires `--implicit-package`).
192
+
Within each tier, if multiple candidates match, the compiler picks the most specific one (by subtyping). If no unique best candidate exists, the call is rejected as ambiguous.
193
+
194
+
This ordering guarantees that direct matches are always preferred over derived ones, and local definitions take precedence over imported or unimported module definitions.
195
+
196
+
### Implicit derivation
197
+
198
+
When no direct match exists, the compiler can **derive** an implicit argument from a function that itself has implicit parameters. This eliminates the need for boilerplate wrapper functions. The candidate function can be polymorphic (the compiler infers the type instantiation) or monomorphic.
199
+
200
+
For example, suppose `Array.compare` is declared as:
201
+
202
+
```motoko no-repl
203
+
public func compare<T>(a : [T], b : [T], compare : (implicit : (T, T) -> Order)) : Order
204
+
```
205
+
206
+
and a function requires an implicit `compare : ([Nat], [Nat]) -> Order`. Without derivation, you would need to write a wrapper:
207
+
208
+
```motoko no-repl
209
+
module MyArray {
210
+
public func compare(a : [Nat], b : [Nat]) : Order {
211
+
Array.compare(a, b) // resolves inner `compare` to Nat.compare
212
+
};
213
+
};
214
+
```
215
+
216
+
With derivation, the compiler handles this automatically. It recognizes that `Array.compare<Nat>`, after removing its implicit `compare` parameter and instantiating `T := Nat`, has the right type. It then recursively resolves the inner implicit (`Nat.compare`) and synthesizes the wrapper for you.
217
+
218
+
This works transitively: a `compare` for `[[Nat]]` is derived via `Array.compare<[Nat]>`, which needs `[Nat]` compare, which is derived via `Array.compare<Nat>`, which needs `Nat.compare`: all resolved automatically.
219
+
220
+
The resolution depth is bounded to guarantee termination. If you encounter a depth limit, you can increase it with `--implicit-derivation-depth` or provide the argument explicitly.
221
+
222
+
When derivation is attempted but fails (for example, because an inner implicit can't be resolved), the compiler reports which inner implicits were missing and, when applicable, a hint about which module to import.
223
+
180
224
### Supported types
181
225
182
226
The core library provides comparison functions for common types:
@@ -278,7 +322,9 @@ There is no need to update existing code unless you want to take advantage of th
278
322
279
323
## Performance considerations
280
324
281
-
Implicit arguments have no runtime overhead. The comparison function is resolved at compile time, so there is no performance difference between using implicit and explicit arguments. The resulting code is identical.
325
+
Implicit arguments are resolved at compile time.
326
+
- For direct matches, the resulting code is identical to explicitly passing the argument.
327
+
- For derived implicits, the compiler synthesizes a wrapper function at each call site. This creates a small overhead per call site, which could be mitigated by caching in the future. For now, if this becomes a performance issue, consider defining the function explicitly so all call sites share a single definition.
0 commit comments