From b02b0d1f6df3cd769d97c787301e03bb2b7bd335 Mon Sep 17 00:00:00 2001 From: Marco Walz Date: Mon, 18 May 2026 11:47:24 +0200 Subject: [PATCH 01/43] fix(motoko): restore missing pages, fix nav order, rewrite stale links - Restore language-manual.md, style-guide.md, compiler-ref.md to reference/ (all three were silently dropped by the sync script which only checked directories, not top-level .md files) - Restructure fundamentals/ from a flat 53-file list to the correct grouped layout (basic-syntax/, actors/, types/, declarations/, control-flow/) matching the source directory tree; this also fixes the silent page loss caused by two files mapping to the same flat name after stripping numeric prefixes (both basic-syntax/functions.md and types/function-types.md now exist) - Update sidebar.mjs with explicit ordered groups for all Motoko sections so the navbar reflects the logical learning progression instead of alphabetical order - Add URL rewrite table to postprocess-motoko.mjs: all internetcomputer.org/docs/ links in synced pages are now rewritten to internal developer-docs paths - Remove dead docs.motoko.org redirect (was used for language-manual links; that page is now included directly) - Extend sync-motoko.sh guard to check top-level .md files, not just directories - Fix cross-reference in message-execution-properties.md to new actors/ path - Add .docs-plan/motoko-repo-sync-proposal.md: roadmap for eliminating the sync transformation entirely by adopting Starlight-native conventions in the Motoko repo --- .docs-plan/motoko-repo-sync-proposal.md | 213 ++ .../fundamentals/{ => actors}/actors-async.md | 4 +- .../{ => actors}/compatibility.md | 16 +- .../{ => actors}/data-persistence.md | 8 +- .../{ => actors}/enhanced-multi-migration.md | 8 +- .../fundamentals/{ => actors}/messaging.md | 2 +- .../fundamentals/{ => actors}/mixins.md | 0 .../orthogonal-persistence/classical.md} | 4 +- .../orthogonal-persistence/enhanced.md} | 6 +- .../motoko/fundamentals/{ => actors}/state.md | 0 .../{ => basic-syntax}/characters-text.md | 0 .../{ => basic-syntax}/comments.md | 2 +- .../{ => basic-syntax}/defining-an-actor.md | 10 +- .../fundamentals/basic-syntax/functions.md | 86 + .../{ => basic-syntax}/identifiers.md | 2 +- .../{ => basic-syntax}/imports.md | 2 +- .../{ => basic-syntax}/literals.md | 2 +- .../{ => basic-syntax}/numbers.md | 0 .../{ => basic-syntax}/operators.md | 0 .../{ => basic-syntax}/printing-values.md | 2 +- .../fundamentals/{ => basic-syntax}/traps.md | 0 .../{ => basic-syntax}/whitespace.md | 2 +- .../motoko/fundamentals/contextual-dot.md | 2 +- .../{ => control-flow}/basic-control-flow.md | 4 +- .../fundamentals/{ => control-flow}/blocks.md | 0 .../{ => control-flow}/conditionals.md | 0 .../fundamentals/{ => control-flow}/loops.md | 0 .../fundamentals/{ => control-flow}/switch.md | 0 .../{ => declarations}/class-declarations.md | 4 +- .../expression-declarations.md | 2 +- .../function-declarations.md | 2 +- .../{ => declarations}/module-declarations.md | 0 .../{ => declarations}/object-declaration.md | 2 +- .../{ => declarations}/type-declarations.md | 6 +- .../variable-declarations.md | 0 .../motoko/fundamentals/error-handling.md | 2 +- .../motoko/fundamentals/hello-world.md | 10 +- .../fundamentals/implicit-parameters.md | 2 +- .../motoko/fundamentals/modules-imports.md | 6 +- .../{ => types}/advanced-types.md | 6 +- .../{functions.md => types/function-types.md} | 20 +- .../{ => types}/immutable-arrays.md | 6 +- .../{ => types}/mutable-arrays.md | 8 +- .../{ => types}/objects-classes.md | 6 +- .../fundamentals/{ => types}/options.md | 4 +- .../{ => types}/primitive-types.md | 0 .../fundamentals/{ => types}/records.md | 4 +- .../fundamentals/{ => types}/results.md | 0 .../fundamentals/{ => types}/shared-types.md | 20 +- .../fundamentals/{ => types}/stable-types.md | 14 +- .../fundamentals/{ => types}/subtyping.md | 14 +- .../motoko/fundamentals/{ => types}/tuples.md | 2 +- .../{ => types}/type-conversions.md | 4 +- .../fundamentals/{ => types}/variants.md | 10 +- .../icp-features/candid-serialization.md | 10 +- .../motoko/icp-features/randomness.md | 8 +- .../motoko/icp-features/stable-memory.md | 8 +- .../motoko/icp-features/system-functions.md | 18 +- docs/languages/motoko/icp-features/timers.md | 2 +- docs/languages/motoko/reference/changelog.md | 2 +- .../motoko/reference/compiler-ref.md | 78 + .../languages/motoko/reference/error-codes.md | 8 +- .../motoko/reference/language-manual.md | 2999 +++++++++++++++++ .../languages/motoko/reference/style-guide.md | 897 +++++ .../message-execution-properties.md | 2 +- scripts/postprocess-motoko.mjs | 282 +- scripts/sync-motoko.sh | 252 +- sidebar.mjs | 121 +- 68 files changed, 4927 insertions(+), 289 deletions(-) create mode 100644 .docs-plan/motoko-repo-sync-proposal.md rename docs/languages/motoko/fundamentals/{ => actors}/actors-async.md (97%) rename docs/languages/motoko/fundamentals/{ => actors}/compatibility.md (95%) rename docs/languages/motoko/fundamentals/{ => actors}/data-persistence.md (95%) rename docs/languages/motoko/fundamentals/{ => actors}/enhanced-multi-migration.md (98%) rename docs/languages/motoko/fundamentals/{ => actors}/messaging.md (94%) rename docs/languages/motoko/fundamentals/{ => actors}/mixins.md (100%) rename docs/languages/motoko/fundamentals/{orthogonal-persistence-classical.md => actors/orthogonal-persistence/classical.md} (90%) rename docs/languages/motoko/fundamentals/{orthogonal-persistence-enhanced.md => actors/orthogonal-persistence/enhanced.md} (94%) rename docs/languages/motoko/fundamentals/{ => actors}/state.md (100%) rename docs/languages/motoko/fundamentals/{ => basic-syntax}/characters-text.md (100%) rename docs/languages/motoko/fundamentals/{ => basic-syntax}/comments.md (92%) rename docs/languages/motoko/fundamentals/{ => basic-syntax}/defining-an-actor.md (77%) create mode 100644 docs/languages/motoko/fundamentals/basic-syntax/functions.md rename docs/languages/motoko/fundamentals/{ => basic-syntax}/identifiers.md (78%) rename docs/languages/motoko/fundamentals/{ => basic-syntax}/imports.md (98%) rename docs/languages/motoko/fundamentals/{ => basic-syntax}/literals.md (91%) rename docs/languages/motoko/fundamentals/{ => basic-syntax}/numbers.md (100%) rename docs/languages/motoko/fundamentals/{ => basic-syntax}/operators.md (100%) rename docs/languages/motoko/fundamentals/{ => basic-syntax}/printing-values.md (84%) rename docs/languages/motoko/fundamentals/{ => basic-syntax}/traps.md (100%) rename docs/languages/motoko/fundamentals/{ => basic-syntax}/whitespace.md (90%) rename docs/languages/motoko/fundamentals/{ => control-flow}/basic-control-flow.md (96%) rename docs/languages/motoko/fundamentals/{ => control-flow}/blocks.md (100%) rename docs/languages/motoko/fundamentals/{ => control-flow}/conditionals.md (100%) rename docs/languages/motoko/fundamentals/{ => control-flow}/loops.md (100%) rename docs/languages/motoko/fundamentals/{ => control-flow}/switch.md (100%) rename docs/languages/motoko/fundamentals/{ => declarations}/class-declarations.md (91%) rename docs/languages/motoko/fundamentals/{ => declarations}/expression-declarations.md (98%) rename docs/languages/motoko/fundamentals/{ => declarations}/function-declarations.md (96%) rename docs/languages/motoko/fundamentals/{ => declarations}/module-declarations.md (100%) rename docs/languages/motoko/fundamentals/{ => declarations}/object-declaration.md (95%) rename docs/languages/motoko/fundamentals/{ => declarations}/type-declarations.md (93%) rename docs/languages/motoko/fundamentals/{ => declarations}/variable-declarations.md (100%) rename docs/languages/motoko/fundamentals/{ => types}/advanced-types.md (95%) rename docs/languages/motoko/fundamentals/{functions.md => types/function-types.md} (88%) rename docs/languages/motoko/fundamentals/{ => types}/immutable-arrays.md (90%) rename docs/languages/motoko/fundamentals/{ => types}/mutable-arrays.md (93%) rename docs/languages/motoko/fundamentals/{ => types}/objects-classes.md (95%) rename docs/languages/motoko/fundamentals/{ => types}/options.md (97%) rename docs/languages/motoko/fundamentals/{ => types}/primitive-types.md (100%) rename docs/languages/motoko/fundamentals/{ => types}/records.md (95%) rename docs/languages/motoko/fundamentals/{ => types}/results.md (100%) rename docs/languages/motoko/fundamentals/{ => types}/shared-types.md (75%) rename docs/languages/motoko/fundamentals/{ => types}/stable-types.md (88%) rename docs/languages/motoko/fundamentals/{ => types}/subtyping.md (94%) rename docs/languages/motoko/fundamentals/{ => types}/tuples.md (99%) rename docs/languages/motoko/fundamentals/{ => types}/type-conversions.md (95%) rename docs/languages/motoko/fundamentals/{ => types}/variants.md (86%) create mode 100644 docs/languages/motoko/reference/compiler-ref.md create mode 100644 docs/languages/motoko/reference/language-manual.md create mode 100644 docs/languages/motoko/reference/style-guide.md diff --git a/.docs-plan/motoko-repo-sync-proposal.md b/.docs-plan/motoko-repo-sync-proposal.md new file mode 100644 index 00000000..d3fbc352 --- /dev/null +++ b/.docs-plan/motoko-repo-sync-proposal.md @@ -0,0 +1,213 @@ +# Proposal: Transform-free Motoko docs sync + +**Context:** `docs.internetcomputer.org` syncs Motoko language documentation from +`caffeinelabs/motoko` as a git submodule. Currently a 200-line bash script +(`sync-motoko.sh`) plus a 300-line Node.js post-processor (`postprocess-motoko.mjs`) +are needed on every release to: flatten numbered directories, strip numeric prefixes, +convert Docusaurus-specific syntax to Starlight syntax, rewrite relative links to +match the flattened structure, and expand file-embed code blocks. + +The goal is to reach a state where syncing is just a file copy: no structural +transformation, no syntax conversion, no link rewriting needed. + +--- + +## Problems with the current setup + +### 1. Numbered directories and files + +``` +fundamentals/ + 1-basic-syntax/ + 1-defining-an-actor.md + 8-functions.md ← same slug as types/3-functions.md after stripping + 3-types/ + 3-functions.md ← collision! both flatten to "functions.md" +``` + +Numeric prefixes encode ordering in Docusaurus (which uses `_category_.yml`). +Starlight uses `sidebar: { order: N }` frontmatter instead, so the prefix +serves no purpose once the files are in Starlight. Removing the prefixes and +using frontmatter order avoids the collision problem and removes the need to +strip prefixes during sync. + +### 2. Docusaurus-specific frontmatter + +```yaml +sidebar_position: 8 # Docusaurus +``` + +Starlight uses: + +```yaml +sidebar: + order: 8 +``` + +`sidebar_position` is silently ignored by Starlight, leaving all pages in +undefined (alphabetical) order until the consuming site explicitly enumerates +them in its sidebar config. + +### 3. Docusaurus file-embed syntax + +```` +```motoko file=../examples/counter.mo#L1-L30 +``` +```` + +Starlight has no equivalent; the sync post-processor must inline the file +content at build time. Inline code in the source is both more explicit and +removes the dependency on the examples directory structure. + +### 4. Links to retired portal URLs + +Many files reference `internetcomputer.org/docs/...`, which is the retired +DFINITY portal. The sync post-processor maintains a rewrite table to map these +to internal developer-docs paths, but that table needs manual updates with +every Motoko release. + +### 5. `base/` library links + +Several files link to `./base/.md`, which is an excluded section. These +are post-processed to `mops.one/core/docs/` because `mo:base` is +deprecated in favour of `mo:core`. Using `https://mops.one/core/docs/` +links directly in the source removes the need for this rewrite. + +--- + +## Proposed changes to `caffeinelabs/motoko` + +### 1. Remove numeric prefixes from directories and files + +Change the directory structure from: + +``` +doc/md/fundamentals/ + 0-hello-world.md + 1-basic-syntax/ + 1-defining-an-actor.md + 8-functions.md + 3-types/ + 3-functions.md ← rename to function-types.md to resolve slug collision + ... +``` + +to: + +``` +doc/md/fundamentals/ + hello-world.md + basic-syntax/ + defining-an-actor.md + functions.md + types/ + function-types.md ← renamed to avoid collision with basic-syntax/functions.md + ... +``` + +Files that currently share a basename after prefix-stripping need to be given +distinct names (the one collision today is `types/functions.md` vs +`basic-syntax/functions.md`; proposed rename: `types/function-types.md`). + +### 2. Replace `sidebar_position` with Starlight-native `sidebar.order` + +In every file, replace: + +```yaml +--- +sidebar_position: 8 +--- +``` + +with: + +```yaml +--- +sidebar: + order: 8 +--- +``` + +This means the consuming site can use `autogenerate: { directory: "..." }` in +its Starlight sidebar config and get the correct order without maintaining an +explicit page list. + +Note: a few files in `2-actors/` have duplicate `sidebar_position` values (e.g. +both `4-compatibility.md` and `5-messaging.md` carry `sidebar_position: 4`). Fix +these so values are unique and match the numeric filename order. + +### 3. Inline file-embed examples + +Replace Docusaurus file-embed blocks: + +```` +```motoko file=../examples/counter.mo#L1-L30 +``` +```` + +with the actual inline code. This removes the `file=` attribute processing step +and makes the documentation self-contained. For longer examples (>30 lines), +link to the `dfinity/examples` repository rather than embedding. + +### 4. Use `mops.one` for `mo:core` links + +Replace links to `./base/.md` and `./core/.md` with direct +links to `https://mops.one/core/docs/`. This is more durable (no +relative path that changes with directory restructuring) and points to the +authoritative documentation for the `mo:core` library. + +### 5. Use `docs.internetcomputer.org` internal paths + +Replace all `internetcomputer.org/docs/...` links with the canonical +developer-docs paths (relative or absolute using `docs.internetcomputer.org`). +The mapping for common links: + +| Old portal URL | Current developer-docs path | +|---|---| +| `building-apps/essentials/canisters` | `/concepts/canisters` | +| `building-apps/canister-management/upgrade` | `/guides/canister-management/lifecycle` | +| `building-apps/canister-management/logs` | `/guides/canister-management/logs` | +| `building-apps/canister-management/snapshots` | `/guides/canister-management/snapshots` | +| `building-apps/canister-management/storage` | `/concepts/orthogonal-persistence` | +| `building-apps/interact-with-canisters/candid/candid-concepts` | `/guides/canister-calls/candid` | +| `building-apps/network-features/periodic-tasks-timers` | `/guides/backends/timers` | +| `building-apps/network-features/randomness` | `/guides/backends/randomness` | +| `building-apps/security/iam/` | `/guides/security/identity-and-access-management` | +| `references/ic-interface-spec` | `/references/ic-interface-spec/` | +| `references/candid-ref` | `/references/candid-spec` | +| `references/system-canisters/management-canister` | `/references/management-canister` | + +--- + +## What the sync becomes after these changes + +With the above changes in place, `sync-motoko.sh` reduces to: + +```bash +rsync -r --delete \ + .sources/motoko/doc/md/fundamentals/ docs/languages/motoko/fundamentals/ +rsync -r --delete \ + .sources/motoko/doc/md/icp-features/ docs/languages/motoko/icp-features/ +rsync -r --delete \ + .sources/motoko/doc/md/reference/ docs/languages/motoko/reference/ +cp .sources/motoko/doc/md/16-language-manual.md docs/languages/motoko/reference/language-manual.md +cp .sources/motoko/doc/md/14-style.md docs/languages/motoko/reference/style-guide.md +cp .sources/motoko/doc/md/15-compiler-ref.md docs/languages/motoko/reference/compiler-ref.md +``` + +And `postprocess-motoko.mjs` can be deleted entirely. + +--- + +## Migration path + +1. Open a PR in `caffeinelabs/motoko` with the structural changes above. +2. Once merged and released, update the `.sources/motoko` submodule pin. +3. Simplify `sync-motoko.sh` and delete `postprocess-motoko.mjs`. +4. Update `sidebar.mjs` to use `autogenerate: { directory: "..." }` for + the fundamentals subdirectories (since `sidebar.order` will be correct). + +The Docusaurus site in `caffeinelabs/motoko` is unaffected: Docusaurus ignores +`sidebar.order` and continues to use `_category_.yml` position values. +Both `sidebar_position` and `sidebar.order` can coexist in the same frontmatter +during the transition period. diff --git a/docs/languages/motoko/fundamentals/actors-async.md b/docs/languages/motoko/fundamentals/actors/actors-async.md similarity index 97% rename from docs/languages/motoko/fundamentals/actors-async.md rename to docs/languages/motoko/fundamentals/actors/actors-async.md index ffa27a78..44813132 100644 --- a/docs/languages/motoko/fundamentals/actors-async.md +++ b/docs/languages/motoko/fundamentals/actors/actors-async.md @@ -4,7 +4,7 @@ description: "Motoko language documentation" title: "Actors & async data" --- -The actor programming model was designed to solve concurrency issues by encapsulating [state](/languages/motoko/fundamentals/state) and computation within independent units called **actors**. +The actor programming model was designed to solve concurrency issues by encapsulating [state](/languages/motoko/fundamentals/actors/state) and computation within independent units called **actors**. The actor model is built on four key principles: @@ -257,7 +257,7 @@ In other languages without these features, developers often need to use advanced To demonstrate how asynchronous actors work, consider the following example. -Customers place orders at a pizza restaurant, but the chef can only make one pizza at a time. Orders are taken **[asynchronously](/languages/motoko/fundamentals/actors-async#async--await)**, meaning customers do not have to wait for previous orders to be completed before placing their own. However, each pizza is prepared sequentially. This is representative of an asynchronous actor. +Customers place orders at a pizza restaurant, but the chef can only make one pizza at a time. Orders are taken **[asynchronously](/languages/motoko/fundamentals/actors/actors-async#async--await)**, meaning customers do not have to wait for previous orders to be completed before placing their own. However, each pizza is prepared sequentially. This is representative of an asynchronous actor. ```motoko no-repl import Array "mo:core/Array"; diff --git a/docs/languages/motoko/fundamentals/compatibility.md b/docs/languages/motoko/fundamentals/actors/compatibility.md similarity index 95% rename from docs/languages/motoko/fundamentals/compatibility.md rename to docs/languages/motoko/fundamentals/actors/compatibility.md index d8a4b0a7..5444dac1 100644 --- a/docs/languages/motoko/fundamentals/compatibility.md +++ b/docs/languages/motoko/fundamentals/actors/compatibility.md @@ -12,7 +12,7 @@ When upgrading a canister, it is important to verify that the upgrade can procee - Breaking clients due to a Candid interface change. `dfx` checks these properties statically before attempting the upgrade. -Moreover, with [enhanced orthogonal persistence](/languages/motoko/fundamentals/orthogonal-persistence-enhanced), Motoko rejects incompatible changes of stable declarations. +Moreover, with [enhanced orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced), Motoko rejects incompatible changes of stable declarations. ## Upgrade example @@ -231,7 +231,7 @@ This version is neither compatible to stable type declarations, nor to the Candi - The change in the return type of `read` is also not safe. If the change were accepted, then existing clients of the `read` method, that still expect to receive integers, would suddenly start receiving incompatible floats. -With [enhanced orthogonal persistence](/languages/motoko/fundamentals/orthogonal-persistence-enhanced), Motoko actively rejects any upgrades that require type-incompatible state changes. +With [enhanced orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced), Motoko actively rejects any upgrades that require type-incompatible state changes. This is to guarantee that the stable state is always kept safe. @@ -244,7 +244,7 @@ In addition to Motoko's runtime check, `dfx` raises a warning message for these Motoko tolerates Candid interface changes, since these are more likely to be intentional, breaking changes. :::danger -Versions of Motoko using [classical orthogonal persistence](/languages/motoko/fundamentals/orthogonal-persistence-classical) will drop the state and reinitialize the counter with `0.0`, if the `dfx` warning is ignored. +Versions of Motoko using [classical orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/classical) will drop the state and reinitialize the counter with `0.0`, if the `dfx` warning is ignored. For this reason, users should always heed any compatibility warnings issued by `dfx`. ::: @@ -532,7 +532,7 @@ The migration function can be deleted or adjusted on the next upgrade. ## Enhanced stable signatures -When using [enhanced multi-migration](/languages/motoko/fundamentals/enhanced-multi-migration), the compiler produces an **enhanced stable signature** that records the entire migration chain alongside the actor's final stable fields. This extended signature enables the tooling to verify upgrade compatibility across the full history of migrations. +When using [enhanced multi-migration](/languages/motoko/fundamentals/actors/enhanced-multi-migration), the compiler produces an **enhanced stable signature** that records the entire migration chain alongside the actor's final stable fields. This extended signature enables the tooling to verify upgrade compatibility across the full history of migrations. ### Stable signature versions @@ -668,10 +668,10 @@ cannot be consumed at new type var Float ``` -With [enhanced orthogonal persistence](/languages/motoko/fundamentals/orthogonal-persistence-enhanced), compatibility errors of stable variables are always detected in the runtime system and if failing, the upgrade is safely rolled back. +With [enhanced orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced), compatibility errors of stable variables are always detected in the runtime system and if failing, the upgrade is safely rolled back. :::danger -With [classical orthogonal persistence](/languages/motoko/fundamentals/orthogonal-persistence-classical), however, an upgrade attempt from `v2.wasm` to `v3.wasm` is unpredictable and may lead to partial or complete data loss if the `dfx` warning is ignored. +With [classical orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/classical), however, an upgrade attempt from `v2.wasm` to `v3.wasm` is unpredictable and may lead to partial or complete data loss if the `dfx` warning is ignored. ::: ## Adding record fields @@ -718,8 +718,8 @@ cannot be consumed at new type Do you want to proceed? yes/No ``` -It is recommended not to continue, as you will lose the state in older versions of Motoko that use [classical orthogonal persistence](/languages/motoko/fundamentals/orthogonal-persistence-classical). -Upgrading with [enhanced orthogonal persistence](/languages/motoko/fundamentals/orthogonal-persistence-enhanced) will trap and roll back, keeping the old state. +It is recommended not to continue, as you will lose the state in older versions of Motoko that use [classical orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/classical). +Upgrading with [enhanced orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced) will trap and roll back, keeping the old state. Adding a new record field to the type of existing stable variable is not supported. The reason is simple: the upgrade would need to supply values for the new field out of thin air. In this example, the upgrade would need to conjure up some value for the `description` field of every existing `card` in `map`. Moreover, allowing adding optional fields is also a problem, as a record can be shared from various variables with different static types, some of them already declaring the added field or adding a same-named optional field with a potentially different type (and/or different semantics). diff --git a/docs/languages/motoko/fundamentals/data-persistence.md b/docs/languages/motoko/fundamentals/actors/data-persistence.md similarity index 95% rename from docs/languages/motoko/fundamentals/data-persistence.md rename to docs/languages/motoko/fundamentals/actors/data-persistence.md index 4c76933e..a56b0f1b 100644 --- a/docs/languages/motoko/fundamentals/data-persistence.md +++ b/docs/languages/motoko/fundamentals/actors/data-persistence.md @@ -156,7 +156,7 @@ When upgrading a canister, it is important to verify that the upgrade can procee - Introducing an incompatible change in stable declarations. - Breaking clients due to a Candid interface change. -With [enhanced orthogonal persistence](/languages/motoko/fundamentals/orthogonal-persistence-enhanced), Motoko rejects incompatible changes of stable declarations during an upgrade attempt. +With [enhanced orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced), Motoko rejects incompatible changes of stable declarations during an upgrade attempt. Moreover, `dfx` checks the two conditions before attempting the upgrade and warns users as necessary. A Motoko canister upgrade is safe provided: @@ -165,7 +165,7 @@ A Motoko canister upgrade is safe provided: - The canister’s Motoko stable signature evolves to a stable-compatible one. :::danger -With [classical orthogonal persistence](/languages/motoko/fundamentals/orthogonal-persistence-classical), the upgrade can still fail due to resource constraints. This is problematic as the canister can then not be upgraded. It is therefore strongly advised to test the scalability of upgrades extensively. This does not apply to enhanced orthogonal persistence. +With [classical orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/classical), the upgrade can still fail due to resource constraints. This is problematic as the canister can then not be upgraded. It is therefore strongly advised to test the scalability of upgrades extensively. This does not apply to enhanced orthogonal persistence. ::: @@ -214,8 +214,8 @@ A cleaner, more maintainable solution, is to declare an explicit migration expre Both of these data migration paths are supported by static and dynamic checks that prevent data loss or corruption. A user may still lose data due to coding errors, so should tread carefully. -For more information, see the [example of explicit migration](/languages/motoko/fundamentals/compatibility#explicit-migration-using-a-migration-function) and the -reference material on [migration expressions](https://docs.motoko.org#migration-expressions). +For more information, see the [example of explicit migration](/languages/motoko/fundamentals/actors/compatibility#explicit-migration-using-a-migration-function) and the +reference material on [migration expressions](/languages/motoko/reference/language-manual#migration-expressions). ## Legacy features diff --git a/docs/languages/motoko/fundamentals/enhanced-multi-migration.md b/docs/languages/motoko/fundamentals/actors/enhanced-multi-migration.md similarity index 98% rename from docs/languages/motoko/fundamentals/enhanced-multi-migration.md rename to docs/languages/motoko/fundamentals/actors/enhanced-multi-migration.md index b4b03d0c..5ae4f468 100644 --- a/docs/languages/motoko/fundamentals/enhanced-multi-migration.md +++ b/docs/languages/motoko/fundamentals/actors/enhanced-multi-migration.md @@ -20,7 +20,7 @@ With enhanced multi-migration you: 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. :::note -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/compatibility#explicit-migration-using-a-migration-function). +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). ::: ## Getting started @@ -412,6 +412,6 @@ moc --enhanced-orthogonal-persistence \ ## See also -- [Data persistence](/languages/motoko/fundamentals/data-persistence) -- [Verifying upgrade compatibility](/languages/motoko/fundamentals/compatibility) -- [Enhanced orthogonal persistence](/languages/motoko/fundamentals/orthogonal-persistence-enhanced) +- [Data persistence](/languages/motoko/fundamentals/actors/data-persistence) +- [Verifying upgrade compatibility](/languages/motoko/fundamentals/actors/compatibility) +- [Enhanced orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced) diff --git a/docs/languages/motoko/fundamentals/messaging.md b/docs/languages/motoko/fundamentals/actors/messaging.md similarity index 94% rename from docs/languages/motoko/fundamentals/messaging.md rename to docs/languages/motoko/fundamentals/actors/messaging.md index beb32a13..c3c057bd 100644 --- a/docs/languages/motoko/fundamentals/messaging.md +++ b/docs/languages/motoko/fundamentals/actors/messaging.md @@ -4,7 +4,7 @@ description: "Motoko language documentation" title: "Messaging" --- -ICP enforces rules on when and how [canisters](https://internetcomputer.org/docs/building-apps/essentials/canisters) communicate. Motoko includes static (compile-time) messaging restrictions to help prevent certain execution errors. +ICP enforces rules on when and how [canisters](/concepts/canisters) communicate. Motoko includes static (compile-time) messaging restrictions to help prevent certain execution errors. For example, a canister cannot send messages during installation, which helps avoid errors during deployment. Query functions cannot send messages either, because they run locally and do not trigger updates. Additionally, shared functions cannot be called in a synchronous context since shared calls require asynchronous execution. diff --git a/docs/languages/motoko/fundamentals/mixins.md b/docs/languages/motoko/fundamentals/actors/mixins.md similarity index 100% rename from docs/languages/motoko/fundamentals/mixins.md rename to docs/languages/motoko/fundamentals/actors/mixins.md diff --git a/docs/languages/motoko/fundamentals/orthogonal-persistence-classical.md b/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/classical.md similarity index 90% rename from docs/languages/motoko/fundamentals/orthogonal-persistence-classical.md rename to docs/languages/motoko/fundamentals/actors/orthogonal-persistence/classical.md index 7120a17f..5d87d27b 100644 --- a/docs/languages/motoko/fundamentals/orthogonal-persistence-classical.md +++ b/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/classical.md @@ -17,10 +17,10 @@ Upon upgrade, the classical orthogonal persistence mechanism serializes all stab :::danger The above-mentioned issues can lead to a stuck canister that can no longer be upgraded. Therefore, it is absolutely necessary to thoroughly test how much data an upgrade of your application can handle and then conservatively limit the data held by that canister. -Moreover, it is ideal to have a backup plan to rescue data even if upgrades fail, e.g. by controller-privileged data query calls. Another option is to [snapshot](https://internetcomputer.org/docs/building-apps/canister-management/snapshots) the canister before attempting the upgrade. +Moreover, it is ideal to have a backup plan to rescue data even if upgrades fail, e.g. by controller-privileged data query calls. Another option is to [snapshot](/guides/canister-management/snapshots) the canister before attempting the upgrade. ::: -These issues are solved by [enhanced orthogonal persistence](/languages/motoko/fundamentals/orthogonal-persistence-enhanced). +These issues are solved by [enhanced orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced). :::note diff --git a/docs/languages/motoko/fundamentals/orthogonal-persistence-enhanced.md b/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced.md similarity index 94% rename from docs/languages/motoko/fundamentals/orthogonal-persistence-enhanced.md rename to docs/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced.md index 65d0943c..e1ff1312 100644 --- a/docs/languages/motoko/fundamentals/orthogonal-persistence-enhanced.md +++ b/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced.md @@ -19,8 +19,8 @@ Moreover, it is advised to have a backup possibility for rescuing data even when ::: :::note -[Classical orthogonal persistence](/languages/motoko/fundamentals/orthogonal-persistence-classical) with 32-bit main memory and Candid stabilization was the previous default compilation mode for `moc`. If necessary, it can be re-enabled with compiler flag `--legacy-persistence`. -See [orthogonal persistence modes](/languages/motoko/fundamentals/) for a comparison. +[Classical orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/classical) with 32-bit main memory and Candid stabilization was the previous default compilation mode for `moc`. If necessary, it can be re-enabled with compiler flag `--legacy-persistence`. +See [orthogonal persistence modes](/languages/motoko/orthogonal-persistence/) for a comparison. ::: ## Design @@ -53,7 +53,7 @@ Compatible changes for immutable types are largely analogous to the allowed Moto The runtime system checks migration compatibility on upgrade, and if not fulfilled, rolls back the upgrade. This compatibility check serves as an additional safety measure on top of the `dfx` warning that can be bypassed by users. -Any more complex change can be performed with programmatic instruction, see [explicit migration](/languages/motoko/fundamentals/data-persistence#explicit-migration). +Any more complex change can be performed with programmatic instruction, see [explicit migration](/languages/motoko/fundamentals/actors/data-persistence#explicit-migration). ### Migration path When migrating from the old serialization-based stabilization to the new persistent heap, the old data is deserialized one last time from stable memory and then placed in the new persistent heap layout. Once operating on the persistent heap, the system should prevent downgrade attempts to the old serialization-based persistence. diff --git a/docs/languages/motoko/fundamentals/state.md b/docs/languages/motoko/fundamentals/actors/state.md similarity index 100% rename from docs/languages/motoko/fundamentals/state.md rename to docs/languages/motoko/fundamentals/actors/state.md diff --git a/docs/languages/motoko/fundamentals/characters-text.md b/docs/languages/motoko/fundamentals/basic-syntax/characters-text.md similarity index 100% rename from docs/languages/motoko/fundamentals/characters-text.md rename to docs/languages/motoko/fundamentals/basic-syntax/characters-text.md diff --git a/docs/languages/motoko/fundamentals/comments.md b/docs/languages/motoko/fundamentals/basic-syntax/comments.md similarity index 92% rename from docs/languages/motoko/fundamentals/comments.md rename to docs/languages/motoko/fundamentals/basic-syntax/comments.md index b4d720dc..d2e8e038 100644 --- a/docs/languages/motoko/fundamentals/comments.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/comments.md @@ -44,7 +44,7 @@ Multi-line comments can be nested within each other. ## Resources -- [Comment style guide](https://docs.motoko.org#comments) +- [Comment style guide](/languages/motoko/reference/style-guide#comments) - [Generating Motoko documentation](https://docs.motoko.org) diff --git a/docs/languages/motoko/fundamentals/defining-an-actor.md b/docs/languages/motoko/fundamentals/basic-syntax/defining-an-actor.md similarity index 77% rename from docs/languages/motoko/fundamentals/defining-an-actor.md rename to docs/languages/motoko/fundamentals/basic-syntax/defining-an-actor.md index bbf03d2f..5410897d 100644 --- a/docs/languages/motoko/fundamentals/defining-an-actor.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/defining-an-actor.md @@ -5,9 +5,9 @@ title: "Defining an actor" hide_table_of_contents: true --- -In Motoko, an **actor** is a computational process with its own [state](/languages/motoko/fundamentals/state) and behavior. Actors are declared with the `actor` keyword. +In Motoko, an **actor** is a computational process with its own [state](/languages/motoko/fundamentals/actors/state) and behavior. Actors are declared with the `actor` keyword. -Unlike traditional functions or objects in other programming languages, actors operate independently and communicate via [asynchronous](/languages/motoko/fundamentals/actors-async#async--await) messaging. Each actor maintains its own message queue, enabling concurrent execution. +Unlike traditional functions or objects in other programming languages, actors operate independently and communicate via [asynchronous](/languages/motoko/fundamentals/actors/actors-async#async--await) messaging. Each actor maintains its own message queue, enabling concurrent execution. An actor's state is defined by its private variables, while its behavior is defined by the public functions it exposes to other actors. @@ -53,7 +53,7 @@ persistent actor Main { This code defines an actor that can be deployed on ICP. The actor is declared as `persistent` so that its state, `count`, will be preserved when the actor is upgraded. -Learn more about [persistence](/languages/motoko/fundamentals/data-persistence). +Learn more about [persistence](/languages/motoko/fundamentals/actors/data-persistence). ::: Another actor can call `Main.greet()` with an argument and await the result: @@ -62,7 +62,7 @@ Another actor can call `Main.greet()` with an argument and await the result: await Main.greet("Programmer"); ``` -A Motoko actor always presents its interface as a suite of named [functions](/languages/motoko/fundamentals/functions) (also called methods) with defined argument and return types. When Motoko code is compiled, this interface is automatically translated to [Candid](https://internetcomputer.org/docs/building-apps/interact-with-canisters/candid/candid-concepts), an interface description language. The Candid description can be consumed by other canisters, including canisters written in another language such as Rust. +A Motoko actor always presents its interface as a suite of named [functions](/languages/motoko/fundamentals/basic-syntax/functions) (also called methods) with defined argument and return types. When Motoko code is compiled, this interface is automatically translated to [Candid](/guides/canister-calls/candid), an interface description language. The Candid description can be consumed by other canisters, including canisters written in another language such as Rust. The above example's corresponding Candid interface can be found below. @@ -76,5 +76,5 @@ service : { ## Resources -- [Actors](/languages/motoko/fundamentals/actors-async) +- [Actors](/languages/motoko/fundamentals/actors/actors-async) diff --git a/docs/languages/motoko/fundamentals/basic-syntax/functions.md b/docs/languages/motoko/fundamentals/basic-syntax/functions.md new file mode 100644 index 00000000..a0bee145 --- /dev/null +++ b/docs/languages/motoko/fundamentals/basic-syntax/functions.md @@ -0,0 +1,86 @@ +--- +sidebar_position: 8 +description: "Motoko language documentation" +title: "Functions" +hide_table_of_contents: true +--- + +Functions in Motoko can have various attributes, the most fundamental being whether they are public or private. Public functions can be called by users or other [canisters](/concepts/canisters), while private functions are only accessible within the program that defines them. + +The most basic Motoko [function declaration](/languages/motoko/fundamentals/declarations/function-declarations) is: + +```motoko no-repl +func exampleFunction() : () {}; +``` + +In objects, modules, and actors, all functions are private by default unless explicitly declared as `public`. + +```motoko +object Counter { + var value = 0; + func reset() { value := 0 }; + public func inc() { value := 1}; + public func get() : Nat { value }; +} +``` + +The object `Counter` has two public methods, the functions `Counter.inc()` and `Counter.get()`. Both `value` and `reset()` are implicitly `private`. Any attempts to access `Counter.reset()` and `Counter.value` produce type errors. + +A function should specify a return type. If a return type is not declared or otherwise determined from the context, it defaults to the unit `()` return type. + +```motoko no-repl +func exampleFunction(x : Nat) : Nat { + x; +}; +``` + +:::note[Understanding function types] + +Motoko functions vary by access and behavior: + +The public functions of an actor are a special kind of function called shared functions. These functions can only be declared within actors and, unlike ordinary functions, their values can be sent to (i.e., shared with) other actors. +Shared functions come in several forms: + +- `shared` functions, which can modify an actor's state. + +- `shared query` functions, which can read the actor's state without making observable changes and cannot send further messages. + +- `shared composite query` functions, which behave like queries but can also call other queries. +All shared function, unlike ordinary functions, provide access to the identity of their caller, for applications like access control. + +[Learn more about function types](/languages/motoko/fundamentals/types/function-types). + +::: + +For example, you can rewrite the object above as an actor: + +``` motoko +persistent actor Digit { + var value = 0; + func reset() { value := 0 }; + public shared func inc() : async (){ + value += 1; + if (value == 10) reset(); + }; + public shared query func get() : async Nat { + value + }; +} +``` + +Since the public functions of an actor must be `shared`, you can omit the `shared` keyword: + +``` motoko +persistent actor Digit { + var value = 0; + func reset() { value := 0 }; + public func inc() : async () { + value += 1; + if (value == 10) reset(); + }; + public query func get() : async Nat { + value + }; +} +``` + diff --git a/docs/languages/motoko/fundamentals/identifiers.md b/docs/languages/motoko/fundamentals/basic-syntax/identifiers.md similarity index 78% rename from docs/languages/motoko/fundamentals/identifiers.md rename to docs/languages/motoko/fundamentals/basic-syntax/identifiers.md index d629a5ba..739e3cd2 100644 --- a/docs/languages/motoko/fundamentals/identifiers.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/identifiers.md @@ -16,4 +16,4 @@ let snake_case_identifier = "for compatibility with other languages"; ## Reserved syntax keywords -Motoko reserves [keywords](https://docs.motoko.org#keywords) for its syntax and they cannot be used as identifiers. +Motoko reserves [keywords](/languages/motoko/reference/language-manual#keywords) for its syntax and they cannot be used as identifiers. diff --git a/docs/languages/motoko/fundamentals/imports.md b/docs/languages/motoko/fundamentals/basic-syntax/imports.md similarity index 98% rename from docs/languages/motoko/fundamentals/imports.md rename to docs/languages/motoko/fundamentals/basic-syntax/imports.md index 1ba12221..c0cb12a7 100644 --- a/docs/languages/motoko/fundamentals/imports.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/imports.md @@ -48,4 +48,4 @@ import { compare } "mo:core/Nat"; import { type Result; mapOk } "mo:core/Result"; ``` -Learn more about [modules and imports](/languages/motoko/fundamentals/imports). +Learn more about [modules and imports](/languages/motoko/fundamentals/basic-syntax/imports). diff --git a/docs/languages/motoko/fundamentals/literals.md b/docs/languages/motoko/fundamentals/basic-syntax/literals.md similarity index 91% rename from docs/languages/motoko/fundamentals/literals.md rename to docs/languages/motoko/fundamentals/basic-syntax/literals.md index 6b7e4e60..eec4035c 100644 --- a/docs/languages/motoko/fundamentals/literals.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/literals.md @@ -25,5 +25,5 @@ You can use literals directly in expressions. ## Resources -- [Literals](https://docs.motoko.org#literals) +- [Literals](/languages/motoko/reference/language-manual#literals) diff --git a/docs/languages/motoko/fundamentals/numbers.md b/docs/languages/motoko/fundamentals/basic-syntax/numbers.md similarity index 100% rename from docs/languages/motoko/fundamentals/numbers.md rename to docs/languages/motoko/fundamentals/basic-syntax/numbers.md diff --git a/docs/languages/motoko/fundamentals/operators.md b/docs/languages/motoko/fundamentals/basic-syntax/operators.md similarity index 100% rename from docs/languages/motoko/fundamentals/operators.md rename to docs/languages/motoko/fundamentals/basic-syntax/operators.md diff --git a/docs/languages/motoko/fundamentals/printing-values.md b/docs/languages/motoko/fundamentals/basic-syntax/printing-values.md similarity index 84% rename from docs/languages/motoko/fundamentals/printing-values.md rename to docs/languages/motoko/fundamentals/basic-syntax/printing-values.md index d36e9e58..b59379e7 100644 --- a/docs/languages/motoko/fundamentals/printing-values.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/printing-values.md @@ -25,7 +25,7 @@ Debug.print(debug_show {life = 42} ); // "{life = 42}" Functions like `Debug.print("Hello, World!")` are considered **impure functions** because they cause a side effect by printing to the console or log. -In contrast, [**pure functions**](/languages/motoko/fundamentals/functions) return values that do not modify output or have other side effects like sending messages. For example `Nat.toText(42)` is pure because it always returns `"42"` with no other effect. +In contrast, [**pure functions**](/languages/motoko/fundamentals/types/function-types) return values that do not modify output or have other side effects like sending messages. For example `Nat.toText(42)` is pure because it always returns `"42"` with no other effect. ## Resources diff --git a/docs/languages/motoko/fundamentals/traps.md b/docs/languages/motoko/fundamentals/basic-syntax/traps.md similarity index 100% rename from docs/languages/motoko/fundamentals/traps.md rename to docs/languages/motoko/fundamentals/basic-syntax/traps.md diff --git a/docs/languages/motoko/fundamentals/whitespace.md b/docs/languages/motoko/fundamentals/basic-syntax/whitespace.md similarity index 90% rename from docs/languages/motoko/fundamentals/whitespace.md rename to docs/languages/motoko/fundamentals/basic-syntax/whitespace.md index 7a60a39b..0e0ade53 100644 --- a/docs/languages/motoko/fundamentals/whitespace.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/whitespace.md @@ -25,5 +25,5 @@ persistent actor Counter { ## Resources -- [Motoko style guide](https://docs.motoko.org) +- [Motoko style guide](/languages/motoko/reference/style-guide) diff --git a/docs/languages/motoko/fundamentals/contextual-dot.md b/docs/languages/motoko/fundamentals/contextual-dot.md index 587ac851..fd0b0437 100644 --- a/docs/languages/motoko/fundamentals/contextual-dot.md +++ b/docs/languages/motoko/fundamentals/contextual-dot.md @@ -162,4 +162,4 @@ Contextual dot notation has some intentional limitations: ## See also - [Modules and imports](modules-imports) -- [Language reference](https://docs.motoko.org#dotted-function-calls) \ No newline at end of file +- [Language reference](/languages/motoko/reference/language-manual#dotted-function-calls) \ No newline at end of file diff --git a/docs/languages/motoko/fundamentals/basic-control-flow.md b/docs/languages/motoko/fundamentals/control-flow/basic-control-flow.md similarity index 96% rename from docs/languages/motoko/fundamentals/basic-control-flow.md rename to docs/languages/motoko/fundamentals/control-flow/basic-control-flow.md index bb8c2adb..e8b852e4 100644 --- a/docs/languages/motoko/fundamentals/basic-control-flow.md +++ b/docs/languages/motoko/fundamentals/control-flow/basic-control-flow.md @@ -134,7 +134,7 @@ let o4 = addOpt(null, null); // null Instead of having to switch on the options `n` and `m` in a verbose manner the use of the postfix operator `!` makes it easy to unwrap their values but exit the block with `null` when either is `null`. -A more interesting example of option blocks can be found at the end of the section on [switch](/languages/motoko/fundamentals/switch). +A more interesting example of option blocks can be found at the end of the section on [switch](/languages/motoko/fundamentals/control-flow/switch). ## `label` and `break` @@ -278,7 +278,7 @@ You can also exit any loop in a function using `return` or (in an asynchronous f ## Function calls -A function call executes a function by passing arguments and receiving a result. In Motoko, function calls can be synchronous (executing immediately within the same [canister](https://internetcomputer.org/docs/building-apps/essentials/canisters)) or [asynchronous](/languages/motoko/fundamentals/actors-async#async--await) (message passing between canisters). Asynchronous calls use `async`/`await` and are essential for inter-canister communication. +A function call executes a function by passing arguments and receiving a result. In Motoko, function calls can be synchronous (executing immediately within the same [canister](/concepts/canisters)) or [asynchronous](/languages/motoko/fundamentals/actors/actors-async#async--await) (message passing between canisters). Asynchronous calls use `async`/`await` and are essential for inter-canister communication. ```motoko no-repl persistent actor { diff --git a/docs/languages/motoko/fundamentals/blocks.md b/docs/languages/motoko/fundamentals/control-flow/blocks.md similarity index 100% rename from docs/languages/motoko/fundamentals/blocks.md rename to docs/languages/motoko/fundamentals/control-flow/blocks.md diff --git a/docs/languages/motoko/fundamentals/conditionals.md b/docs/languages/motoko/fundamentals/control-flow/conditionals.md similarity index 100% rename from docs/languages/motoko/fundamentals/conditionals.md rename to docs/languages/motoko/fundamentals/control-flow/conditionals.md diff --git a/docs/languages/motoko/fundamentals/loops.md b/docs/languages/motoko/fundamentals/control-flow/loops.md similarity index 100% rename from docs/languages/motoko/fundamentals/loops.md rename to docs/languages/motoko/fundamentals/control-flow/loops.md diff --git a/docs/languages/motoko/fundamentals/switch.md b/docs/languages/motoko/fundamentals/control-flow/switch.md similarity index 100% rename from docs/languages/motoko/fundamentals/switch.md rename to docs/languages/motoko/fundamentals/control-flow/switch.md diff --git a/docs/languages/motoko/fundamentals/class-declarations.md b/docs/languages/motoko/fundamentals/declarations/class-declarations.md similarity index 91% rename from docs/languages/motoko/fundamentals/class-declarations.md rename to docs/languages/motoko/fundamentals/declarations/class-declarations.md index 094bfd29..72f04a4e 100644 --- a/docs/languages/motoko/fundamentals/class-declarations.md +++ b/docs/languages/motoko/fundamentals/declarations/class-declarations.md @@ -4,7 +4,7 @@ description: "Motoko language documentation" title: "Class declarations" --- -A class in Motoko serves as a blueprint for creating [objects](/languages/motoko/fundamentals/object-declaration) that encapsulate both [state](/languages/motoko/fundamentals/state) and behavior. It defines fields to hold data and methods to operate on that data. Unlike records and plain objects, classes support constructors, allowing developers to initialize each instance with unique values at creation time. +A class in Motoko serves as a blueprint for creating [objects](/languages/motoko/fundamentals/declarations/object-declaration) that encapsulate both [state](/languages/motoko/fundamentals/actors/state) and behavior. It defines fields to hold data and methods to operate on that data. Unlike records and plain objects, classes support constructors, allowing developers to initialize each instance with unique values at creation time. Classes in Motoko are not the same as classes in other object oriented programming languages, but they serve the same purpose. Motoko also doesn’t have a `this` or `self` keyword because you can simply call other methods directly by name or name the entire object using an identifier of your choice. @@ -165,5 +165,5 @@ Using this `system` syntax, developers can: - Manually install, upgrade, or reinstall canisters. - Access lower-level canister management features provided by ICP. -[Learn more about actor class management](https://docs.motoko.org#actor-class-management). +[Learn more about actor class management](/languages/motoko/reference/language-manual#actor-class-management). diff --git a/docs/languages/motoko/fundamentals/expression-declarations.md b/docs/languages/motoko/fundamentals/declarations/expression-declarations.md similarity index 98% rename from docs/languages/motoko/fundamentals/expression-declarations.md rename to docs/languages/motoko/fundamentals/declarations/expression-declarations.md index 3796e1c1..7e82f078 100644 --- a/docs/languages/motoko/fundamentals/expression-declarations.md +++ b/docs/languages/motoko/fundamentals/declarations/expression-declarations.md @@ -31,7 +31,7 @@ In Motoko, expressions of type `()` play the role of statements in other languag ## Basic usage -Expression declarations are commonly used for functions or operations that produce side effects, such as printing or modifying [state](/languages/motoko/fundamentals/state). +Expression declarations are commonly used for functions or operations that produce side effects, such as printing or modifying [state](/languages/motoko/fundamentals/actors/state). ```motoko no-repl Debug.print("Hello, Motoko!"); diff --git a/docs/languages/motoko/fundamentals/function-declarations.md b/docs/languages/motoko/fundamentals/declarations/function-declarations.md similarity index 96% rename from docs/languages/motoko/fundamentals/function-declarations.md rename to docs/languages/motoko/fundamentals/declarations/function-declarations.md index e718b186..0255de7e 100644 --- a/docs/languages/motoko/fundamentals/function-declarations.md +++ b/docs/languages/motoko/fundamentals/declarations/function-declarations.md @@ -98,7 +98,7 @@ assert echoTwice("Hello") == "Hello!!"; ## Shared functions in actors -In actors, functions can be marked as `shared` to allow [asynchronous](/languages/motoko/fundamentals/actors-async#async--await) [inter-canister](https://internetcomputer.org/docs/references/async-code) communication. +In actors, functions can be marked as `shared` to allow [asynchronous](/languages/motoko/fundamentals/actors/actors-async#async--await) [inter-canister](/references/message-execution-properties) communication. ```motoko no-repl actor Counter { diff --git a/docs/languages/motoko/fundamentals/module-declarations.md b/docs/languages/motoko/fundamentals/declarations/module-declarations.md similarity index 100% rename from docs/languages/motoko/fundamentals/module-declarations.md rename to docs/languages/motoko/fundamentals/declarations/module-declarations.md diff --git a/docs/languages/motoko/fundamentals/object-declaration.md b/docs/languages/motoko/fundamentals/declarations/object-declaration.md similarity index 95% rename from docs/languages/motoko/fundamentals/object-declaration.md rename to docs/languages/motoko/fundamentals/declarations/object-declaration.md index 1a3324ad..ac82e228 100644 --- a/docs/languages/motoko/fundamentals/object-declaration.md +++ b/docs/languages/motoko/fundamentals/declarations/object-declaration.md @@ -8,7 +8,7 @@ In Motoko, records and objects are both used to group related values using named While records expressions are ideal for lightweight data representation, objects expressions are more verbose. Object expressions can define full objects in the sense of object-oriented programming where an object is a collection of named fields and methods acting on private state. In Motoko, the private declarations define the encapsulated state, while the public definitions define the object's visible members. -Record and object both use the `var` keyword to define [mutable](/languages/motoko/fundamentals/variable-declarations) and declarations. Both records and objects support `and` and `with` for merging and updating object fields to create new records and objects. +Record and object both use the `var` keyword to define [mutable](/languages/motoko/fundamentals/declarations/variable-declarations) and declarations. Both records and objects support `and` and `with` for merging and updating object fields to create new records and objects. **Record expressions** are used to construct simple data structures that consist of named fields holding values. The fields can be mutable or immutable. The fields of a record cannot refer to each other by name and are mainly used to store plain data, like the records in a database. diff --git a/docs/languages/motoko/fundamentals/type-declarations.md b/docs/languages/motoko/fundamentals/declarations/type-declarations.md similarity index 93% rename from docs/languages/motoko/fundamentals/type-declarations.md rename to docs/languages/motoko/fundamentals/declarations/type-declarations.md index 1db09f7d..528e11a8 100644 --- a/docs/languages/motoko/fundamentals/type-declarations.md +++ b/docs/languages/motoko/fundamentals/declarations/type-declarations.md @@ -42,7 +42,7 @@ Structural typing means that the types `User` and `Person` are interchangeable b ## Record types -In Motoko, a type can define a structured [record](/languages/motoko/fundamentals/records) with labeled fields. Each field has a specific type, and you can access them using dot notation. Records are useful for organizing related data clearly and safely. +In Motoko, a type can define a structured [record](/languages/motoko/fundamentals/types/records) with labeled fields. Each field has a specific type, and you can access them using dot notation. Records are useful for organizing related data clearly and safely. ```motoko no-repl // A reusable record @@ -145,8 +145,8 @@ type Seq = ?(T, Seq<[T]>); ## Resources -- [`Record`](/languages/motoko/fundamentals/records) -- [`Variant`](/languages/motoko/fundamentals/variants) +- [`Record`](/languages/motoko/fundamentals/types/records) +- [`Variant`](/languages/motoko/fundamentals/types/variants) diff --git a/docs/languages/motoko/fundamentals/variable-declarations.md b/docs/languages/motoko/fundamentals/declarations/variable-declarations.md similarity index 100% rename from docs/languages/motoko/fundamentals/variable-declarations.md rename to docs/languages/motoko/fundamentals/declarations/variable-declarations.md diff --git a/docs/languages/motoko/fundamentals/error-handling.md b/docs/languages/motoko/fundamentals/error-handling.md index 4905e655..306017c2 100644 --- a/docs/languages/motoko/fundamentals/error-handling.md +++ b/docs/languages/motoko/fundamentals/error-handling.md @@ -177,7 +177,7 @@ try { ## Traps -Traps immediately stop execution and roll back [state](/languages/motoko/fundamentals/state). They are used for fatal errors that cannot be recovered. +Traps immediately stop execution and roll back [state](/languages/motoko/fundamentals/actors/state). They are used for fatal errors that cannot be recovered. ```motoko no-repl import Runtime "mo:core/Runtime"; diff --git a/docs/languages/motoko/fundamentals/hello-world.md b/docs/languages/motoko/fundamentals/hello-world.md index 4023021c..2576ae72 100644 --- a/docs/languages/motoko/fundamentals/hello-world.md +++ b/docs/languages/motoko/fundamentals/hello-world.md @@ -29,12 +29,12 @@ persistent actor HelloWorld { In this example: -1. The code begins by defining an [actor](/languages/motoko/fundamentals/actors-async) named `HelloWorld`. In Motoko, an actor is an object capable of maintaining state and communicating with other entities via message passing. +1. The code begins by defining an [actor](/languages/motoko/fundamentals/actors/actors-async) named `HelloWorld`. In Motoko, an actor is an object capable of maintaining state and communicating with other entities via message passing. -2. It then declares the variable `greeting`. This is a [stable variable](/languages/motoko/fundamentals/stable-types) because the actor is declared with the keyword `persistent`. Stable variables are used to store data that persists across canister upgrades. [Read more about canister upgrades.](https://internetcomputer.org/docs/building-apps/canister-management/upgrade) +2. It then declares the variable `greeting`. This is a [stable variable](/languages/motoko/fundamentals/types/stable-types) because the actor is declared with the keyword `persistent`. Stable variables are used to store data that persists across canister upgrades. [Read more about canister upgrades.](/guides/canister-management/lifecycle) -3. An [update method](https://internetcomputer.org/docs/building-apps/interact-with-canisters/update-calls) named `setGreeting` is used to modify the canister’s state. This method specifically updates the value stored in `greeting`. +3. An [update method](/concepts/canisters) named `setGreeting` is used to modify the canister’s state. This method specifically updates the value stored in `greeting`. -4. Finally, a [query method](https://internetcomputer.org/docs/building-apps/interact-with-canisters/query-calls) named `greet` is defined. Query methods are read-only and return information from the canister without changing its state. This method returns the current `greeting` value, followed by the input text. The method body produces a response by concatenating `"Hello, "` with the input `name`, followed by an exclamation point. +4. Finally, a [query method](/concepts/canisters) named `greet` is defined. Query methods are read-only and return information from the canister without changing its state. This method returns the current `greeting` value, followed by the input text. The method body produces a response by concatenating `"Hello, "` with the input `name`, followed by an exclamation point. -[Learn more about actors and basic syntax](/languages/motoko/fundamentals/defining-an-actor). \ No newline at end of file +[Learn more about actors and basic syntax](/languages/motoko/fundamentals/basic-syntax/defining-an-actor). \ No newline at end of file diff --git a/docs/languages/motoko/fundamentals/implicit-parameters.md b/docs/languages/motoko/fundamentals/implicit-parameters.md index 0e413c4f..98e4e6b2 100644 --- a/docs/languages/motoko/fundamentals/implicit-parameters.md +++ b/docs/languages/motoko/fundamentals/implicit-parameters.md @@ -282,4 +282,4 @@ Implicit arguments have no runtime overhead. The comparison function is resolved ## See also -- [Language reference](https://docs.motoko.org#function-calls) +- [Language reference](/languages/motoko/reference/language-manual#function-calls) diff --git a/docs/languages/motoko/fundamentals/modules-imports.md b/docs/languages/motoko/fundamentals/modules-imports.md index f9e12ae2..33fb18b9 100644 --- a/docs/languages/motoko/fundamentals/modules-imports.md +++ b/docs/languages/motoko/fundamentals/modules-imports.md @@ -110,7 +110,7 @@ import PureList "mo:core/pure/List"; ## Importing from another canister -Actors and their functions can be imported from other [canisters](https://internetcomputer.org/docs/building-apps/essentials/canisters) using the `canister:` prefix. +Actors and their functions can be imported from other [canisters](/concepts/canisters) using the `canister:` prefix. ```motoko no-repl import BigMap "canister:BigMap"; @@ -146,7 +146,7 @@ When importing from another canister, the canister must be listed as a dependenc ## Importing actor classes -When imported, an [actor](/languages/motoko/fundamentals/actors-async) class provides a type definition describing the class interface and a function that returns an instance of the class. +When imported, an [actor](/languages/motoko/fundamentals/actors/actors-async) class provides a type definition describing the class interface and a function that returns an instance of the class. For example, if you define the following actor class: @@ -183,7 +183,7 @@ persistent actor CountToTen { }; ``` -`Counters.Counter(1)` installs a new counter on the network. Installation is [asynchronous](/languages/motoko/fundamentals/actors-async#async--await), so the result is awaited. If the actor class is not named, it will result in a bad import error because actor class imports cannot be anonymous. +`Counters.Counter(1)` installs a new counter on the network. Installation is [asynchronous](/languages/motoko/fundamentals/actors/actors-async#async--await), so the result is awaited. If the actor class is not named, it will result in a bad import error because actor class imports cannot be anonymous. ## Importing `Blob` values diff --git a/docs/languages/motoko/fundamentals/advanced-types.md b/docs/languages/motoko/fundamentals/types/advanced-types.md similarity index 95% rename from docs/languages/motoko/fundamentals/advanced-types.md rename to docs/languages/motoko/fundamentals/types/advanced-types.md index b52b7cbe..47aa3982 100644 --- a/docs/languages/motoko/fundamentals/advanced-types.md +++ b/docs/languages/motoko/fundamentals/types/advanced-types.md @@ -8,7 +8,7 @@ Advanced type features enable more flexible and expressive type definitions, inc ## Structural equality -Structural equality determines whether two values are equal based on their contents. This applies to immutable data structures, such as [records](/languages/motoko/fundamentals/records) and [variants](/languages/motoko/fundamentals/variants), but does not apply to mutable structures for safety reasons. +Structural equality determines whether two values are equal based on their contents. This applies to immutable data structures, such as [records](/languages/motoko/fundamentals/types/records) and [variants](/languages/motoko/fundamentals/types/variants), but does not apply to mutable structures for safety reasons. ```motoko type Point = { x : Int; y : Int }; @@ -34,7 +34,7 @@ p1 == p2; // true (structural equality at type `Point`) ## Generic types -Generic types are used to define type parameters that work with multiple data types, commonly used in [functions](/languages/motoko/fundamentals/functions), [classes](/languages/motoko/fundamentals/objects-classes), and data structures. +Generic types are used to define type parameters that work with multiple data types, commonly used in [functions](/languages/motoko/fundamentals/types/function-types), [classes](/languages/motoko/fundamentals/types/objects-classes), and data structures. ```motoko // Generic function @@ -180,7 +180,7 @@ let ghost = { name = "Motoko"; age = 30 }; printName(ghost); // Allowed since 'ghost' has a 'name' field. ``` -In the example above, `T <: { name : Text }` requires that any type used for `T` must be a subtype of the [record](/languages/motoko/fundamentals/records) `{ name : Text }`, that is, it must have at least a `name` field of type [`Text`](https://mops.one/core/docs/Text). Extra fields are permitted, but the `name` field is mandatory. +In the example above, `T <: { name : Text }` requires that any type used for `T` must be a subtype of the [record](/languages/motoko/fundamentals/types/records) `{ name : Text }`, that is, it must have at least a `name` field of type [`Text`](https://mops.one/core/docs/Text). Extra fields are permitted, but the `name` field is mandatory. Type bounds are not limited to records. In general, the notation `T <: A` in a parameter declaration mandates that any type provided for type parameter `T` must be a subtype of the specified type `A`. diff --git a/docs/languages/motoko/fundamentals/functions.md b/docs/languages/motoko/fundamentals/types/function-types.md similarity index 88% rename from docs/languages/motoko/fundamentals/functions.md rename to docs/languages/motoko/fundamentals/types/function-types.md index 24fd9825..2d2fdb0d 100644 --- a/docs/languages/motoko/fundamentals/functions.md +++ b/docs/languages/motoko/fundamentals/types/function-types.md @@ -16,7 +16,7 @@ Motoko offers different types of functions, each with distinct capabilities: - **Local functions**, declared using the `func` keyword, are typically synchronous but can be asynchronous if their body contains an `async` expression. A local function is only available within the actor that defines it; it cannot be called from another actor or sent to another actor in a message. -- **Shared functions**, declared using the `shared`, `shared query`, or `shared composite query` keywords, are asynchronous by nature. Calling a shared function sends a message to another actor. The caller is typically another Motoko actor, a [canister](https://internetcomputer.org/docs/building-apps/essentials/canisters), or an [agent](https://internetcomputer.org/docs/building-apps/interact-with-canisters/agents/overview). +- **Shared functions**, declared using the `shared`, `shared query`, or `shared composite query` keywords, are asynchronous by nature. Calling a shared function sends a message to another actor. The caller is typically another Motoko actor, a [canister](/concepts/canisters), or an [agent](/guides/canister-calls/calling-from-clients). An actor's shared functions are always called as the result of the actor receiving some message. Shared functions that return a result have `async` return types. @@ -29,12 +29,12 @@ Motoko provides different types of functions based on where in the program they | Keyword | Function | |-------------|--------------| | `shared` | Used to enable async communication between actors. Exposes the caller’s identity. | -| `async` | Runs the function [asynchronously](/languages/motoko/fundamentals/actors-async#async--await) and returns its result in a future. | -| `query` | Optimized for reading data but cannot modify [state](/languages/motoko/fundamentals/state). | +| `async` | Runs the function [asynchronously](/languages/motoko/fundamentals/actors/actors-async#async--await) and returns its result in a future. | +| `query` | Optimized for reading data but cannot modify [state](/languages/motoko/fundamentals/actors/state). | ## Function comparison -| Function type | Mutates [state](/languages/motoko/fundamentals/state) | Calls updates | Calls queries | Asynchronous | External calls | +| Function type | Mutates [state](/languages/motoko/fundamentals/actors/state) | Calls updates | Calls queries | Asynchronous | External calls | |------------------------------|---------------|------------------|------------------|---------------|---------------| | Local (synchronous) | Yes | No | No | No | No | | Local (asynchronous) | Yes | Yes | Yes | Yes | No | @@ -44,7 +44,7 @@ Motoko provides different types of functions based on where in the program they ## Local functions -Local functions run within the canister's [actor](/languages/motoko/fundamentals/actors-async). They cannot call other [canisters](https://internetcomputer.org/docs/building-apps/essentials/canisters). Local functions are cheap to call and execute synchronously. +Local functions run within the canister's [actor](/languages/motoko/fundamentals/actors/actors-async). They cannot call other [canisters](/concepts/canisters). Local functions are cheap to call and execute synchronously. ```motoko persistent actor CommonDivisor{ @@ -173,7 +173,7 @@ The second call increments the balance from `50` to `100`, returning `100`. Since `Account.deposit` is asynchronous, its results are returned in futures of type `async Nat`. Calling `await` on each future extracts the results of the calls when they become available (so `b1` is `50` and `b2` is `100`). -**Example use case**: Transactions, user [state](/languages/motoko/fundamentals/state) updates, or anything that modifies persistent data. +**Example use case**: Transactions, user [state](/languages/motoko/fundamentals/actors/state) updates, or anything that modifies persistent data. ### One-way functions @@ -204,7 +204,7 @@ Again, the shared keyword is optional. Note that `Account.credit(100` just retur ## Query functions -[Query](https://internetcomputer.org/docs/building-apps/interact-with-canisters/query-calls) functions are designed for retrieving data. They cannot permanently update [state](/languages/motoko/fundamentals/state) and execute faster than [update](https://internetcomputer.org/docs/building-apps/interact-with-canisters/update-calls) functions because they do not go through consensus. Query functions are identified with the `query` keyword. Any function without the `query` keyword is an [update](https://internetcomputer.org/docs/building-apps/interact-with-canisters/update-calls) function. +[Query](/concepts/canisters) functions are designed for retrieving data. They cannot permanently update [state](/languages/motoko/fundamentals/actors/state) and execute faster than [update](/concepts/canisters) functions because they do not go through consensus. Query functions are identified with the `query` keyword. Any function without the `query` keyword is an [update](/concepts/canisters) function. ```motoko no-repl public query func greet(name : Text) : async Text { @@ -236,11 +236,11 @@ persistent actor Account { The `getBalance` function has function type `shared query () -> async Nat`. -**Example use case:** Fetching data quickly without modifying the canister [state](/languages/motoko/fundamentals/state). +**Example use case:** Fetching data quickly without modifying the canister [state](/languages/motoko/fundamentals/actors/state). ### Composite queries -[Composite queries](https://internetcomputer.org/docs/building-apps/interact-with-canisters/query-calls#composite-queries) chain multiple query calls together within the same function. +[Composite queries](/concepts/canisters#composite-queries) chain multiple query calls together within the same function. A good example of a composite query might be a bank that holds references to its individual accounts, implemented as separate actors, and provides a composite query that sums the deposits in all its accounts: @@ -305,7 +305,7 @@ Functions can accept multiple arguments and return multiple results by enclosing ### Using a record as an argument -Multiple values can be passed as a single argument by encapsulating them within a [record](/languages/motoko/fundamentals/records) type. +Multiple values can be passed as a single argument by encapsulating them within a [record](/languages/motoko/fundamentals/types/records) type. ```motoko no-repl func userName(user: { name : Text; age : Nat }) : Text { diff --git a/docs/languages/motoko/fundamentals/immutable-arrays.md b/docs/languages/motoko/fundamentals/types/immutable-arrays.md similarity index 90% rename from docs/languages/motoko/fundamentals/immutable-arrays.md rename to docs/languages/motoko/fundamentals/types/immutable-arrays.md index 87eab412..7366bdc4 100644 --- a/docs/languages/motoko/fundamentals/immutable-arrays.md +++ b/docs/languages/motoko/fundamentals/types/immutable-arrays.md @@ -4,7 +4,7 @@ description: "Motoko language documentation" title: "Immutable arrays" --- -Immutable arrays are fixed-size, read-only data structures that allow efficiently storing elements of the same type. Unlike [mutable arrays](/languages/motoko/fundamentals/mutable-arrays), they cannot be modified after creation, ensuring data integrity and predictable behavior. +Immutable arrays are fixed-size, read-only data structures that allow efficiently storing elements of the same type. Unlike [mutable arrays](/languages/motoko/fundamentals/types/mutable-arrays), they cannot be modified after creation, ensuring data integrity and predictable behavior. ## When to use immutable arrays @@ -30,7 +30,7 @@ The size of an array `a` is available as `a.size()`, a `Nat`. Array elements are zero-indexed, allowing indices `0` up to `a.size() - 1`. -Attempting to access an array's index that does not exist will cause a [trap](/languages/motoko/fundamentals/traps). Attempting to modify an immutable array will result in an error `expected mutable assignment target(M0073)`. +Attempting to access an array's index that does not exist will cause a [trap](/languages/motoko/fundamentals/basic-syntax/traps). Attempting to modify an immutable array will result in an error `expected mutable assignment target(M0073)`. ```motoko import Debug "mo:core/Debug"; @@ -148,7 +148,7 @@ transformArray(); To demonstrate nested immutable arrays, consider the following: -A chessboard is a fixed `8×8` grid. Using immutable arrays to represent the initial [state](/languages/motoko/fundamentals/state) of the board ensures that the setup remains unchanged, preventing accidental modifications. This is useful because the starting position of pieces in chess is fixed, and any changes should be intentional, such as when making a move. Immutable arrays provide stability and help maintain the integrity of the initial board [state](/languages/motoko/fundamentals/state). +A chessboard is a fixed `8×8` grid. Using immutable arrays to represent the initial [state](/languages/motoko/fundamentals/actors/state) of the board ensures that the setup remains unchanged, preventing accidental modifications. This is useful because the starting position of pieces in chess is fixed, and any changes should be intentional, such as when making a move. Immutable arrays provide stability and help maintain the integrity of the initial board [state](/languages/motoko/fundamentals/actors/state). ```motoko no-repl import Array "mo:core/Array"; diff --git a/docs/languages/motoko/fundamentals/mutable-arrays.md b/docs/languages/motoko/fundamentals/types/mutable-arrays.md similarity index 93% rename from docs/languages/motoko/fundamentals/mutable-arrays.md rename to docs/languages/motoko/fundamentals/types/mutable-arrays.md index 2d339aa0..c4580146 100644 --- a/docs/languages/motoko/fundamentals/mutable-arrays.md +++ b/docs/languages/motoko/fundamentals/types/mutable-arrays.md @@ -4,7 +4,7 @@ description: "Motoko language documentation" title: "Mutable arrays" --- -Mutable arrays allow direct modification of elements, making them suitable for scenarios where data needs to be updated frequently. Unlike [immutable arrays](/languages/motoko/fundamentals/immutable-arrays), which require creating a new array to reflect changes, mutable arrays support in place modifications, improving performance in some cases. +Mutable arrays allow direct modification of elements, making them suitable for scenarios where data needs to be updated frequently. Unlike [immutable arrays](/languages/motoko/fundamentals/types/immutable-arrays), which require creating a new array to reflect changes, mutable arrays support in place modifications, improving performance in some cases. ## Creating a mutable array @@ -107,7 +107,7 @@ mutableArray; ## Accessing and modifying elements -Mutable array elements can be read and modified using indexed access. Attempting to access an index that does not exist will result in a [trap](/languages/motoko/fundamentals/traps). +Mutable array elements can be read and modified using indexed access. Attempting to access an index that does not exist will result in a [trap](/languages/motoko/fundamentals/basic-syntax/traps). ```motoko let numbers : [var Nat] = [var 10, 20, 30]; @@ -119,7 +119,7 @@ debug_show(numbers[0]); // 100 The size of an array `a` is available as `a.size()`, a `Nat`. Array elements are zero-indexed, allowing indices `0` up to `a.size() - 1`. -Attempting to access an array's index that does not exist will cause a [trap](/languages/motoko/fundamentals/traps). +Attempting to access an array's index that does not exist will cause a [trap](/languages/motoko/fundamentals/basic-syntax/traps). ```motoko no-repl let numbers : [var Nat] = [var 10, 20, 30]; @@ -157,7 +157,7 @@ for (i in arr.keys()) { ## Converting a mutable array to an immutable array -You can convert a mutable array into an immutable array using `Array.freeze`, ensuring that the contents cannot be modified after conversion. Since mutable arrays are not [sharable](/languages/motoko/fundamentals/shared-types), freezing them is useful when passing data across [functions](/languages/motoko/fundamentals/functions) or [actors](/languages/motoko/fundamentals/actors-async) to ensure immutability. +You can convert a mutable array into an immutable array using `Array.freeze`, ensuring that the contents cannot be modified after conversion. Since mutable arrays are not [sharable](/languages/motoko/fundamentals/types/shared-types), freezing them is useful when passing data across [functions](/languages/motoko/fundamentals/types/function-types) or [actors](/languages/motoko/fundamentals/actors/actors-async) to ensure immutability. ```motoko no-repl import Array "mo:core/Array"; diff --git a/docs/languages/motoko/fundamentals/objects-classes.md b/docs/languages/motoko/fundamentals/types/objects-classes.md similarity index 95% rename from docs/languages/motoko/fundamentals/objects-classes.md rename to docs/languages/motoko/fundamentals/types/objects-classes.md index 18fb4fde..6cc9c6f9 100644 --- a/docs/languages/motoko/fundamentals/objects-classes.md +++ b/docs/languages/motoko/fundamentals/types/objects-classes.md @@ -9,7 +9,7 @@ title: "Objects & classes" In Motoko, an object is a collection of named fields that hold values. These values can be plain data or functions. Each field can be either **mutable** or **immutable** depending on whether it's declared with `var` or not. A simple object containing just fields of data is like a record in a database. -Motoko's light-weight [record](/languages/motoko/fundamentals/records) syntax makes it easy to construct such objects. +Motoko's light-weight [record](/languages/motoko/fundamentals/types/records) syntax makes it easy to construct such objects. When fields contain function values, Motoko objects can represent traditional objects with methods, familiar from object-oriented programming (OOP). From an OOP perspective, an object is an abstraction, defined by the behavior of its methods. Methods are typically used to modify or observe some encapsulated (i.e. hidden) state of an object. @@ -34,7 +34,7 @@ object Account { ## Classes -An object declaration just declares a single object. To declare a function that generates objects of a similar type, Motoko offer classes. A class acts as a blueprint for creating multiple objects with independent [state](/languages/motoko/fundamentals/state). +An object declaration just declares a single object. To declare a function that generates objects of a similar type, Motoko offer classes. A class acts as a blueprint for creating multiple objects with independent [state](/languages/motoko/fundamentals/actors/state). ```motoko class Account(initialBalance : Nat) { @@ -189,5 +189,5 @@ withdrawFromAccount(_premiumAccount); // withdrawFromAccount(_basicAccount); // type error: (missing withdraw) ``` -[Learn more about subtyping](/languages/motoko/fundamentals/subtyping). +[Learn more about subtyping](/languages/motoko/fundamentals/types/subtyping). diff --git a/docs/languages/motoko/fundamentals/options.md b/docs/languages/motoko/fundamentals/types/options.md similarity index 97% rename from docs/languages/motoko/fundamentals/options.md rename to docs/languages/motoko/fundamentals/types/options.md index 04d1f813..844c1ac9 100644 --- a/docs/languages/motoko/fundamentals/options.md +++ b/docs/languages/motoko/fundamentals/types/options.md @@ -53,7 +53,7 @@ if (Option.isSome(value)) { } ``` -By leveraging the `Option` module, handling optional values becomes more concise and expressive, reducing the need for explicit [`switch`](/languages/motoko/fundamentals/switch) statements. +By leveraging the `Option` module, handling optional values becomes more concise and expressive, reducing the need for explicit [`switch`](/languages/motoko/fundamentals/control-flow/switch) statements. ### Providing default values @@ -67,7 +67,7 @@ Option.get(username, "Guest"); // "Guest" if username is null ### Using options for error handling -Options can be used to catch expected failures instead of calling a [`trap`](/languages/motoko/fundamentals/traps), making a function return `null` when it encounters an invalid input. +Options can be used to catch expected failures instead of calling a [`trap`](/languages/motoko/fundamentals/basic-syntax/traps), making a function return `null` when it encounters an invalid input. ```motoko func safeDivide(a : Int, b : Int) : ?Int { diff --git a/docs/languages/motoko/fundamentals/primitive-types.md b/docs/languages/motoko/fundamentals/types/primitive-types.md similarity index 100% rename from docs/languages/motoko/fundamentals/primitive-types.md rename to docs/languages/motoko/fundamentals/types/primitive-types.md diff --git a/docs/languages/motoko/fundamentals/records.md b/docs/languages/motoko/fundamentals/types/records.md similarity index 95% rename from docs/languages/motoko/fundamentals/records.md rename to docs/languages/motoko/fundamentals/types/records.md index 0d18816b..fbd7d65f 100644 --- a/docs/languages/motoko/fundamentals/records.md +++ b/docs/languages/motoko/fundamentals/types/records.md @@ -5,7 +5,7 @@ title: "Records" --- Records allow you to group related values using named fields, with each field potentially having a different type. -Unlike [tuples](/languages/motoko/fundamentals/tuples), which use positional access, records provide field-based access, improving readability and maintainability. +Unlike [tuples](/languages/motoko/fundamentals/types/tuples), which use positional access, records provide field-based access, improving readability and maintainability. Records also support **mutable fields**, declared using the `var` keyword. In contrast, all fields in a tuple are always **immutable**. @@ -120,7 +120,7 @@ let individual : Individual = { ## Pattern matching on records -Records can be destructured using [`switch`](/languages/motoko/fundamentals/switch), allowing selective extraction of fields. This approach makes accessing deeply nested fields more explicit and readable. +Records can be destructured using [`switch`](/languages/motoko/fundamentals/control-flow/switch), allowing selective extraction of fields. This approach makes accessing deeply nested fields more explicit and readable. ```motoko type Address = { diff --git a/docs/languages/motoko/fundamentals/results.md b/docs/languages/motoko/fundamentals/types/results.md similarity index 100% rename from docs/languages/motoko/fundamentals/results.md rename to docs/languages/motoko/fundamentals/types/results.md diff --git a/docs/languages/motoko/fundamentals/shared-types.md b/docs/languages/motoko/fundamentals/types/shared-types.md similarity index 75% rename from docs/languages/motoko/fundamentals/shared-types.md rename to docs/languages/motoko/fundamentals/types/shared-types.md index 11202541..52252024 100644 --- a/docs/languages/motoko/fundamentals/shared-types.md +++ b/docs/languages/motoko/fundamentals/types/shared-types.md @@ -4,7 +4,7 @@ description: "Motoko language documentation" title: "Shared types" --- -All Motoko types are divided into sets. The smallest is the set of shared types. Shared types are part of the larger set of [stable types](/languages/motoko/fundamentals/stable-types). +All Motoko types are divided into sets. The smallest is the set of shared types. Shared types are part of the larger set of [stable types](/languages/motoko/fundamentals/types/stable-types). A shared type's value can be easily exchanged with other actors. To prevent issues associated with sharing mutable state across actors, **all shared types are immutable**. This immutability allows values to be transmitted safely by copying data, avoiding the complexity and risks of sharing stateful or mutable objects. @@ -22,14 +22,14 @@ Shareability is essential for several reasons: - Shared types ensure data can be safely serialized and deserialized across network boundaries. - Restricting sharing to immutable data prevents synchronization issues between canisters. -- Shared types map directly to [Candid](https://internetcomputer.org/docs/building-apps/interact-with-canisters/candid/candid-concepts), enabling interaction between canisters written in different languages. +- Shared types map directly to [Candid](/guides/canister-calls/candid), enabling interaction between canisters written in different languages. - Web and mobile frontends communicate with canisters using shared types. ## Common shared types ### Primitive types -Most [primitive types](/languages/motoko/fundamentals/primitive-types) are shared by default. +Most [primitive types](/languages/motoko/fundamentals/types/primitive-types) are shared by default. ```motoko no-repl // Numbers, text, and booleans are shared @@ -40,7 +40,7 @@ let flag : Bool = true; ### Immutable collections -Collections that cannot be modified after creation are shared, including [immutable arrays](/languages/motoko/fundamentals/immutable-arrays) and [tuples](/languages/motoko/fundamentals/tuples). +Collections that cannot be modified after creation are shared, including [immutable arrays](/languages/motoko/fundamentals/types/immutable-arrays) and [tuples](/languages/motoko/fundamentals/types/tuples). ```motoko no-repl // Immutable arrays are shared @@ -52,7 +52,7 @@ let person : (Text, Nat) = ("Motoko", 25); ### Records with immutable fields -Objects with immutable fields containing shared types are shared, including [records](/languages/motoko/fundamentals/records). +Objects with immutable fields containing shared types are shared, including [records](/languages/motoko/fundamentals/types/records). ```motoko no-repl // Records with immutable fields are shared @@ -65,7 +65,7 @@ let user = { ### Variants with shared type tags -[Variant types](/languages/motoko/fundamentals/variants) are shared when their tags contain shared types. +[Variant types](/languages/motoko/fundamentals/types/variants) are shared when their tags contain shared types. ```motoko no-repl // Variant types with shared tags are shared @@ -80,7 +80,7 @@ let failure : Result = #error("Operation failed"); ### Option types -[Option types](/languages/motoko/fundamentals/options) are shared when they contain shared types. +[Option types](/languages/motoko/fundamentals/types/options) are shared when they contain shared types. ```motoko no-repl // Option types with shared inner types are shared @@ -90,7 +90,7 @@ let nothing : ?Nat = null; ### Actor references -References to [actors](/languages/motoko/fundamentals/actors-async) are shared, allowing [canisters](https://internetcomputer.org/docs/building-apps/essentials/canisters) to call each other. +References to [actors](/languages/motoko/fundamentals/actors/actors-async) are shared, allowing [canisters](/concepts/canisters) to call each other. ```motoko no-repl // Actor types are shared @@ -102,7 +102,7 @@ type CounterActor = actor { ### Shared functions -[Function types](/languages/motoko/fundamentals/functions) marked as `shared` are sharable. +[Function types](/languages/motoko/fundamentals/types/function-types) marked as `shared` are sharable. ```motoko no-repl // Shared function types are shared @@ -111,7 +111,7 @@ type Callback = shared (Nat) -> async (); ## Non-shared types -Certain types cannot be shared between [canisters](https://internetcomputer.org/docs/building-apps/essentials/canisters). +Certain types cannot be shared between [canisters](/concepts/canisters). ### Mutable collections diff --git a/docs/languages/motoko/fundamentals/stable-types.md b/docs/languages/motoko/fundamentals/types/stable-types.md similarity index 88% rename from docs/languages/motoko/fundamentals/stable-types.md rename to docs/languages/motoko/fundamentals/types/stable-types.md index dadd17bd..96e71762 100644 --- a/docs/languages/motoko/fundamentals/stable-types.md +++ b/docs/languages/motoko/fundamentals/types/stable-types.md @@ -4,7 +4,7 @@ description: "Motoko language documentation" title: "Stable types" --- -**Stable types** include all [shared types](/languages/motoko/fundamentals/shared-types) and represent the kinds of values that can be stored in the `stable` declarations of a Motoko actor. +**Stable types** include all [shared types](/languages/motoko/fundamentals/types/shared-types) and represent the kinds of values that can be stored in the `stable` declarations of a Motoko actor. Storing a value in a `stable` declaration ensures that it persists across canister upgrades. This enables state preservation without the need for an external file system or database. The set of stable types defines the kinds of values that can be transferred from an actor to its future upgraded versions. @@ -26,7 +26,7 @@ To give the user more flexibility, the set of stable types is larger than the se ## Stable vs shared types -While all shared types are stable, the reverse is not true. Some stable types cannot be shared across [canisters](https://internetcomputer.org/docs/building-apps/essentials/canisters). +While all shared types are stable, the reverse is not true. Some stable types cannot be shared across [canisters](/concepts/canisters). | Type | Stable | Shared | |----------------------------------------------------------------------------------------------|--------|--------| @@ -55,7 +55,7 @@ Non-shared functions and futures (`async T`) and computations (`async* T`) depen ### Primitive types -Most [primitive types](/languages/motoko/fundamentals/primitive-types) in Motoko are stable. +Most [primitive types](/languages/motoko/fundamentals/types/primitive-types) in Motoko are stable. ```motoko no-repl persistent actor { @@ -83,7 +83,7 @@ persistent actor { ### Records with mutable or immutable fields -[Records](/languages/motoko/fundamentals/records) that contain only stable types remain stable, regardless of whether their fields are mutable or immutable. +[Records](/languages/motoko/fundamentals/types/records) that contain only stable types remain stable, regardless of whether their fields are mutable or immutable. ```motoko no-repl persistent actor { @@ -104,7 +104,7 @@ persistent actor { ### Variants with stable type tags -[Variants](/languages/motoko/fundamentals/variants) are stable when their tags contain only stable types. +[Variants](/languages/motoko/fundamentals/types/variants) are stable when their tags contain only stable types. ```motoko no-repl persistent actor { @@ -122,7 +122,7 @@ persistent actor { ### Option types -[Option](/languages/motoko/fundamentals/options) types are stable when they contain stable types. +[Option](/languages/motoko/fundamentals/types/options) types are stable when they contain stable types. ```motoko no-repl persistent actor { @@ -145,7 +145,7 @@ persistent actor { ### Actor references -References to [actors](/languages/motoko/fundamentals/actors-async) are stable, allowing stable canister-to-canister interactions. +References to [actors](/languages/motoko/fundamentals/actors/actors-async) are stable, allowing stable canister-to-canister interactions. ```motoko no-repl persistent actor { diff --git a/docs/languages/motoko/fundamentals/subtyping.md b/docs/languages/motoko/fundamentals/types/subtyping.md similarity index 94% rename from docs/languages/motoko/fundamentals/subtyping.md rename to docs/languages/motoko/fundamentals/types/subtyping.md index 0368e5bd..d7586feb 100644 --- a/docs/languages/motoko/fundamentals/subtyping.md +++ b/docs/languages/motoko/fundamentals/types/subtyping.md @@ -125,7 +125,7 @@ discard("abc"); // Allowed, since `Text <: Any` ## Options -If `T <: U`, then `?T <: ?U` because option subtyping is covariant. This means an [optional value](/languages/motoko/fundamentals/options) of a subtype can be used as an optional value of a supertype. +If `T <: U`, then `?T <: ?U` because option subtyping is covariant. This means an [optional value](/languages/motoko/fundamentals/types/options) of a subtype can be used as an optional value of a supertype. ```motoko no-repl let a : ?Nat = ?5; @@ -144,7 +144,7 @@ let ot : ?Text = n; // Allowed, since `Null <: ?Text` ## Records and objects -[Records](/languages/motoko/fundamentals/records) and, more generally, [objects](/languages/motoko/fundamentals/objects-classes) +[Records](/languages/motoko/fundamentals/types/records) and, more generally, [objects](/languages/motoko/fundamentals/types/objects-classes) support subtyping, both in the required fields and the types of those fields. An object type `T` is a subtype of another object type `U`, if `T` requires all the fields required by `U`, @@ -182,7 +182,7 @@ However, both `A` and `B` are still subtypes of `C`, since `C` lacks the `age` f ## Variants -[Variants](/languages/motoko/fundamentals/variants) also support subtyping, both in the allowed fields and the types of those fields. +[Variants](/languages/motoko/fundamentals/types/variants) also support subtyping, both in the allowed fields and the types of those fields. A variant type `T` is a subtype of another variant type `U` if every value in `T` also appears in `U`, and the associated types in `T` are subtypes of those in `U`. `T` may allow fewer fields than `U`. @@ -227,7 +227,7 @@ let rok : Result = ok; // Allowed, since `{#ok : Nat} <: {#ok : Int; ## Immutable arrays -[Immutable arrays (`[T]`)](/languages/motoko/fundamentals/immutable-arrays) support covariant subtyping, meaning if `T <: U`, then `[T] <: [U]`. +[Immutable arrays (`[T]`)](/languages/motoko/fundamentals/types/immutable-arrays) support covariant subtyping, meaning if `T <: U`, then `[T] <: [U]`. If `T <: U`, then an (immutable) array of type `[T]` can be used as an array of type `[U]`. @@ -238,7 +238,7 @@ let ints : [Int] = nats; // Allowed, since `Nat <: Int` we also have `[Nat] <: ## Mutable arrays -[Mutable arrays](/languages/motoko/fundamentals/mutable-arrays) of the form `[var T]` do not support interesting subtyping. +[Mutable arrays](/languages/motoko/fundamentals/types/mutable-arrays) of the form `[var T]` do not support interesting subtyping. The mutable array constructor `[var T]` is invariant in `T`. This means that `[var T]` is a subtype of `[var U]` only if `T` and `U` are equivalent types, that is, both `T <: U` and `U <: T` must hold. @@ -252,7 +252,7 @@ let ints : [var Int] = nats; // Not allowed, because `[var Nat] T2` is a subtype of another function type `U1 -> U2` provided that: 1. The argument types are related in the opposite direction (`U1 <: T1` ). @@ -298,7 +298,7 @@ In the case of actors, which can only contain shared functions as fields, this m ## Recursive and generic types -[Recursive and generic types](/languages/motoko/fundamentals/advanced-types) can be subtypes of each other when their definitions allow it. +[Recursive and generic types](/languages/motoko/fundamentals/types/advanced-types) can be subtypes of each other when their definitions allow it. Consider the following recursive point types, where the second extends the first by adding a color field: diff --git a/docs/languages/motoko/fundamentals/tuples.md b/docs/languages/motoko/fundamentals/types/tuples.md similarity index 99% rename from docs/languages/motoko/fundamentals/tuples.md rename to docs/languages/motoko/fundamentals/types/tuples.md index 9d742241..b9ecddc2 100644 --- a/docs/languages/motoko/fundamentals/tuples.md +++ b/docs/languages/motoko/fundamentals/types/tuples.md @@ -59,7 +59,7 @@ Tuples can be stored in arrays or other data structures. Tuples can be construct let users : [(Text, Nat)] = [("Motoko", 25), ("Ghost", 30)]; ``` -This structure efficiently represents a collection of key-value pairs without requiring a dedicated [record](/languages/motoko/fundamentals/records) type. +This structure efficiently represents a collection of key-value pairs without requiring a dedicated [record](/languages/motoko/fundamentals/types/records) type. ## Pattern matching on tuples diff --git a/docs/languages/motoko/fundamentals/type-conversions.md b/docs/languages/motoko/fundamentals/types/type-conversions.md similarity index 95% rename from docs/languages/motoko/fundamentals/type-conversions.md rename to docs/languages/motoko/fundamentals/types/type-conversions.md index 28519598..5626f5f6 100644 --- a/docs/languages/motoko/fundamentals/type-conversions.md +++ b/docs/languages/motoko/fundamentals/types/type-conversions.md @@ -162,7 +162,7 @@ assert arrayOfNatToText([1, 2, 3]) == "1 2 3"; ### `Array` of tuples to an object -Motoko lacks support for dynamic objects, so an array of tuples is converted into a [record](/languages/motoko/fundamentals/records) or a structured representation. +Motoko lacks support for dynamic objects, so an array of tuples is converted into a [record](/languages/motoko/fundamentals/types/records) or a structured representation. ```motoko no-repl import HashMap "mo:core/HashMap"; @@ -181,7 +181,7 @@ persistent actor MapConverter { arrayToMap([("Motoko", 4), ("Ghost", 21)]); ``` -To convert an array of tuples `[(Text, Nat)]` into a custom [record](/languages/motoko/fundamentals/records) type, such as `User`, `Array.map` is used to transform each tuple into a structured [record](/languages/motoko/fundamentals/records). +To convert an array of tuples `[(Text, Nat)]` into a custom [record](/languages/motoko/fundamentals/types/records) type, such as `User`, `Array.map` is used to transform each tuple into a structured [record](/languages/motoko/fundamentals/types/records). ```motoko no-repl import Array "mo:core/Array"; diff --git a/docs/languages/motoko/fundamentals/variants.md b/docs/languages/motoko/fundamentals/types/variants.md similarity index 86% rename from docs/languages/motoko/fundamentals/variants.md rename to docs/languages/motoko/fundamentals/types/variants.md index fff7dec7..175378a1 100644 --- a/docs/languages/motoko/fundamentals/variants.md +++ b/docs/languages/motoko/fundamentals/types/variants.md @@ -4,7 +4,7 @@ description: "Motoko language documentation" title: "Variants" --- -Variant type describe values that take on one of several forms, each labeled with a distinct tag. Unlike [records](/languages/motoko/fundamentals/records), where all fields exist at once, a value of a variant type holds exactly one of the type's possible values. This makes variants useful for representing mutually exclusive alternatives such as states, enumerations, categories and even trees. +Variant type describe values that take on one of several forms, each labeled with a distinct tag. Unlike [records](/languages/motoko/fundamentals/types/records), where all fields exist at once, a value of a variant type holds exactly one of the type's possible values. This makes variants useful for representing mutually exclusive alternatives such as states, enumerations, categories and even trees. ## Defining a variant @@ -29,7 +29,7 @@ let bannedUser = #Banned("Violation of rules"); ## Accessing a variant's value -To work with a variant, use a [`switch`](/languages/motoko/fundamentals/switch) expression to match each possible case. +To work with a variant, use a [`switch`](/languages/motoko/fundamentals/control-flow/switch) expression to match each possible case. ```motoko no-repl import Debug "mo:core/Debug"; @@ -59,7 +59,7 @@ A traffic light cycles between three distinct states: - Yellow: Vehicles should prepare to stop. - Green: Vehicles may proceed. -Since the traffic light can only be in one of these states at a time, a variant is well-suited to model it. There is no invalid [state](/languages/motoko/fundamentals/state), as every possible value is explicitly defined. The transitions are controlled and predictable. +Since the traffic light can only be in one of these states at a time, a variant is well-suited to model it. There is no invalid [state](/languages/motoko/fundamentals/actors/state), as every possible value is explicitly defined. The transitions are controlled and predictable. ### Defining the traffic light state @@ -73,7 +73,7 @@ type TrafficLight = { ### Transitioning between states -A function can define how the traffic light cycles from one [state](/languages/motoko/fundamentals/state) to the next. +A function can define how the traffic light cycles from one [state](/languages/motoko/fundamentals/actors/state) to the next. ```motoko no-repl func nextState(light : TrafficLight) : TrafficLight { @@ -183,7 +183,7 @@ traverseInOrder(tree); ### Using generic types -Currently, the example tree only supports [`Nat`](https://mops.one/core/docs/Nat) values. To allow it to store any type of data, a [generic type](/languages/motoko/fundamentals/advanced-types#generic-types) can be used. A generic type allows a data structure to work with multiple types by using a placeholder type `T`, which is replaced with a specific type when used. +Currently, the example tree only supports [`Nat`](https://mops.one/core/docs/Nat) values. To allow it to store any type of data, a [generic type](/languages/motoko/fundamentals/types/advanced-types#generic-types) can be used. A generic type allows a data structure to work with multiple types by using a placeholder type `T`, which is replaced with a specific type when used. ```motoko no-repl type Tree = { diff --git a/docs/languages/motoko/icp-features/candid-serialization.md b/docs/languages/motoko/icp-features/candid-serialization.md index 5f2721f5..8edb150d 100644 --- a/docs/languages/motoko/icp-features/candid-serialization.md +++ b/docs/languages/motoko/icp-features/candid-serialization.md @@ -10,9 +10,9 @@ Motoko automatically generates Candid interfaces for canisters and provides buil ## Autogenerated Candid interfaces -When Motoko code is compiled, a Candid interface file [(`.did`)](https://internetcomputer.org/docs/building-apps/interact-with-canisters/candid/using-candid#the-did-file) for the canister's public methods is automatically generated. This file is used to ensure data passed into and returned from these methods is automatically encoded to and decoded from Candid’s binary format. +When Motoko code is compiled, a Candid interface file [(`.did`)](/guides/canister-calls/candid#the-did-file) for the canister's public methods is automatically generated. This file is used to ensure data passed into and returned from these methods is automatically encoded to and decoded from Candid’s binary format. -Motoko canisters automatically handle the serialization and deserialization of data when the canister interacts with [inter-canister calls or ingress messages](https://internetcomputer.org/docs/building-apps/essentials/message-execution). +Motoko canisters automatically handle the serialization and deserialization of data when the canister interacts with [inter-canister calls or ingress messages](/references/message-execution-properties). ## Candid operators @@ -131,6 +131,6 @@ While dynamic calls offer more flexibility, they should be used judiciously. In For more detailed information on Candid, refer to: -- [What is Candid?](https://internetcomputer.org/docs/building-apps/interact-with-canisters/candid/candid-concepts) -- [Using Candid](https://internetcomputer.org/docs/building-apps/interact-with-canisters/candid/using-candid) -- [Candid Specification](https://internetcomputer.org/docs/references/candid-ref) +- [What is Candid?](/guides/canister-calls/candid) +- [Using Candid](/guides/canister-calls/candid) +- [Candid Specification](/references/candid-spec) diff --git a/docs/languages/motoko/icp-features/randomness.md b/docs/languages/motoko/icp-features/randomness.md index 2456fe52..51e0ebad 100644 --- a/docs/languages/motoko/icp-features/randomness.md +++ b/docs/languages/motoko/icp-features/randomness.md @@ -4,9 +4,9 @@ description: "Motoko language documentation" title: "Randomness" --- -[Randomness](https://internetcomputer.org/docs/building-apps/network-features/randomness) is used for generating unique identifiers, ensuring fairness in games, cryptographic protocols, and much more. On ICP, all computations, including [randomness](https://internetcomputer.org/docs/building-apps/network-features/randomness), must be **verifiable and reproducible** across the network's nodes. +[Randomness](/guides/backends/randomness) is used for generating unique identifiers, ensuring fairness in games, cryptographic protocols, and much more. On ICP, all computations, including [randomness](/guides/backends/randomness), must be **verifiable and reproducible** across the network's nodes. -The network provides a **verifiable random function (VRF)** through the [management canister](https://internetcomputer.org/docs/references/system-canisters/management-canister) that produces random values that are unpredictable yet verifiable, ensuring fairness and security while maintaining network consensus. It guarantees cryptographic security, making it suitable for use cases such as cryptographic key generation. +The network provides a **verifiable random function (VRF)** through the [management canister](/references/management-canister) that produces random values that are unpredictable yet verifiable, ensuring fairness and security while maintaining network consensus. It guarantees cryptographic security, making it suitable for use cases such as cryptographic key generation. The VRF generates 256-bit random `Blob`s in each execution round. A canister can request one of these random `Blob`s via the management canister's `raw_rand` method. @@ -27,7 +27,7 @@ Before using the [`fuzz`](https://mops.one/fuzz) or [`idempotency-keys`](https:/ ## `raw_rand` -The `raw_rand` function is a system API provided by the [ICP management canister](https://internetcomputer.org/docs/references/system-canisters/management-canister) for requesting cryptographic randomness derived from the network’s verifiable random function. `raw_rand` generates fresh entropy in every execution round, making it suitable for applications requiring high security such as key generation or applications where fairness is a legal requirement. +The `raw_rand` function is a system API provided by the [ICP management canister](/references/management-canister) for requesting cryptographic randomness derived from the network’s verifiable random function. `raw_rand` generates fresh entropy in every execution round, making it suitable for applications requiring high security such as key generation or applications where fairness is a legal requirement. Since `raw_rand` operates asynchronously, canisters must await its response before using the generated bytes. Each call returns a 32-byte (256-bit) random `Blob`. @@ -104,7 +104,7 @@ persistent actor { ## Resources -- [`raw_rand`](https://internetcomputer.org/docs/references/ic-interface-spec#ic-raw_rand) +- [`raw_rand`](/references/ic-interface-spec/#ic-raw_rand) - [`Random`](https://mops.one/core/docs/Random) - [`fuzz`](https://mops.one/fuzz) - [`idempotency-keys`](https://mops.one/idempotency-keys) diff --git a/docs/languages/motoko/icp-features/stable-memory.md b/docs/languages/motoko/icp-features/stable-memory.md index 0df985f6..1d6ea623 100644 --- a/docs/languages/motoko/icp-features/stable-memory.md +++ b/docs/languages/motoko/icp-features/stable-memory.md @@ -4,14 +4,14 @@ description: "Motoko language documentation" title: "Stable memory and regions" --- -Canisters have two types of storage: Wasm memory and stable memory. The Wasm memory is often referred to as the [heap memory](https://internetcomputer.org/docs/building-apps/canister-management/storage#heap-memory). It is automatically used for heap-allocated objects and has a maximum size limitation of 4 GiB or 6 GiB respective to whether you are using 32-bit or 64-bit heap storage without enhanced orthogonal persistence. When a canister is upgraded, the heap memory is cleared, only retaining data stored in stable variables. +Canisters have two types of storage: Wasm memory and stable memory. The Wasm memory is often referred to as the [heap memory](/concepts/orthogonal-persistence#heap-memory). It is automatically used for heap-allocated objects and has a maximum size limitation of 4 GiB or 6 GiB respective to whether you are using 32-bit or 64-bit heap storage without enhanced orthogonal persistence. When a canister is upgraded, the heap memory is cleared, only retaining data stored in stable variables. -Stable memory has a maximum size of 500 GiB and is preserved across canister upgrades. Motoko utilizes [stable memory](https://internetcomputer.org/docs/building-apps/canister-management/storage#stable-memory) through the [stable storage feature](https://internetcomputer.org/docs/building-apps/canister-management/storage#motoko-storage-handling) to preserve data across canister upgrades. Stable regions extend this functionality to allow more structured and flexible memory management. +Stable memory has a maximum size of 500 GiB and is preserved across canister upgrades. Motoko utilizes [stable memory](/concepts/orthogonal-persistence#stable-memory) through the [stable storage feature](/concepts/orthogonal-persistence#motoko-storage-handling) to preserve data across canister upgrades. Stable regions extend this functionality to allow more structured and flexible memory management. The system automatically commits all memory modifications, both Wasm and stable, after the successful execution of a message. If a message execution fails, the changes are not committed. :::caution -The `Regions` library should only be used if [enhanced orthogonal persistence](/languages/motoko/fundamentals/orthogonal-persistence-enhanced) does not fit your use case. +The `Regions` library should only be used if [enhanced orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced) does not fit your use case. ::: ## What is a `Region`? @@ -56,7 +56,7 @@ let previousSize = Region.grow(myRegion, 10); // Add 10 pages (640 KiB) ### Growing a `Region` safely -`Regions` can only grow, never shrink. Growth may fail due to [ICP resource limitations](https://internetcomputer.org/docs/building-apps/canister-management/resource-limits) and it is recommended to use the minimum pages needed to conserve resources. +`Regions` can only grow, never shrink. Growth may fail due to [ICP resource limitations](/guides/canister-management/large-wasm) and it is recommended to use the minimum pages needed to conserve resources. Growing a [`Region`](https://mops.one/core/docs/Region) safely requires checking the current allocated size and ensuring that the required space does not exceed available capacity. Since stable memory is allocated in fixed-size pages of 64 KiB, any expansion must be done in page increments. To determine how many additional pages are needed, the difference between the required memory and the current capacity is calculated and rounded up to the nearest page boundary. Once the necessary pages are determined, the [`Region`](https://mops.one/core/docs/Region) is expanded accordingly. After growth, verifying that the expansion was successful ensures stability and prevents unintended memory access issues. diff --git a/docs/languages/motoko/icp-features/system-functions.md b/docs/languages/motoko/icp-features/system-functions.md index 071edd7a..8643921f 100644 --- a/docs/languages/motoko/icp-features/system-functions.md +++ b/docs/languages/motoko/icp-features/system-functions.md @@ -6,19 +6,19 @@ title: "System functions" ICP supports five system functions that canisters can call to interact with the ICP runtime environment: -- [`timer`](https://internetcomputer.org/docs/references/ic-interface-spec#global-timer) +- [`timer`](/references/ic-interface-spec/#global-timer) - [`preupgrade`](#preupgrade) - [`postupgrade`](#postupgrade) - [`lowmemory`](#lowmemory) -- [`inspect`](https://internetcomputer.org/docs/references/ic-interface-spec#system-api-inspect-message) -- [`heartbeat`](https://internetcomputer.org/docs/references/ic-interface-spec#heartbeat) +- [`inspect`](/references/ic-interface-spec/#system-api-inspect-message) +- [`heartbeat`](/references/ic-interface-spec/#heartbeat) Declaring any other system function will result in an error. Canisters can use these functions to efficiently manage state transitions, automate tasks, or handle system-level operations. ## `timer()` -The [`timer()` system function](https://internetcomputer.org/docs/building-apps/network-features/periodic-tasks-timers#timers) lets canisters schedule a task to execute after a specified delay. To make the timer repeat, the function must explicitly call `setGlobalTimer()` within its body to reset the timer. It accepts a single argument to set the global timer and returns `async ()`. +The [`timer()` system function](/guides/backends/timers#timers) lets canisters schedule a task to execute after a specified delay. To make the timer repeat, the function must explicitly call `setGlobalTimer()` within its body to reset the timer. It accepts a single argument to set the global timer and returns `async ()`. Unlike `heartbeat()`, which runs automatically every subnet round, `timer()` requires manual rescheduling after each execution. This design gives canisters precise control over whether the timer runs once or continuously, depending on if and when `setGlobalTimer()` is called again. @@ -121,11 +121,11 @@ The following properties apply to the low memory hook: ## `inspect()` -The [`inspect()` system function](https://internetcomputer.org/docs/references/ic-interface-spec#system-api-inspect-message) allows a canister to inspect ingress messages before execution, determining whether to accept or reject them. The function receives a record of message attributes, including the caller’s principal, the raw argument `Blob`, and a variant identifying the target function. +The [`inspect()` system function](/references/ic-interface-spec/#system-api-inspect-message) allows a canister to inspect ingress messages before execution, determining whether to accept or reject them. The function receives a record of message attributes, including the caller’s principal, the raw argument `Blob`, and a variant identifying the target function. -It returns a `Bool`, where `true` permits execution and `false` rejects the message. Similar to a [query](https://internetcomputer.org/docs/building-apps/essentials/message-execution), any side effects are discarded. If `inspect()` traps, it is equivalent to returning `false`. Unlike other system functions, the argument type of `inspect()` depends on the actor's exposed interface, meaning it can selectively handle different methods or ignore unnecessary fields. +It returns a `Bool`, where `true` permits execution and `false` rejects the message. Similar to a [query](/references/message-execution-properties), any side effects are discarded. If `inspect()` traps, it is equivalent to returning `false`. Unlike other system functions, the argument type of `inspect()` depends on the actor's exposed interface, meaning it can selectively handle different methods or ignore unnecessary fields. -However, `inspect()` should not be used for definitive access control because it runs on a single replica without going through consensus, making it susceptible to boundary node spoofing. Additionally, `inspect()` only applies to [ingress messages](https://internetcomputer.org/docs/building-apps/essentials/message-execution), not [inter-canister calls](https://internetcomputer.org/docs/references/async-code), meaning secure access control must still be enforced within shared functions. +However, `inspect()` should not be used for definitive access control because it runs on a single replica without going through consensus, making it susceptible to boundary node spoofing. Additionally, `inspect()` only applies to [ingress messages](/references/message-execution-properties), not [inter-canister calls](/references/message-execution-properties), meaning secure access control must still be enforced within shared functions. The following actor defines an inspect function that blocks anonymous callers, limits message size, and rejects specific argument values. @@ -172,12 +172,12 @@ persistent actor Counter { Heartbeats are computationally expensive for both the network and user, and instead you should use a timer if possible. ::: -Canisters can opt to receive [heartbeat messages](https://internetcomputer.org/docs/building-apps/network-features/periodic-tasks-timers#heartbeats) by exposing a `canister_heartbeat` function. In Motoko, this is achieved by declaring the system function `heartbeat`, which takes no arguments and returns an asynchronous unit type (`async ()`). +Canisters can opt to receive [heartbeat messages](/guides/backends/timers#heartbeats) by exposing a `canister_heartbeat` function. In Motoko, this is achieved by declaring the system function `heartbeat`, which takes no arguments and returns an asynchronous unit type (`async ()`). Since `heartbeat()` is async, it can invoke other asynchronous functions and await their results. This function executes on every **subnet heartbeat**, enabling periodic task execution without requiring external triggers. Since subnet heartbeats operate at the protocol level, their timing is not precise and depends on network conditions and execution load. As a result, using heartbeats for high-frequency or time-sensitive operations should be done cautiously, as there is no guarantee of real-time execution. Every async call in Motoko causes a context switch, which means the actual execution of the heartbeat function may be delayed relative to when the subnet triggers it. The function’s result is ignored, so any errors or traps during execution do not impact future heartbeat calls. -If a canister exports a function named `canister_heartbeat`, it must have the type `() -> ()`, ensuring it adheres to the expected [system function signature](https://internetcomputer.org/docs/references/ic-interface-spec#heartbeat). +If a canister exports a function named `canister_heartbeat`, it must have the type `() -> ()`, ensuring it adheres to the expected [system function signature](/references/ic-interface-spec/#heartbeat). Heartbeats should be considered deprecated as they have been superseded by timers. diff --git a/docs/languages/motoko/icp-features/timers.md b/docs/languages/motoko/icp-features/timers.md index 36ef5eae..ba9f2bd2 100644 --- a/docs/languages/motoko/icp-features/timers.md +++ b/docs/languages/motoko/icp-features/timers.md @@ -32,7 +32,7 @@ persistent actor Reminder { } ``` -The underlying mechanism is a [global timer](https://internetcomputer.org/docs/references/ic-interface-spec#timer) that, by default, is issued with appropriate callbacks from a priority queue maintained by the Motoko runtime. +The underlying mechanism is a [global timer](/references/ic-interface-spec/#timer) that, by default, is issued with appropriate callbacks from a priority queue maintained by the Motoko runtime. The timer mechanism can be disabled completely by passing the `--no-timer` flag to `moc`. diff --git a/docs/languages/motoko/reference/changelog.md b/docs/languages/motoko/reference/changelog.md index 27d3e755..2159ac54 100644 --- a/docs/languages/motoko/reference/changelog.md +++ b/docs/languages/motoko/reference/changelog.md @@ -898,7 +898,7 @@ $(dfx cache show)/moc --version ensures that no cleanup is required. The relevant security best practices are accessible at - https://internetcomputer.org/docs/current/developer-docs/security/security-best-practices/inter-canister-calls#recommendation + /guides/security/inter-canister-calls#recommendation BREAKING CHANGE (Minor): `finally` is now a reserved keyword, programs using this identifier will break. diff --git a/docs/languages/motoko/reference/compiler-ref.md b/docs/languages/motoko/reference/compiler-ref.md new file mode 100644 index 00000000..3be90c0f --- /dev/null +++ b/docs/languages/motoko/reference/compiler-ref.md @@ -0,0 +1,78 @@ +--- +sidebar_position: 15 +description: "Motoko language documentation" +title: "Compiler reference" +--- + +The Motoko compiler (`moc`) is the primary tool for compiling Motoko programs into executable WebAssembly (Wasm) modules. The compiler runs in the background when you build projects using the [IC SDK](https://github.com/dfinity/sdk). If you invoke the compiler directly on the command-line, you can press CTRL-C to exit. + +This section provides compiler command-line reference information. + +## moc + +Use the Motoko compiler (`moc`) to compile Motoko programs into executable WebAssembly (Wasm) modules. + +### Basic usage + +``` bash +moc [option] [file ...] +``` + +### Options + +You can use the following options with the `moc` command. + +| Option | Description | +|-------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------| +| `--ai-errors` | Emit AI tailored error messages. | +| `--actor-idl ` | Specifies a path to actor IDL (Candid) files. | +| `--actor-alias ` | Specifies an actor import alias. | +| `--args ` | Read additional newline separated command line arguments from ``. | +| `--args0 ` | Read additional `NUL` separated command line arguments from ``. | +| `-c` | Compile to WebAssembly. | +| `--check` | Performs type checking only. | +| `--compacting-gc` | Use compacting GC (only available with legacy/classical persistence). | +| `--copying-gc` | Use copying GC (only available with legacy/classical persistence). | +| `--debug` | Respects debug expressions in the source (the default). | +| `--enhanced-orthogonal-persistence` | Use enhanced orthogonal persistence (default): Scalable and fast upgrades using a persistent 64-bit main memory. | +| `--enhanced-migration ` | Enable enhanced migration system: requires initializers for all stable variables, disallows side-effects in actor bodies; only available with enhanced orthogonal persistence. | +| `--error-detail ` | Set level of error message detail for syntax errors, n in \[0..3\] (default 2). | +| `--experimental-stable-memory ` | Select support for the deprecated `ExperimentalStableMemory.mo` library (n < 0: error, n = 0: warn, n > 0: allow) (default 0). | +| `-fno-shared-code` | Do not share low-level utility code: larger code size but decreased cycle consumption (default). | +| `--generational-gc` | Use generational GC (only available with legacy/classical persistence). | +| `-fshared-code` | Do share low-level utility code: smaller code size but increased cycle consumption. | +| `--generate-view-queries` | Auto-generate queries for stable variables; preferring applicable .view() methods (default false) | +| `-help`,`--help` | Displays usage information. | +| `--hide-warnings` | Hides compiler warnings. | +| `-Werror` | Treat warnings as errors. | +| `-A ` | Disable (Allow) comma-separated warning codes, e.g. `-A M0194,M0223` | +| `-W ` | Enable (Warn) comma-separated warning codes, e.g. `-W M0223` | +| `-E ` | Treat as error comma-separated warning codes, e.g. `-E M0217` | +| `--warn-help` | Show available warning codes, current lint level, and descriptions | +| `--incremental-gc` | Use incremental GC (default, works with both enhanced orthogonal persistence and legacy/classical persistence). | +| `--idl` | Compile binary and emit Candid IDL specification to `.did` file. | +| `-i` | Runs the compiler in an interactive read–eval–print loop (REPL) shell so you can evaluate program execution (implies -r). | +| `--legacy-persistence` | Use legacy (classical) persistence. This also enables the usage of --copying-gc, --compacting-gc, and --generational-gc. Deprecated in favor of the new enhanced orthogonal persistence, which is default. Legacy persistence will be removed in the future.| +| `--map` | Outputs a JavaScript source map. | +| `--max-stable-pages ` | Set maximum number of pages available for library `ExperimentStableMemory.mo` (default 65536). | +| `-no-system-api` | Disables system API imports. | +| `-no-timer` | Disables timer API imports and hides timer primitives. | +| `-o ` | Specifies the output file. | +| `-p ` | Sets the print depth. | +| `--package ` | Specifies a `` `` pair, separated by a space. | +| `--public-metadata ` | Emit ICP custom section `` (`candid:args` or `candid:service` or `motoko:stable-types` or `motoko:compiler`) as `public` (default is `private`).| +| `--omit-metadata ` | Omit ICP custom section `` (`candid:args` or `candid:service` or `motoko:stable-types` or `motoko:compiler`). | +| `--print-deps` | Prints the dependencies for a given source file. | +| `-r` | Interprets programs. | +| `--release` | Ignores debug expressions in the source. | +| `--stable-regions` | Force eager initialization of stable regions metadata (for testing purposes); consumes between 386KiB or 8MiB of additional physical stable memory, depending on current use of ExperimentalStableMemory. | +| `--stable-types` | Compile binary and emit signature of stable types to `.most` file. | +| `--stable-compatible
 `        | Test upgrade compatibility between stable-type signatures `
` and ``.                                                                       |
+| `--rts-stack-pages `                   | Set maximum number of pages available for runtime system stack (only supported with classical persistence, default 32).                               |
+| `--trap-on-call-error`                    | Trap, don't throw an [`Error`](https://mops.one/core/docs/Error), when an IC call fails due to destination queue full or freezing threshold is crossed. Emulates behavior of moc versions < 0.8.0.                                                                                                                                           |
+| `-t`                                      | Activates tracing in interpreter.                                                                                                                     |
+| `-v`                                      | Generates verbose output.                                                                                                                             |
+| `--version`                               | Displays version information.                                                                                                                         |
+| `-wasi-system-api`                        | Uses the WASI system API (`wasmtime`).                                                                                                                |
+
+
diff --git a/docs/languages/motoko/reference/error-codes.md b/docs/languages/motoko/reference/error-codes.md
index df716e3f..cab2c229 100644
--- a/docs/languages/motoko/reference/error-codes.md
+++ b/docs/languages/motoko/reference/error-codes.md
@@ -17,7 +17,7 @@ title: "Error code reference"
 | M0030 | Type field does not exist in type. | ```type Person = { name : Text }; func getName(p : Person) : Nat { p.age }``` | The field `age` doesn't exist in the `Person` type. |
 | M0031 | Shared function has non-shared parameter type. | ```public shared func process(obj : { var count : Nat }) { ... }``` | Shared functions cannot have mutable types as parameters. |
 | M0032 | Shared function has non-shared return type. | ```public shared func getData() : { var data : [Nat] } { ... }``` | Shared functions cannot return mutable types. |
-| M0033 | Async has non-shared content type. | ```async { var counter = 0 }``` | Async blocks cannot contain mutable [state](/languages/motoko/fundamentals/state). |
+| M0033 | Async has non-shared content type. | ```async { var counter = 0 }``` | Async blocks cannot contain mutable [state](/languages/motoko/fundamentals/actors/state). |
 | M0036 | Invalid return type for shared query function. | ```public shared query func getUsers() : async [User] { ... }``` | Query functions cannot return async types. |
 | M0038 | Misplaced await. | ```func compute() { let x = await promise; }``` | `await` can only be used in an async function or block. |
 | M0045 | Wrong number of type arguments. | ```func process(x : Array) { ... }``` | `Array` type expects one type parameter, not two. |
@@ -33,7 +33,7 @@ title: "Error code reference"
 | M0082 | Expected iterable type. | ```for (item in 42) { ... }``` | The value `42` is not an iterable type for a for-loop. |
 | M0088 | Expected async type. | ```let result = await 42;``` | Cannot `await` on a non-async value. |
 | M0089 | Redundant ignore. | ```ignore (5);``` | The `ignore` is unnecessary for a value that doesn't need to be ignored. |
-| M0090 | Actor reference must have an [actor](/languages/motoko/fundamentals/actors-async) type .| ```let a = actor { ... }; a.someMethod();``` | The variable `a` must have an explicit [actor](/languages/motoko/fundamentals/actors-async) type to call its methods. |
+| M0090 | Actor reference must have an [actor](/languages/motoko/fundamentals/actors/actors-async) type .| ```let a = actor { ... }; a.someMethod();``` | The variable `a` must have an explicit [actor](/languages/motoko/fundamentals/actors/actors-async) type to call its methods. |
 | M0096 | Expression can't produce expected type. | ```func getValue() : Bool { return "true"; }``` | String cannot be returned where a [`Bool`](https://mops.one/core/docs/Bool) is expected. |
 | M0097 | Expected function type. | ```let x = 5; x();``` | Cannot call a non-function value. |
 | M0098 | Cannot instantiate function type. | ```type Func = (Nat) -> Nat; let f = Func();``` | Function types cannot be instantiated directly. |
@@ -44,8 +44,8 @@ title: "Error code reference"
 | M0139 | Inner actor classes are not supported. | ```class Outer() { actor class Inner() { ... } }``` | Actor classes cannot be nested inside other classes. |
 | M0141 | Forbidden declaration in program. | ```import Prim "mo:prim";``` | Certain imports/declarations are not allowed in normal user code. |
 | M0145 | Pattern does not cover value. | ```switch (option) { case (null) { ... } };``` (missing `?some` case) | Switch statement doesn't handle all possible values. |
-| M0149 | An immutable [record](/languages/motoko/fundamentals/records) field (declared without `var`) was supplied where a mutable [record](/languages/motoko/fundamentals/records) field (specified with `var`), was expected. | ```type Mutable = { var x : Nat }; func set(r : Mutable) { ... }; set({ x = 10 });``` | Immutable [record](/languages/motoko/fundamentals/records) provided where mutable was expected. |
-| M0150 | A mutable [record](/languages/motoko/fundamentals/records) field (declared with `var`) was supplied where an immutable [record](/languages/motoko/fundamentals/records) field (specified without `var`) was expected. | ```type Immutable = { x : Nat }; let record : Immutable = { var x = 10 };``` | Mutable field provided where immutable was expected. |
+| M0149 | An immutable [record](/languages/motoko/fundamentals/types/records) field (declared without `var`) was supplied where a mutable [record](/languages/motoko/fundamentals/types/records) field (specified with `var`), was expected. | ```type Mutable = { var x : Nat }; func set(r : Mutable) { ... }; set({ x = 10 });``` | Immutable [record](/languages/motoko/fundamentals/types/records) provided where mutable was expected. |
+| M0150 | A mutable [record](/languages/motoko/fundamentals/types/records) field (declared with `var`) was supplied where an immutable [record](/languages/motoko/fundamentals/types/records) field (specified without `var`) was expected. | ```type Immutable = { x : Nat }; let record : Immutable = { var x = 10 };``` | Mutable field provided where immutable was expected. |
 | M0151 | A object literal is missing some fields. | ```type Person = { name : Text; age : Nat }; let p : Person = { name = "John" };``` | The `age` field is missing from the object literal. |
 | M0153 | An imported Candid file (.did) mentions types that cannot be represented in Motoko. | ```import Types from "types.did";``` (where `types.did` contains incompatible types) | The imported Candid file contains types that don't map to Motoko types. |
 | M0154 | Deprecation annotation. | ```@deprecated("Use newFunction instead") func oldFunction() { ... }``` | Using a deprecated function or feature that has been marked with `@deprecated`. |
diff --git a/docs/languages/motoko/reference/language-manual.md b/docs/languages/motoko/reference/language-manual.md
new file mode 100644
index 00000000..f766ea5d
--- /dev/null
+++ b/docs/languages/motoko/reference/language-manual.md
@@ -0,0 +1,2999 @@
+---
+sidebar_position: 16
+description: "Motoko language documentation"
+title: "Language reference"
+---
+
+
+
+
+
+This reference page provides technical details of interest to the following audiences:
+
+-   Authors providing the higher-level documentation about the Motoko programming language.
+
+-   Compiler experts interested in the details of Motoko and its compiler.
+
+-   Advanced programmers who want to learn more about the lower-level details of Motoko.
+
+This page is intended to provide complete reference information about Motoko, but this section does not provide explanatory text or usage information. Therefore, this section is typically not suitable for readers who are new to programming languages or who are looking for a general introduction to using Motoko.
+
+In this documentation, the term canister is used to refer to an Internet Computer smart contract.
+
+## Basic language syntax
+
+This section describes the basic language conventions of Motoko.
+
+### Whitespace
+
+Space, newline, horizontal tab, carriage return, line feed and form feed are considered as whitespace. Whitespace is ignored but used to separate adjacent keywords, identifiers and operators.
+
+In the definition of some lexemes, the quick reference uses the symbol `␣` to denote a single whitespace character.
+
+### Comments
+
+Single line comments are all characters following `//` until the end of the same line.
+
+``` motoko no-repl
+// single line comment
+x = 1
+```
+
+Single or multi-line comments are any sequence of characters delimited by `/*` and `*/`:
+
+``` motoko no-repl
+/* multi-line comments
+   look like this, as in C and friends */
+```
+
+Comments delimited by `/*` and `*/` may be nested, provided the nesting is well-bracketed.
+
+``` motoko no-repl
+/// I'm a documentation comment
+/// for a function
+```
+
+Documentation comments start with `///` followed by a space until the end of line, and get attached to the definition immediately following them.
+
+Deprecation comments start with `/// @deprecated` followed by a space until the end of line, and get attached to the definition immediately following them. They are only recognized in front of `public` declarations.
+
+All comments are treated as whitespace.
+
+### Keywords
+
+The following keywords are reserved and may not be used as identifiers:
+
+``` bnf
+actor and assert async async* await await? await* break case
+catch class composite continue debug debug_show do else false flexible
+finally for from_candid func if ignore import implicit in include label let
+loop mixin module not null object or persistent private public query
+return shared stable switch system throw to_candid true transient try
+type var weak while with
+```
+
+### Identifiers
+
+Identifiers are alpha-numeric, start with a letter and may contain underscores:
+
+``` bnf
+   ::= Letter (Letter | Digit | _)*
+Letter ::= A..Z | a..z
+Digit  ::= 0..9
+```
+
+### Integers
+
+Integers are written as decimal or hexadecimal, `Ox`-prefixed natural numbers. Subsequent digits may be prefixed a single, semantically irrelevant, underscore.
+
+``` bnf
+digit ::= ['0'-'9']
+hexdigit ::= ['0'-'9''a'-'f''A'-'F']
+num ::= digit ('_'? digit)*
+hexnum ::= hexdigit ('_'? hexdigit)*
+nat ::= num | "0x" hexnum
+```
+
+Negative integers may be constructed by applying a prefix negation `-` operation.
+
+### Floats
+
+Floating point literals are written in decimal or `Ox`-prefixed hexadecimal scientific notation.
+
+``` bnf
+let frac = num
+let hexfrac = hexnum
+let float =
+    num '.' frac?
+  | num ('.' frac?)? ('e' | 'E') sign? num
+  | "0x" hexnum '.' hexfrac?
+  | "0x" hexnum ('.' hexfrac?)? ('p' | 'P') sign? num
+```
+
+The 'e' (or 'E') prefixes a base 10, decimal exponent; 'p' (or 'P') prefixes a base 2, binary exponent. In both cases, the exponent is in decimal notation.
+
+:::note
+
+The use of decimal notation, even for the base 2 exponent, adheres to the established hexadecimal floating point literal syntax of the `C` language.
+
+:::
+
+### Characters
+
+A character is a single quote (`'`) delimited:
+
+-   Unicode character in UTF-8.
+
+-   `\`-escaped newline, carriage return, tab, single or double quotation mark.
+
+-   `\`-prefixed ASCII character (TBR).
+
+-   or `\u{` hexnum `}` enclosed valid, escaped Unicode character in hexadecimal (TBR).
+
+``` bnf
+ascii ::= ['\x00'-'\x7f']
+ascii_no_nl ::= ['\x00'-'\x09''\x0b'-'\x7f']
+utf8cont ::= ['\x80'-'\xbf']
+utf8enc ::=
+    ['\xc2'-'\xdf'] utf8cont
+  | ['\xe0'] ['\xa0'-'\xbf'] utf8cont
+  | ['\xed'] ['\x80'-'\x9f'] utf8cont
+  | ['\xe1'-'\xec''\xee'-'\xef'] utf8cont utf8cont
+  | ['\xf0'] ['\x90'-'\xbf'] utf8cont utf8cont
+  | ['\xf4'] ['\x80'-'\x8f'] utf8cont utf8cont
+  | ['\xf1'-'\xf3'] utf8cont utf8cont utf8cont
+utf8 ::= ascii | utf8enc
+utf8_no_nl ::= ascii_no_nl | utf8enc
+
+escape ::= ['n''r''t''\\''\'''\"']
+
+character ::=
+  | [^'"''\\''\x00'-'\x1f''\x7f'-'\xff']
+  | utf8enc
+  | '\\'escape
+  | '\\'hexdigit hexdigit
+  | "\\u{" hexnum '}'
+  | '\n'        // literal newline
+
+char := '\'' character '\''
+```
+
+### Text
+
+A text literal is `"`-delimited sequence of characters:
+
+``` bnf
+text ::= '"' character* '"'
+```
+
+Note that a text literal may span multiple lines.
+
+### Literals
+
+``` bnf
+ ::=                                     literals
+                                           natural
+                                         float
+                                          character
+                                          Unicode text
+```
+
+Literals are constant values. The syntactic validity of a literal depends on the precision of the type at which it is used.
+
+## Operators and types
+
+To simplify the presentation of available operators, operators and primitive types are classified into basic categories:
+
+| Abbreviation | Category   | Supported operations             |
+| ------------ | ---------- | ------------------------------- |
+| A            | Arithmetic | Arithmetic operations           |
+| B            | Bitwise    | Bitwise and wrapping operations |
+| O            | Ordered    | Comparison                      |
+| T            | Text       | Concatenation                   |
+
+Some types have several categories. For example, type [`Int`](https://mops.one/core/docs/Int) is both arithmetic (A) and ordered (O) and supports both arithmetic addition (`+`) and relational less than (`<`) amongst other operations.
+
+### Unary operators
+
+| `` | Category |                  |
+| -------- | -------- | ---------------- |
+| `-`      | A        | Numeric negation |
+| `+`      | A        | Numeric identity |
+| `^`      | B        | Bitwise negation |
+
+### Relational operators
+
+|           |          |                                                 |
+| --------- | -------- | ----------------------------------------------- |
+| `` | Category |                                                 |
+| `==`      |          | Equals                                          |
+| `!=`      |          | Not equals                                      |
+| `␣<␣`     | O        | Less than (must be enclosed in whitespace)    |
+| `␣>␣`     | O        | Greater than (must be enclosed in whitespace) |
+| `<=`      | O        | Less than or equal                              |
+| `>=`      | O        | Greater than or equal                           |
+
+Note that equality (`==`) and inequality (`!=`) do not have categories. Instead, equality and inequality are applicable to arguments of all shared types, including non-primitive, compound types such as immutable arrays, records, and variants.
+
+Equality and inequality are structural and based on the observable content of their operands as determined by their static type.
+
+### Numeric binary operators
+
+| `` | Category |                |
+| --------- | -------- | -------------- |
+| `+`       | A        | Addition       |
+| `-`       | A        | Subtraction    |
+| `*`       | A        | Multiplication |
+| `/`       | A        | Division       |
+| `%`       | A        | Modulo         |
+| `**`      | A        | Exponentiation |
+
+### Bitwise and wrapping binary operators
+
+| `` | Category |                                                |
+| --------- | -------- | ---------------------------------------------- |
+| `&`       | B        | Bitwise and                                    |
+| | | B        | Bitwise or                                     |
+| `^`       | B        | Exclusive or                                   |
+| `<<`      | B        | Shift left                                     |
+| `␣>>`     | B        | Shift right (must be preceded by whitespace)   |
+| `<<>`     | B        | Rotate left                                    |
+| `<>>`     | B        | Rotate right                                   |
+| `+%`      | A        | Addition (wrap-on-overflow)                    |
+| `-%`      | A        | Subtraction (wrap-on-overflow)                 |
+| `*%`      | A        | Multiplication (wrap-on-overflow)              |
+| `**%`     | A        | Exponentiation (wrap-on-overflow)              |
+
+### Text operators
+
+| `` | Category |               |
+| --------- | -------- | ------------- |
+| `#`       | T        | Concatenation |
+
+### Assignment operators
+
+| `:=`, `=`, `=` | Category |                                            |
+| --------------------------- | -------- | ------------------------------------------ |
+| `:=`                        | \*       | Assignment (in place update)               |
+| `+=`                        | A        | In place add                               |
+| `-=`                        | A        | In place subtract                          |
+| `*=`                        | A        | In place multiply                          |
+| `/=`                        | A        | In place divide                            |
+| `%=`                        | A        | In place modulo                            |
+| `**=`                       | A        | In place exponentiation                    |
+| `&=`                        | B        | In place logical and                       |
+| |=        | B        | In place logical or                        |
+| `^=`                        | B        | In place exclusive or                      |
+| `<<=`                       | B        | In place shift left                        |
+| `>>=`                       | B        | In place shift right                       |
+| `<<>=`                      | B        | In place rotate left                       |
+| `<>>=`                      | B        | In place rotate right                      |
+| `+%=`                       | B        | In place add (wrap-on-overflow)            |
+| `-%=`                       | B        | In place subtract (wrap-on-overflow)       |
+| `*%=`                       | B        | In place multiply (wrap-on-overflow)       |
+| `**%=`                      | B        | In place exponentiation (wrap-on-overflow) |
+| `#=`                        | T        | In place concatenation                     |
+
+The category of a compound assignment `=`/`=` is given by the category of the operator ``/``.
+
+### Operator and keyword precedence
+
+The following table defines the relative precedence and associativity of operators and tokens, ordered from lowest to highest precedence. Tokens on the same line have equal precedence with the indicated associativity.
+
+| Precedence | Associativity | Token                                                                                                                         |
+| ---------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------- |
+| LOWEST     | none          | `if _ _` (no `else`), `loop _` (no `while`)                                                                                   |
+| (higher)   | none          | `else`, `while`                                                                                                               |
+| (higher)   | right         | `:=`, `+=`, `-=`, `*=`, `/=`, `%=`, `**=`, `#=`, `&=`, |=, `^=`, `<<=`, `>>=`, `<<>=`, `<>>=`, `+%=`, `-%=`, `*%=`, `**%=` |
+| (higher)   | left          | `:`                                                                                                                           |
+| (higher)   | left          | |>                                                                                                          |
+| (higher)   | left          | `or`                                                                                                                          |
+| (higher)   | left          | `and`                                                                                                                         |
+| (higher)   | none          | `==`, `!=`, `<`, `>`, `<=`, `>`, `>=`                                                                                         |
+| (higher)   | left          | `+`, `-`, `#`, `+%`, `-%`                                                                                                     |
+| (higher)   | left          | `*`, `/`, `%`, `*%`                                                                                                           |
+| (higher)   | left          | |                                                                                                           |
+| (higher)   | left          | `&`                                                                                                                           |
+| (higher)   | left          | `^`                                                                                                                           |
+| (higher)   | none          | `<<`, `>>`, `<<>`, `<>>`                                                                                                      |
+| HIGHEST    | left          | `**`, `**%`                                                                                                                   |
+
+### Programs
+
+The syntax of a **program** `` is as follows:
+
+``` bnf
+ ::=             programs
+  ;* ;*
+```
+
+A program is a sequence of imports `;*` followed by a sequence of declarations `;*` that ends with an optional actor or actor class declaration. The actor or actor class declaration determines the main actor, if any, of the program.
+
+Compiled programs must obey the following additional restrictions:
+
+-   A `shared` function can only appear as a public field of an actor or actor class.
+
+-   A program may contain at most one actor or actor class declaration, i.e. the final main actor or actor class.
+
+-   Any main actor class declaration should be anonymous. If named, the class name should not be used as a value within the class and will be reported as an unavailable identifier.
+
+These restrictions are not imposed on interpreted programs.
+
+The last two restrictions are designed to forbid programmatic actor class recursion, pending compiler support.
+
+Note that the parameters of an actor class must have [shared type](#shareability). The parameters of a program’s final actor class provide access to the corresponding canister installation argument(s). The Candid type of this argument is determined by the Candid projection of the Motoko type of the class parameter.
+
+### Imports
+
+The syntax of an **import** `` is as follows:
+
+``` bnf
+ ::=                           imports
+  import  =? 
+
+ ::=
+  ""                      Import module from relative .mo
+  "mo:/"    Import module from package
+  "ic:"                 Import external actor by 
+  "canister:"                 Import external actor by 
+  "blob:file:"            Import literal `Blob` value from 
+```
+
+An import introduces a resource referring to a local source module, module from a package of modules, a canister imported as an actor, or a literal [`Blob`](#type-blob) value. The contents of the resource are bound to ``.
+
+Though typically a simple identifier, ``, `` can also be any composite pattern binding selective components of the resource.
+
+The pattern must be irrefutable.
+
+### Libraries
+
+The syntax of a **library** that can be referenced in an import is as follows:
+
+``` bnf
+ ::=                                               Library
+  ;* module ? (: )? =?            Module
+  ;* ? actor ? class          Actor class
+     ?  (: )? 
+  ;* mixin                            Mixin
+```
+
+A library `` is a sequence of imports `;*` followed by:
+
+-   A named or anonymous module declaration, or
+
+-   A named actor class declaration.
+
+-   An anonymous mixin declaration.
+
+Libraries stored in `.mo` files may be referenced by `import` declarations.
+
+In a module library, the optional name `?` is only significant within the library and does not determine the name of the library when imported. Instead, the imported name of a library is determined by the `import` declaration, giving clients of the library the freedom to choose library names e.g. to avoid clashes.
+
+An actor class library, because it defines both a type constructor and a function with name ``, is imported as a module defining both a type and a function named ``. The name `` is mandatory and cannot be omitted. An actor class constructor is always asynchronous, with return type `async T` where `T` is the inferred type of the class body. Because actor construction is asynchronous, an instance of an imported actor class can only be created in an asynchronous context i.e. in the body of a non-`query` `shared` function, asynchronous function, `async` expression or `async*` expression.
+
+### Declaration syntax
+
+The syntax of a declaration is as follows:
+
+``` bnf
+ ::=                                                               Declaration
+                                                                     Expression
+  let  =                                                        Immutable, trap on match failure
+  let  =  else                                    Immutable, handle match failure
+  var  (: )? =                                              Mutable
+  ?  ? (: )? =?                   Object
+  ? func ? ?  (: )? =?         Function
+  type  ? =                                     Type
+  ? ? ? class                            Class
+    ? ?  (: )? 
+  mixin                                                    Mixin
+  include                                                        Mixin inlusion
+
+ ::=           Object body
+  { ;* }       Field declarations
+
+ ::=         Class body
+  = ?       Object body, optionally binding  to 'this' instance
+                Object body
+
+ ::=
+   persistent? actor
+   module
+   object
+
+ ::=       Parenthetical expression
+  ( ? with ;* )   Parenthetical combination/extension
+```
+
+The syntax of a shared function qualifier with call-context pattern is as follows:
+
+``` bnf
+ ::=
+ composite? query
+
+ ::=
+  shared ? ?
+```
+
+For ``, an absent `?` is shorthand for the wildcard pattern `_`.
+
+``` bnf
+ ::=                                object declaration fields
+  ? ?                            field
+
+ ::=                                      field visibility
+  public
+  private
+  system
+
+ ::=                                     field stability (actor only)
+  stable
+  flexible
+  transient                                      (equivalent to flexible)
+```
+
+The **visibility** qualifier `?` determines the accessibility of every field `` declared by ``:
+
+-   An absent `?` qualifier defaults to `private` visibility.
+
+-   Visibility `private` restricts access to `` to the enclosing object, module or actor.
+
+-   Visibility `public` extends `private` with external access to `` using the dot notation `.`.
+
+-   Visibility `system` extends `private` with access by the run-time system.
+
+-   Visibility `system` may only appear on `func` declarations that are actor fields, and **must not** appear anywhere else.
+
+The **stability** qualifier `` determines the **upgrade** behavior of actor fields:
+
+-   A stability qualifier should appear on `let` and `var` declarations that are actor fields.
+    Within a `persistent` actor or actor class, an absent stability qualifier defaults to `stable`.
+    Within a non-`persistent` actor or actor class, an absent stability qualifier defaults to `flexible` (or `transient`).
+    The keywords `transient` and `flexible` are interchangeable.
+
+-   `` qualifiers must not appear on fields of objects or modules.
+
+-   The pattern in a `stable let  = ` declaration must be simple where, a pattern `pat` is simple if it recursively consists of any of the following:
+
+    -   A variable pattern ``.
+
+    -   An annotated simple pattern ` : `.
+
+    -   A parenthesized simple pattern `(  )`.
+
+### Expression syntax
+
+The syntax of an expression is as follows:
+
+``` bnf
+ ::=                                      Expressions
+                                             Variable
+                                            Literal
+                                      Unary operator
+                                Binary operator
+                                Binary relational operator
+  _                                              Placeholder expression
+   |>                                  Pipe operator
+  ( ,* )                                    Tuple
+   .                                   Tuple projection
+  ?                                         Option injection
+  { ;* }                              Object
+  {  (and )* (with ;+)? }   Object combination/extension
+  # id ?                                    Variant injection
+   .                                    Object projection/member access
+   :=                                  Assignment
+  =                                   Unary update
+   =                            Binary update
+  [ var? ,* ]                               Array
+   [  ]                                Array indexing
+  ? func                   Function expression
+  ?  ?        Function call
+  not                                       Negation
+   and                                 Conjunction
+   or                                  Disjunction
+  if   (else )? Conditional
+  switch  { (case  ;)+ } Switch
+  while                       While loop
+  loop  (while )?             Loop
+  for (  in  )           Iteration
+  label  (: )?            Label
+  break  ?                              Break
+  continue                                   Continue
+  return ?                                  Return
+  ? async           Async expression
+  await                            Await future (only in async)
+  await?                           Await future (only in async) without state commit when completed
+  async*                           Delay an asynchronous computation
+  await*                           Await a delayed computation (only in async)
+  throw                                     Raise an error (only in async)
+  try  catch    Catch an error (only in async)
+  try  finally       Guard with cleanup
+  try  catch   finally 
+                                                 Catch an error (only in async) and cleanup
+  assert                           Assertion
+   :                                   Type annotation
+                                            Declaration
+  ignore                           Ignore value
+  do                                      Block as expression
+  do ?                                    Option block
+   !                                        Null break
+  debug                            Debug expression
+  actor                                     Actor reference
+  to_candid ( ,* )                          Candid serialization
+  from_candid                               Candid deserialization
+  (system  . )                          System actor class constructor
+  (  )                                      Parentheses
+
+ ::=
+  
+  
+
+ ::=
+  { ;* }
+```
+
+### Patterns
+
+The syntax of a pattern is as follows:
+
+``` bnf
+ ::=                                      Patterns
+  _                                              Wildcard
+                                             Variable
+  ?                                   Literal
+  ( ,* )                                    Tuple or brackets
+  { ;* }                              Object pattern
+  #  ?                                  Variant pattern
+  ?                                         Option
+   :                                   Type annotation
+   or                                  Disjunctive pattern
+
+ ::=                                Object pattern fields
+   (: )? =                         Field
+   (: )?                                Punned field
+  type                                       Type field
+```
+
+## Type syntax
+
+Type expressions are used to specify the types of arguments, constraints on type parameters, definitions of type constructors, and the types of sub-expressions in type annotations.
+
+``` bnf
+ ::=                                     Type expressions
+   ?                       Constructor
+  ? { ;* }                 Object
+  { ;* }                               Variant
+  { # }                                         Empty variant
+  [ var?  ]                                Array
+  Null                                          Null type
+  ?                                        Option
+  ? ?  ->         Function
+  async                                    Future
+  async*                                   Delayed, asynchronous computation
+  ( ,* )                              Tuple
+  Any                                           Top
+  None                                          Bottom
+   and                                Intersection
+   or                                 Union
+  Error                                         Errors/exceptions
+  (  )                                     Parenthesized type
+
+                                    Type item
+                                           Simple item
+   :                                   Named item
+  implicit :                               Implicit argument
+
+ ::= (actor | module | object)
+
+ ::=                                 Shared function type qualifier
+  shared ?
+
+ ::=                                   Paths
+                                           Type identifier
+   .                                 Projection
+```
+
+An absent `?` abbreviates `object`.
+
+
+Type items of the form ` (implicit : )` and ` : (implicit : ( : ))` are used to indicate implicit and re-named implicit parameters.  The second form is used to override the parameter named `` as implicit parameter named ``.
+These special type items are only meaningful in parameter positions of function types and have no significance elsewhere.
+
+### Primitive types
+
+Motoko provides the following primitive type identifiers, including support for Booleans, signed and unsigned integers and machine words of various sizes, characters and text.
+
+The category of a type determines the operators (unary, binary, relational and in-place update via assignment) applicable to values of that type.
+
+| Identifier                         | Category | Description                                                            |
+| ---------------------------------- | -------- | ---------------------------------------------------------------------- |
+| [`Bool`](https://mops.one/core/docs/Bool)           | L        | Boolean values `true` and `false` and logical operators                |
+| [`Char`](https://mops.one/core/docs/Char)           | O        | Unicode characters                                                     |
+| [`Text`](https://mops.one/core/docs/Text)           | T, O     | Unicode strings of characters with concatenation `_ # _` and iteration |
+| [`Float`](https://mops.one/core/docs/Float)         | A, O     | 64-bit floating point values                                           |
+| [`Int`](https://mops.one/core/docs/Int)             | A, O     | Signed integer values with arithmetic (unbounded)                      |
+| [`Int8`](https://mops.one/core/docs/Int8)          | A, O     | Signed 8-bit integer values with checked arithmetic                    |
+| [`Int16`](https://mops.one/core/docs/Int16)       | A, O     | Signed 16-bit integer values with checked arithmetic                   |
+| [`Int32`](https://mops.one/core/docs/Int32)       | A, O     | Signed 32-bit integer values with checked arithmetic                   |
+| [`Int64`](https://mops.one/core/docs/Int64)         | A, O     | Signed 64-bit integer values with checked arithmetic                   |
+| [`Nat`](https://mops.one/core/docs/Nat)             | A, O     | Non-negative integer values with arithmetic (unbounded)                |
+| [`Nat8`](https://mops.one/core/docs/Nat8)          | A, O     | Non-negative 8-bit integer values with checked arithmetic              |
+| [`Nat16`](https://mops.one/core/docs/Nat16)      | A, O     | Non-negative 16-bit integer values with checked arithmetic             |
+| [`Nat32`](https://mops.one/core/docs/Nat32)      | A, O     | Non-negative 32-bit integer values with checked arithmetic             |
+| [`Nat64`](https://mops.one/core/docs/Nat64)        | A, O     | Non-negative 64-bit integer values with checked arithmetic             |
+| [`Blob`](https://mops.one/core/docs/Blob)          | O        | Binary blobs with iterators                                            |
+| [`Principal`](https://mops.one/core/docs/Principal) | O        | Principals                                                             |
+| [`Error`](https://mops.one/core/docs/Error)         |          | (Opaque) error values                                                  |
+| [`Region`](https://mops.one/core/docs/Region)       |          | (Opaque) stable memory region objects                                  |
+
+Although many of these types have linguistic support for literals and operators, each primitive type also has an eponymous library in the core package providing related [functions and values](https://mops.one/core). For example, the [`Text`](https://mops.one/core/docs/Text) library provides common functions on `Text` values.
+
+### Type [`Bool`](https://mops.one/core/docs/Bool)
+
+The type [`Bool`](https://mops.one/core/docs/Bool) of category L (Logical) has values `true` and `false` and is supported by one and two branch `if _  (else )?`, `not `, `_ and _` and `_ or _` expressions. Expressions `if`, `and` and `or` are short-circuiting.
+
+
+
+### Type `Char`
+
+A `Char` of category O (Ordered) represents a character as a code point in the unicode character set.
+
+Core package function `Char.toNat32(c)` converts a `Char` value, `c` to its [`Nat32`](https://mops.one/core/docs/Nat32) code point. Function `Char.fromNat32(n)` converts a [`Nat32`](https://mops.one/core/docs/Nat32) value, `n`, in the range *0x0..xD7FF* or *0xE000..0x10FFFF* of valid code points to its `Char` value; this conversion traps on invalid arguments. Function `Char.toText(c)` converts the `Char` `c` into the corresponding, single character [`Text`](https://mops.one/core/docs/Text) value.
+
+### Type [`Text`](https://mops.one/core/docs/Text)
+
+The type [`Text`](https://mops.one/core/docs/Text) of categories T and O (Text, Ordered) represents sequences of unicode characters i.e. strings. Function `t.size` returns the number of characters in [`Text`](https://mops.one/core/docs/Text) value `t`. Operations on text values include concatenation (`_ # _`) and sequential iteration over characters via `t.chars` as in `for (c : Char in t.chars()) { …​ c …​ }`.
+
+
+
+### Type `Float`
+
+The type `Float` represents 64-bit floating point values of categories A (Arithmetic) and O (Ordered).
+
+The semantics of `Float` and its operations is in accordance with standard [IEEE 754-2019](https://ieeexplore.ieee.org/document/8766229) (See [References](#references)).
+
+Common functions and values are defined in the [`Float`](https://mops.one/core/docs/Float) core package.
+
+### Types [`Int`](https://mops.one/core/docs/Int) and [`Nat`](https://mops.one/core/docs/Nat)
+
+The types [`Int`](https://mops.one/core/docs/Int) and [`Nat`](https://mops.one/core/docs/Nat) are signed integral and natural numbers of categories A (Arithmetic) and O (Ordered).
+
+Both [`Int`](https://mops.one/core/docs/Int) and [`Nat`](https://mops.one/core/docs/Nat) are arbitrary precision, with only subtraction `-` on [`Nat`](https://mops.one/core/docs/Nat) trapping on underflow.
+
+The subtype relation `Nat <: Int` holds, so every expression of type [`Nat`](https://mops.one/core/docs/Nat) is also an expression of type [`Int`](https://mops.one/core/docs/Int) but not vice versa. In particular, every value of type [`Nat`](https://mops.one/core/docs/Nat) is also a value of type [`Int`](https://mops.one/core/docs/Int), without change of representation.
+
+### Bounded integers [`Int8`](https://mops.one/core/docs/Int8), [`Int16`](https://mops.one/core/docs/Int16), [`Int32`](https://mops.one/core/docs/Int32) and [`Int64`](https://mops.one/core/docs/Int64)
+
+The types [`Int8`](https://mops.one/core/docs/Int8), [`Int16`](https://mops.one/core/docs/Int16), [`Int32`](https://mops.one/core/docs/Int32) and [`Int64`](https://mops.one/core/docs/Int64) represent signed integers with respectively 8, 16, 32 and 64 bit precision. All have categories A (Arithmetic), B (Bitwise) and O (Ordered).
+
+Operations that may under- or overflow the representation are checked and trap on error.
+
+The operations `+%`, `-%`, `*%` and `**%` provide access to wrap-around, modular arithmetic.
+
+As bitwise types, these types support bitwise operations and (`&`), or (`|`) and exclusive-or (`^`). Further, they can be rotated left (`<<>`), right (`<>>`), and shifted left (`<<`), right (`>>`). The right-shift preserves the two’s-complement sign. All shift and rotate amounts are considered modulo the numbers’s bit width `n`.
+
+Bounded integer types are not in subtype relationship with each other or with other arithmetic types, and their literals need type annotation if the type cannot be inferred from context, e.g. `(-42 : Int16)`.
+
+The corresponding module in the core package provides conversion functions:
+
+- Conversion to [`Int`](https://mops.one/core/docs/Int).
+
+- Checked and wrapping conversions from [`Int`](https://mops.one/core/docs/Int).
+
+- Wrapping conversion to the bounded natural type of the same size.
+
+### Bounded naturals [`Nat8`](https://mops.one/core/docs/Nat8), [`Nat16`](https://mops.one/core/docs/Nat16), [`Nat32`](https://mops.one/core/docs/Nat32) and [`Nat64`](https://mops.one/core/docs/Nat64)
+
+The types [`Nat8`](https://mops.one/core/docs/Nat8), [`Nat16`](https://mops.one/core/docs/Nat16), [`Nat32`](https://mops.one/core/docs/Nat32) and [`Nat64`](https://mops.one/core/docs/Nat64) represent unsigned integers with respectively 8, 16, 32 and 64 bit precision. All have categories A (Arithmetic), B (Bitwise) and O (Ordered).
+
+Operations that may under- or overflow the representation are checked and trap on error.
+
+The operations `+%`, `-%`, `*%` and `**%` provide access to the modular, wrap-on-overflow operations.
+
+As bitwise types, these types support bitwise operations and (`&`), or (`|`) and exclusive-or (`^`). Further, they can be rotated left (`<<>`), right (`<>>`), and shifted left (`<<`), right (`>>`). The right-shift is logical. All shift and rotate amounts are considered modulo the number’s bit width *n*.
+
+The corresponding module in the core package provides conversion functions:
+
+- Conversion to [`Nat`](https://mops.one/core/docs/Nat).
+
+- Checked and wrapping conversions from [`Nat`](https://mops.one/core/docs/Nat).
+
+- Wrapping conversion to the bounded, signed integer type of the same size.
+
+### Type [`Blob`](https://mops.one/core/docs/Blob)
+
+The type [`Blob`](https://mops.one/core/docs/Blob) of category O (Ordered) represents binary blobs or sequences of bytes. Function `b.size()` returns the number of characters in [`Blob`](https://mops.one/core/docs/Blob) value `b`. Operations on blob values include sequential iteration over bytes via function `b.values()` as in `for (v : Nat8 in b.values()) { …​ v …​ }`.
+
+### Type [`Principal`](https://mops.one/core/docs/Principal)
+
+The type [`Principal`](https://mops.one/core/docs/Principal) of category O (Ordered) represents opaque principals such as canisters and users that can be used to identify callers of shared functions and used for simple authentication. Although opaque, principals may be converted to binary [`Blob`](https://mops.one/core/docs/Blob) values for more efficient hashing and other applications.
+
+### Error type
+
+Assuming core package import:
+
+``` motoko no-repl
+import E "mo:core/Error";
+```
+
+Errors are opaque values constructed and examined with operations:
+
+-   `E.reject : Text -> Error`
+
+-   `E.code : Error -> E.ErrorCode`
+
+-   `E.message : Error -> Text`
+
+Type `E.ErrorCode` is equivalent to variant type:
+
+``` motoko no-repl
+type ErrorCode = {
+  // Fatal error.
+  #system_fatal;
+  // Transient error.
+  #system_transient;
+  // Response unknown due to missed deadline.
+  #system_unknown;
+  // Destination invalid.
+  #destination_invalid;
+  // Explicit reject by canister code.
+  #canister_reject;
+  // Canister trapped.
+  #canister_error;
+  // Future error code (with unrecognized numeric code).
+  #future : Nat32;
+  // Error issuing inter-canister call
+  // (indicating destination queue full or freezing threshold crossed).
+  #call_error : { err_code : Nat32 }
+};
+```
+
+A constructed error `e = E.reject(t)` has `E.code(e) = #canister_reject` and `E.message(e) = t`.
+
+[`Error`](https://mops.one/core/docs/Error) values can be thrown and caught within an `async` expression or `shared` function only. See [throw](#throw) and [try](#try).
+
+Errors with codes other than `#canister_reject`, i.e. system errors, may be caught and thrown but not user-constructed.
+
+:::note
+
+Exiting an async block or shared function with a non-`#canister-reject` system error exits with a copy of the error with revised code `#canister_reject` and the original [`Text`](https://mops.one/core/docs/Text) message. This prevents programmatic forgery of system errors.
+
+:::
+
+:::note
+
+On ICP, the act of issuing a call to a canister function can fail, so that the call cannot (and will not be) performed.
+This can happen due to a lack of canister resources, typically because the local message queue for the destination canister is full,
+or because performing the call would reduce the current cycle balance of the calling canister to a level below its freezing threshold.
+Such call failures are reported by throwing an [`Error`](https://mops.one/core/docs/Error) with code `#call_error { err_code = n }`, where `n` is the non-zero `err_code` value returned by ICP.
+Like other errors, call errors can be caught and handled using `try ... catch ...` expressions, if desired.
+
+:::
+
+### Type `Region`
+
+The type `Region` represents opaque stable memory regions. Region objects are dynamically allocated and independently growable. They represent isolated partitions of IC stable memory.
+
+The region type is stable but not shared and its objects, which are stateful, may be stored in stable variables and data structures.
+
+Objects of type `Region` are created and updated using the functions provided by base libary `Region`. See [stable regions](/languages/motoko/icp-features/stable-memory) and library [Region](https://mops.one/core/docs/Region) for more information.
+
+### Constructed types
+
+` ?` is the application of a type identifier or path, either built-in (i.e. [`Int`](https://mops.one/core/docs/Int)) or user defined, to zero or more type arguments. The type arguments must satisfy the bounds, if any, expected by the type constructor’s type parameters (see [Well-formed types](#well-formed-types)).
+
+Though typically a type identifier, more generally, `` may be a `.`-separated sequence of actor, object or module identifiers ending in an identifier accessing a type component of a value (for example, `Acme.Collections.List`).
+
+### Object types
+
+`? { ;* }` specifies an object type by listing its zero or more named **type fields**.
+
+Within an object type, the names of fields must be distinct both by name and hash value.
+
+Object types that differ only in the ordering of the fields are equivalent.
+
+When `?` is `actor`, all fields have `shared` function type for specifying messages.
+
+### Variant types
+
+`{ ;* }` specifies a variant type by listing its variant type fields as a sequence of ``s.
+
+Within a variant type, the tags of its variants must be distinct both by name and hash value.
+
+Variant types that differ only in the ordering of their variant type fields are equivalent.
+
+`{ # }` specifies the empty variant type.
+
+### Array types
+
+`[ var?  ]` specifies the type of arrays with elements of type ``.
+
+Arrays are immutable unless specified with qualifier `var`.
+
+### Null type
+
+The `Null` type has a single value, the literal `null`. `Null` is a subtype of the option `? T`, for any type `T`.
+
+### Option types
+
+`? ` specifies the type of values that are either `null` or a proper value of the form `? ` where `` has type ``.
+
+### Weak reference types
+
+`weak ` specifies the type of weak references to values of type ``.
+
+### Function types
+
+Type `? ?  -> ` specifies the type of functions that consume optional type parameters ``, consume a value parameter of type `` and produce a result of type ``.
+
+Both `` and `` may reference type parameters declared in ``.
+
+If `` or `` or both is a tuple type, then the length of that tuple type determines the argument or result *arity* of the function type.
+The arity is the number of arguments or results a function returns.
+
+The optional `` qualifier specifies whether the function value is shared, which further constrains the form of ``, `` and `` (see [sharability](#shareability) below).
+
+Note that a `` function may itself be `shared` or `shared query` or `shared composite query`, determining the persistence of its state changes.
+
+### Async types
+
+`async ` specifies a future producing a value of type ``.
+
+Future types typically appear as the result type of a `shared` function that produces an `await`-able value.
+
+### Async* types
+
+`async* ` specifies a delayed, asynchronous computation producing a value of type ``.
+
+Computation types typically appear as the result type of a `local` function that produces an `await*`-able value.
+
+They cannot be used as the return types of `shared` functions.
+
+### Tuple types
+
+`( (( :)? ),* )` specifies the type of a tuple with zero or more ordered components.
+
+The optional identifier ``, naming its components, is for documentation purposes only and cannot be used for component access. In particular, tuple types that differ only in the names of components are equivalent.
+
+The empty tuple type `()` is called the *unit type*.
+
+### Any type
+
+Type `Any` is the top type, i.e. the supertype of all types. All values have type `Any`.
+
+### None type
+
+Type `None` is the bottom type, the subtype of all other types. No value has type `None`.
+
+As an empty type, `None` can be used to specify the impossible return value of an infinite loop or unconditional trap.
+
+### Intersection type
+
+The type expression ` and ` denotes the syntactic **intersection** between its two type operands, that is, the greatest type that is a subtype of both. If both types are incompatible, the intersection is `None`.
+
+The intersection is syntactic, in that it does not consider possible instantiations of type variables. The intersection of two type variables is `None`, unless they are equal, or one is declared to be a (direct or indirect) subtype of the other.
+
+### Union type
+
+The type expression ` or ` denotes the syntactic **union** between its two type operands, that is, the smallest type that is a supertype of both. If both types are incompatible, the union is `Any`.
+
+The union is syntactic, in that it does not consider possible instantiations of type variables. The union of two type variables is the union of their bounds, unless the variables are equal, or one is declared to be a direct or indirect subtype of the other.
+
+### Parenthesized type
+
+A function that takes an immediate, syntactic tuple of length `n \>= 0` as its domain or range is a function that takes and respectively returns `n` values.
+
+When enclosing the argument or result type of a function, which is itself a tuple type, `(  )` declares that the function takes or returns a single boxed value of type ``.
+
+In all other positions, `(  )` has the same meaning as ``.
+
+### Type fields
+
+``` bnf
+ ::=                               Object type fields
+   :                                   Immutable value
+  var  :                               Mutable value
+   ?  :             Function value (short-hand)
+  type  ? =           Type component
+```
+
+A type field specifies the name and type of a value field of an object, or the name and definition of a type component of an object. The value field names within a single object type must be distinct and have non-colliding hashes. The type component names within a single object type must also be distinct and have non-colliding hashes. Value fields and type components reside in separate name spaces and thus may have names in common.
+
+` : ` : Specifies an **immutable** field, named `` of type ``.
+
+`var  : ` : Specifies a **mutable** field, named `` of type ``.
+
+`type  ? = ` : Specifies a **type component**, with field name ``, abbreviating parameterized type ``.
+
+Unlike type declarations, a type component is not, in itself, recursive though it may abbreviate an existing recursive type.
+In particular, the name `` is not bound in `` nor in any other fields of the enclosing object type. The name `` only determines the label to use when accessing the definition through a record of this type using the dot notation.
+
+
+### Variant type fields
+
+``` bnf
+ ::=                                 Variant type fields
+  #  :                                 Tag
+  #                                         Unit tag (short-hand)
+```
+
+A variant type field specifies the tag and type of a single variant of an enclosing variant type. The tags within a single variant type must be distinct and have non-colliding hashes.
+
+`#  : ` specifies an immutable field, named `` of type ``. `# ` is sugar for an immutable field, named `` of type `()`.
+
+### Sugar
+
+When enclosed by an `actor` object type, ` ?  : ` is syntactic sugar for an immutable field named `` of `shared` function type `shared ? `.
+
+When enclosed by a non-`actor` object type, ` ?  : ` is syntactic sugar for an immutable field named `` of ordinary function type `? `.
+
+### Type parameters
+
+``` bnf
+ ::=                              Type parameters
+  < typ-param,* >
+
+   <:                                Constrained type parameter
+                                          Unconstrained type parameter
+```
+
+``` bnf
+ ::=                         Type parameters to type constructors
+  < typ-param,* >
+
+ ::=                              Function type parameters
+  < typ-param,* >                             Type parameters
+  < system (, *)) >                System capability prefixed type parameters
+
+
+   <:                                Constrained type parameter
+                                          Unconstrained type parameter
+
+```
+
+A type constructor may be parameterized by a vector of comma-separated, optionally constrained, type parameters.
+
+A function, class constructor or function type may be parameterized by a vector of comma-separated, optionally constrained, type parameters.
+The first of these may be the special, pseudo type parameter `system`.
+
+` <: ` declares a type parameter with constraint ``. Any instantiation of `` must subtype `` at that same instantiation.
+
+Syntactic sugar `` declares a type parameter with implicit, trivial constraint `Any`.
+
+The names of type parameters in a vector must be distinct.
+
+All type parameters declared in a vector are in scope within its bounds.
+
+The `system` pseudo-type parameter on function types indicates that a value of that type requires `system` capability in order to be called and may itself call functions requiring `system` capability during its execution.
+
+### Type arguments
+
+``` bnf
+ ::=                           Type arguments to type constructors
+  < ,* >
+
+
+ ::=                                Type arguments to functions
+  < ,* >                                   Plain type arguments
+  < system (, *) >                         System capability prefixed type arguments
+
+```
+
+Type constructors and functions may take type arguments.
+
+The number of type arguments must agree with the number of declared type parameters of the type constructor.
+
+For a function, the number of type arguments, when provided, must agree with the number of declared type parameters of the function’s type. Note that type arguments in function applications can typically be omitted and inferred by the compiler.
+
+Given a vector of type arguments instantiating a vector of type parameters, each type argument must satisfy the instantiated bounds of the corresponding type parameter.
+
+In function calls, supplying the `system` pseudo type argument grants system capability to the function that requires it.
+
+System capability is available only in the following syntactic contexts:
+
+- In the body of an actor expression or actor class.
+- In the body of a (non-`query`) `shared` function, asynchronous function, `async` expression or `async*` expression.
+- In the body of a function or class that is declared with `system` pseudo type parameter.
+- In system functions `preupgrade` and `postupgrade`.
+
+No other context provides `system` capabilities, including `query` and `composite query` methods.
+
+The `` type parameters of shared and asynchronous functions need not be declared.
+
+
+### Well-formed types
+
+A type `T` is well-formed only if recursively its constituent types are well-formed, and:
+
+-   If `T` is `async U` or `async* U` then `U` is shared, and
+
+-   If `T` is `shared ? U -> V`:
+    - `U` is shared and,
+    - `V == ()` and `?` is absent, or
+    - `V == async W` with `W` shared, and
+
+-   If `T` is `C` where:
+
+    -   A declaration `type C  = …​` is in scope, and
+
+    -   `Ti <: Ui[ T0/X0, …​, Tn/Xn ]`, for each `0 <= i <= n`.
+
+-   If `T` is `actor { …​ }` then all fields in `…​` are immutable and have `shared` function type.
+
+### Subtyping
+
+Two types `T`, `U` are related by subtyping, written `T <: U`, whenever, one of the following conditions is true:
+
+1.   `T` equals `U` (subtyping is *reflexive*).
+
+2.   `U` equals `Any`.
+
+3.   `T` equals `None`.
+
+4.   `T` is a type parameter `X` declared with constraint `U`.
+
+5.   `T` is [`Nat`](https://mops.one/core/docs/Nat) and `U` is [`Int`](https://mops.one/core/docs/Int).
+
+6.   `T` is a tuple `(T0, …​, Tn)`, `U` is a tuple `(U0, …​, Un)`, and for each `0 <= i <= n`, `Ti <: Ui`.
+
+7.   `T` is an immutable array type `[ V ]`, `U` is an immutable array type `[ W ]` and `V <: W`.
+
+8.   `T` is a mutable array type `[ var V ]`, `U` is a mutable array type `[ var W ]` and `V == W`.
+
+9.   `T` is `Null` and `U` is an option type `? W` for some `W`.
+
+10.  `T` is `? V`, `U` is `? W` and `V <: W`.
+
+11.  `T` is `weak V`, `U` is `weak W` and `V <: W`.
+
+12.   `T` is a future `async V`, `U` is a future `async W`, and `V <: W`.
+
+13.   `T` is an object type ` { fts0 }`, `U` is an object type ` { fts1 }` and
+
+      1. `` == ``, and, for all fields,
+
+      2. If field `id : W` is in `fts1` then `id : V` is in `fts0` and `V <: W`, and
+
+      3. If mutable field `var id : W` is in `fts1` then `var id : V` is in `fts0` and `V == W`, and
+
+      4. If type field `type id = V` is in `fts1` then `type id = W` is in `fts0` and `V == W` (up to renaming of type parameters).
+
+      That is, object type `T` is a subtype of object type `U` if they have the same sort, every mutable field in `U` super-types the same field in `T` and every mutable field in `U` is mutable in `T` with an equivalent type. In particular, `T` may specify more fields than `U`.
+      Note that this clause defines subtyping for all sorts of object type, whether `module`, `object` or `actor`.
+
+14.   `T` is a variant type `{ fts0 }`, `U` is a variant type `{ fts1 }` and
+
+       1.   If field `# id : V` is in `fts0` then `# id : W` is in `fts1` and `V <: W`.
+
+       That is, variant type `T` is a subtype of variant type `U` if every field of `T` subtypes the same field of `U`. In particular, `T` may specify fewer variants than `U`.
+
+15.   `T` is a function type `?  T1 -> T2`, `U` is a function type `?  U1 -> U2` and
+
+       1.   `T` and `U` are either both equivalently `?`, and
+
+       2.   Assuming constraints `X0 <: W0, …​, Xn <: Wn` then
+
+            1.   for all `i`, `Wi == Vi`, and
+
+            2.   `U1 <: T1`, and
+
+            3.   `T2 <: U2`.
+
+            That is, function type `T` is a subtype of function type `U` if they have same `?` qualification, they have the same type parameters (modulo renaming) and assuming the bounds in `U`, every bound in `T` supertypes the corresponding parameter bound in `U` (contra-variance), the domain of `T` supertypes the domain of `U` (contra-variance) and the range of `T` subtypes the range of `U` (co-variance).
+
+16.   `T` (respectively `U`) is a constructed type `C` that is equal, by definition of type constructor `C`, to `W`, and `W <: U` (respectively `U <: W`).
+
+17.   `T` (respectively `U`) is an named type typ item `( : W)` that is equal, by definition, to `W`, and `W <: U` (respectively `U <: W`).
+
+18.   For some type `V`, `T <: V` and `V <: U` (*transitivity*).
+
+#### Stable Subtyping
+
+Two types `T`, `U` are related by *stable subtyping*, written `T < U`, (and not to be confused with ordinary subtyping `T <: U`), using the same rules
+as subtyping but replacing occurences of `_ <: _` by `_ < _` and, crucially, excluding rule:
+
+2.   `U` equals `Any`.
+
+And adopting a more restrictive rule for object types:
+
+13.   `T` is an object type ` { fts0 }`, `U` is an object type ` { fts1 }` and
+
+      1. `` == ``, and, for all fields,
+
+      2. Field `id : W` is in `fts1` if, and only if, `id : V` is in `fts0` and `V < W`, and
+
+      3. Mutable field `var id : W` is in `fts1` if, and only if,  `var id : V` is in `fts0` and `V == W`, and
+
+      4. If type field `type id = V` is in `fts1` then `type id = W` is in `fts0` and `V == W` (up to renaming of type parameters).
+
+Note that stable subtyping entails subtyping, i.e. `T < U` implies `T <: U` but is a strictly smaller relation.
+In particular, compared with subtyping, no type other than `Any` is a stable subtype of `Any` and no value field may be dropped from the stable supertype of an object type.
+
+This stricter relation is used to determine the compatibility of stable variables across upgrades while preventing any implicit loss of data that would otherwise
+be allowed by full subtyping.
+
+### Shareability
+
+A type `T` is **shared** if it is:
+
+-   `Any` or `None`, or
+
+-   A primitive type other than [`Error`](https://mops.one/core/docs/Error) and [`Region`](https://mops.one/core/docs/Region), or
+
+-   An option type `? V` where `V` is shared, or
+
+-   A tuple type `(T0, …​, Tn)` where all `Ti` are shared, or
+
+-   An immutable array type `[V]` where `V` is shared, or
+
+-   An `object` type where all fields are immutable and have shared type, or
+
+-   A variant type where all tags have shared type, or
+
+-   A shared function type, or
+
+-   An `actor` type.
+
+### Stability
+
+Stability extends shareability to include mutable types, regions and weak references. More precisely:
+
+A type `T` is **stable** if it is:
+
+-   `Any` or `None`, or
+
+-   A primitive type other than [`Error`](https://mops.one/core/docs/Error), or
+
+-   An option type `? V` where `V` is stable, or
+
+-   An weak reference type `weak V` where `V` is stable, or
+
+-   A tuple type `(T0, …​, Tn)` where all `Ti` are stable, or
+
+-   A (mutable or immutable) array type `[var? V]` where `V` is stable, or
+
+-   An `object` type where all fields have stable type, or
+
+-   A variant type where all tags have stable type, or
+
+-   A shared function type, or
+
+-   An `actor` type.
+
+This definition implies that every shared type is a stable type. The converse does not hold: there are types that are stable but not share, notably types with mutable components.
+
+The types of actor fields declared with the `stable` qualifier must have stable type.
+
+The current value of such a field is preserved upon upgrade, whereas the values of other fields are reinitialized after an upgrade.
+
+Note: the primitive `Region` type is stable.
+
+Note: a weak reference type is stable when its content is stable.
+
+## Static and dynamic semantics
+
+Below is a detailed account of the semantics of Motoko programs.
+
+For each [expression form](#expression-syntax) and each [declaration form](#declaration-syntax), this page summarizes its semantics, both in static terms based on typing and dynamic terms based on program evaluation.
+
+### Programs
+
+A program `;* ;*` has type `T` provided:
+
+-   `;*` has type `T` under the static environment induced by the imports in `;*`.
+
+All type and value declarations within `;*` are mutually-recursive.
+
+A program evaluates by transitively evaluating the imports, binding their values to the identifiers in `;*` and then evaluating the sequence of declarations in `;*`.
+
+### Libraries
+
+Restrictions on the syntactic form of modules means that libraries can have no side-effects.
+
+The imports of a library are local and not re-exported in its interface.
+
+Multiple imports of the same library can be safely deduplicated without loss of side-effects.
+
+#### Module libraries
+
+A library `;* module ? (: )? =? ` is a sequence of imports `;*` followed by a single module declaration.
+
+A library has module type `T` provided:
+
+-   `module ? (: )? =? ` has (module) type `T` under the static environment induced by the imports in `;*`.
+
+A module library evaluates by transitively evaluating its imports, binding their values to the identifiers in `;*` and then evaluating `module ? =? `.
+
+If `(: )?` is present, then `T` must be a subtype of ``.
+
+#### Actor class libraries
+
+The actor class library `;* ` where `` is of the form `? actor class  ?  (: )? ` has type:
+
+``` bnf
+module {
+  type  = T;
+   : (U1,...,Un) -> async T
+}
+```
+
+Provided that the actor class declaration `` has function type `(U1, ...​, Un) -> async T` under the static environment induced by the imports in `;*`.
+
+Notice that the imported type of the function `` must be asynchronous.
+
+An actor class library evaluates by transitively evaluating its imports, binding their values to the identifiers in `;*`, and evaluating the derived module:
+
+``` bnf
+module {
+  
+}
+```
+
+On ICP, if this library is imported as identifier `Lib`, then calling `await Lib.(, ..., )`, installs a fresh instance of the actor class as an isolated IC canister, passing the values of ``, ...​, `` as installation arguments, and returns a reference to a remote actor of type `Lib.`, that is, `T`. Installation is necessarily asynchronous.
+
+
+#### Actor class management
+
+On ICP, the primary constructor of an imported actor class always creates a new principal and installs a fresh instance of the class as the code for that principal.
+While that is one way to install a canister on ICP, it is not the only way.
+
+To provide further control over the installation of actor classes, Motoko endows each imported actor class with an extra, secondary constructor, for use on ICP.
+This constructor takes an additional first argument that tailors the installation. The constructor is only available via special syntax that stresses its
+`system` functionality.
+
+Given some actor class constructor:
+
+``` motoko no-repl
+Lib. : (U1, ...​, Un) -> async T
+```
+
+Its secondary constructor is accessed as `(system Lib.)` with typing:
+
+``` motoko no-repl
+(system Lib.) :
+  { #new : CanisterSettings;
+    #install : Principal;
+    #reinstall : actor {} ;
+    #upgrade : actor {} }  ->
+    (U1, ...​, Un) -> async T
+```
+
+where:
+
+``` motoko no-repl
+  type CanisterSettings = {
+     settings : ?{
+        controllers : ?[Principal];
+        compute_allocation : ?Nat;
+        memory_allocation : ?Nat;
+        freezing_threshold : ?Nat;
+     }
+  }
+```
+
+
+Calling `(system Lib.)()(, ...​, )` uses the first argument ``, a variant value, to control the installation of the canister further. Arguments `(, ..., )` are just the user-declared constructor arguments of types `U1, ..., Un` that would also be passed to the primary constructor.
+
+If `` is:
+
+- `#new s`, where `s` has type `CanisterSettings`:
+
+    - The call creates a fresh ICP principal `p`, with settings `s`, and installs the instance to principal `p`.
+
+- `#install p`, where `p` has type [`Principal`](https://mops.one/core/docs/Principal):
+
+    - The call installs the actor to an already created ICP principal `p`. The principal must be empty, having no previously installed code, or the call will return an error.
+
+-  `#upgrade a`, where `a` has type (or supertype) `actor {}`:
+
+    - The call installs the instance as an upgrade of actor `a`, using its current stable storage to initialize stable variables and stable memory of the new instance.
+
+- `#reinstall a`, where `a` has type (or supertype) `actor {}`:
+
+    - Reinstalls the instance over the existing actor `a`, discarding its stable variables and stable memory.
+
+:::note
+
+On ICP, calling the primary constructor `Lib.` is equivalent to calling the secondary constructor `(system Lib.)` with argument `(#new {settings = null})` i.e. using default settings.
+
+:::
+
+:::note
+
+On ICP, calls to `Lib.` and  `(system Lib.)(#new ...)` must be provisioned with enough cycles for the creation of a new principal. Other call variants will use the cycles of the already allocated principal or actor.
+
+:::
+
+:::danger
+
+The use of `#upgrade a` may be unsafe. Motoko will currently not verify that the upgrade is compatible with the code currently installed at `a`. A future extension may verify compatibility with a dynamic check.
+
+The use of `#reinstall a` may be unsafe. Motoko cannot verify that the reinstall is compatible with the code currently installed in actor `a` even with a dynamic check.
+A change in interface may break any existing clients of `a`. The current state of `a` will be lost.
+
+:::
+
+### Imports and URLs
+
+An import `import  =? ` declares a pattern `` bound to the contents of the text literal ``.
+
+`` is a text literal that designates some resource: a local library specified with a relative path (imported as source), a named module from a named package (imported as source), an external canister, referenced either by numeric canister id or by a named alias (imported as a Motoko actor), or a binary file (imported as a blob).
+
+In detail, if `` is of the form:
+
+-   `""` then `` is bound to the library module defined in file `.mo`. `` is interpreted relative to the absolute location of the enclosing file. Note the `.mo` extension is implicit and should not be included in ``. For example, `import U "lib/Util"` defines `U` to reference the module in local file `./lib/Util.mo`.
+
+-   `"mo:/"` then `` is bound to the library module defined in file `/.mo` in directory `` referenced by package alias ``. The mapping from `` to `` is determined by a compiler command-line argument `--package  `. For example, `import L "mo:core/List"` defines `L` to reference the `List` library in package alias `core`.
+
+-   `"ic:"` then `` is bound to a Motoko actor whose Motoko type is determined by the canister’s IDL interface. The IDL interface of canister `` must be found in file `/.did`. The compiler assumes that `` is specified by command line argument `--actor-idl ` and that file `/.did` exists. For example, `import C "ic:lg264-qjkae"` defines `C` to reference the actor with canister id `lg264-qjkae` and IDL file `lg264-qjkae.did`.
+
+-   `"canister:"` is a symbolic reference to canister alias ``. The compiler assumes that the mapping of `` to `` is specified by command line argument `--actor-alias  ic:`. If so, `"canister:"` is equivalent to `"ic:"` (see above). For example, `import C "canister:counter"` defines `C` to reference the actor otherwise known as `counter`.
+
+-   `"blob:file:"` then `` is bound to a blob containing the contents of the file ``. `` is interpreted relative to the absolute location of the enclosing file. For example, `import image "blob:file:/assets/image.jpg"` defines `image` as the blob with bytes from local file `./assets/image.jpg`. Unlike library imports, `` should include the
+file's extension, if any.
+
+The case sensitivity of file references depends on the host operating system so it is recommended not to distinguish resources by filename casing alone.
+
+When building multi-canister projects with the [IC SDK](https://github.com/dfinity/sdk), Motoko programs can typically import canisters by alias (e.g. `import C "canister:counter"`), without specifying low-level canister ids (e.g. `import C "ic:lg264-qjkae"`). The SDK tooling takes care of supplying the appropriate command-line arguments to the Motoko compiler.)
+
+Sensible choices for `` are identifiers, such as [`Array`](https://mops.one/core/docs/Array), or object patterns like `{ cons; nil = empty }`, which allow selective importing of individual fields, under original or other names.
+
+### Declaration fields
+
+A declaration field `? ? ` defines zero or more fields of an actor or object, according to the set of variables defined by ``.
+
+Any identifier bound by a `public` declaration appears in the type of enclosing object, module or actor and is accessible via the dot notation.
+
+An identifier bound by a `private` or `system` declaration is excluded from the type of the enclosing object, module or actor and thus inaccessible.
+
+In a `persistent` actor or actor class, all declarations are implicitly `stable` unless explicitly declared otherwise.
+In a non-`persistent` actor or actor class, all declarations are implicitly `transient` (equivalently `flexible`) unless explicitly declared otherwise.
+
+The declaration field has type `T` provided:
+
+-   `` has type `T`.
+
+-   If `?` is `stable`  then `T` must be a stable type (see [stability](#stability)).
+
+-   If `?` is absent and the actor or actor class is `persistent`, then `T` must be a stable type (see [stability](#stability)).
+
+Actor fields declared `transient` (or legacy `flexible`) can have any type, but will not be preserved across upgrades.
+
+
+In the absence of any `?` migration expression, sequences of declaration fields are evaluated in order by evaluating their constituent declarations, with the following exception:
+
+  - During an upgrade only, the value of a `stable` declaration is obtained as follows:
+
+    - If the stable declaration was previously declared stable in the retired actor, its initial value is inherited from the retired actor.
+
+    - If the stable declaration was not declared stable in the retired actor, and is thus new, its value is obtained by evaluating ``.
+
+For an upgrade to be safe:
+
+  - Every stable identifier declared with type `T` in the retired actor must be declared stable and of type `U` in the replacement actor and must satisfy `T < U` (stable subtyping).
+
+This condition ensures that every stable variable is either fresh, requiring initialization, or its value can be safely inherited from the retired actor, without any loss of data.
+
+Note that stable variables cannot be implicitly removed across upgrades and cannot be promoted to type `Any`.
+These effects can only be achieved using an explicit [migration expression](#migration-expressions).
+
+
+#### Migration expressions
+
+Actors and actor class declaration may specify a migration expression, using an optional, leading `` expression with a required field named `migration`.
+The value of this field, a function, is applied to the stable variables of an upgraded actor, before initializing any stable fields of the declared actor.
+
+The parenthetical expression must satisfy the following conditions:
+
+* It must be static, that is, have no immediate side effects.
+* Its `migration` field must be present and have a non-shared function type whose domain and codomain are both record types.
+* The domain and the codomain must both be stable.
+* Any field in the codomain must be declared as a stable field in the actor body.
+* The content type of the codomain field must be a subtype of the content type of the actor's stable field.
+
+The migration expression only affects upgrades of the actor and is otherwise ignored during fresh installation of the actor.
+
+On upgrade, the domain of the migration function is used to construct a record of values containing the current contents of the corresponding stable fields
+of the retired actor. If one of the fields is absent, the upgrade traps and is aborted.
+
+Otherwise, we obtain an input record of stable values of the appropriate type.
+
+The migration function is applied to the input record. If the application traps, the upgrade is aborted.
+
+Otherwise, the application produces an output record of stable values whose type is the codomain.
+
+The actor's declarations are evaluated in order by evaluating each declaration as usual except that
+the value of a `stable` declaration is obtained as follows:
+
+- If the stable declaration is present in the codomain, its initial value is obtained from the output record.
+
+- Otherwise, if the stable declaration is not present in the domain and is declared stable in the retired actor,
+  then its initial value is obtained from the retired actor.
+
+- Otherwise, its value is obtained by evaluating the declaration's initalizer.
+
+Thus a stable variable's initializer is run if the variable is not produced by the migration function and either
+consumed by the migration function (by appearing in its domain) or absent in the retired actor.
+
+For the upgrade to be safe:
+
+- Every stable identifier declared with type `U` in the domain of the migration function
+  must be declared stable for some type `T` in the retired actor, with `T < U` (stable subtyping).
+
+- Every stable identifier declared with type `T` in the retired actor, not present in the domain or codomain,
+  and declared stable and of type `U` in the replacement actor, must satisfy `T < U` (stable subtyping).
+
+Thses conditions ensure that every stable variable is either discarded or fresh, requiring initialization,
+or that its value can be safely consumed from the output of migration or the retired actor without loss of date.
+
+The compiler will issue a warning if a migration function appears to be discarding data by consuming a field and not producing it.
+The warnings should be carefully considered to verify any data loss is intentional and not accidental.
+
+#### System fields
+
+The declaration `` of a `system` field must be a manifest `func` declaration with one of the following names and types:
+
+| name          | type                                                          | description         |
+| ------------- | ------------------------------------------------------------- | ------------------- |
+| `heartbeat`   | `() -> async ()`                                              | Heartbeat action    |
+| `timer`       | `(Nat64 -> ()) -> async ()`                                   | Timer action        |
+| `inspect`     | `{ caller : Principal; msg : ; arg : Blob } -> Bool` | Message predicate   |
+| `preupgrade`  | `() -> ()`                                            | Pre upgrade action  |
+| `postupgrade` | `() -> ()`                                            | Post upgrade action |
+
+-   `heartbeat`: When declared, is called on every Internet Computer subnet heartbeat, scheduling an asynchronous call to the `heartbeat` function. Due to its `async` return type, a heartbeat function may send messages and await results. The result of a heartbeat call, including any trap or thrown error, is ignored. The implicit context switch means that the time the heartbeat body is executed may be later than the time the heartbeat was issued by the subnet.
+
+-   `timer`: When declared, is called as a response of the canister global timer's expiration. The canister's global timer can be manipulated with the passed-in function argument of type `Nat64 -> ()` (taking an absolute time in nanoseconds) upon which libraries can build their own abstractions. When not declared (and in absence of the `-no-timer` flag), this system action is provided with default implementation by the compiler (additionally `setTimer` and `cancelTimer` are available as primitives).
+
+-   `inspect`: When declared, is called as a predicate on every Internet Computer ingress message with the exception of HTTP query calls. The return value, a [`Bool`](https://mops.one/core/docs/Bool), indicates whether to accept or decline the given message. The argument type depends on the interface of the enclosing actor (see [inspect](#inspect)).
+
+-   `preupgrade`: When declared, is called during an upgrade, immediately before the current values of the retired actor’s stable variables are transferred to the replacement actor.
+     Its `` type parameter is implicitly assumed and need not be declared.
+
+-   `postupgrade`: When declared, is called during an upgrade, immediately after the replacement actor body has initialized its fields, inheriting values of the retired actors' stable variables, and before its first message is processed. Its `` type parameter is implicitly assumed and need not be declared.
+
+:::danger
+
+Using the pre- and post-upgrade system methods is discouraged. It is error-prone and can render a canister unusable.
+In particular, if a `preupgrade` method traps and cannot be prevented from trapping by other means, then your canister may be left in a state in which it can no longer be upgraded.
+Per best practices, using these methods should be avoided if possible.
+
+:::
+
+These `preupgrade` and `postupgrade` system methods provide the opportunity to save and restore in-flight data structures, e.g. caches, that are better represented using non-stable types.
+
+During an upgrade, a trap occurring in the implicit call to `preupgrade()` or `postupgrade()` causes the entire upgrade to trap, preserving the pre-upgrade actor.
+
+##### `inspect`
+
+Given a record of message attributes, this function produces a [`Bool`](https://mops.one/core/docs/Bool) that indicates whether to accept or decline the message by returning `true` or `false`. The function is invoked by the system on each ingress message issue as an ICP update call, excluding non-replicated query calls. Similar to a query, any side-effects of an invocation are transient and discarded. A call that traps due to some fault has the same result as returning `false` message denial.
+
+The argument type of `inspect` depends on the interface of the enclosing actor. In particular, the formal argument of `inspect` is a record of fields of the following types:
+
+-   `caller : Principal`: The principal, possibly anonymous, of the caller of the message.
+
+-   `arg : Blob`: The raw, binary content of the message argument.
+
+-   `msg : `: A variant of decoding functions, where ` == {…​; #: () → T; …​}` contains one variant per `shared` or `shared query` function, ``, of the actor.
+    The variant’s tag identifies the function to be called; The variant’s argument is a function that, when applied, returns the (decoded) argument of the call as a value of type `T`.
+
+Using a variant, tagged with `#`, allows the return type, `T`, of the decoding function to vary with the argument type (also `T`) of the shared function ``.
+
+The variant’s argument is a function so that one can avoid the expense of message decoding when appropriate.
+
+:::danger
+
+An actor that fails to declare system field `inspect` will simply accept all ingress messages.
+
+:::
+
+:::note
+
+Any `shared composite query` function in the interface is *not* included in `` since, unlike a `shared query`, it can only be invoked as a non-replicated query call, never as an update call.
+
+:::
+
+### Sequence of declarations
+
+A sequence of declarations `;*` occurring in a block, a program or embedded in the `;*` sequence of an object body has type `T` provided:
+
+-   `;*` is empty and `T == ()`, or
+
+-   `;*` is non-empty and:
+
+    -   All value identifiers bound by `;*` are distinct.
+
+    -   All type identifiers bound by `;*` are distinct.
+
+    -   Under the assumption that each value identifier `` in `;*` has type `var_id? Tid`, and assuming the type definitions in `;*`:
+
+        -   Each declaration in `;*` is well-typed,.
+
+        -   Each value identifier `` in bindings produced by `;*` has type `var_id? Tid`.
+
+        -   All but the last `` in `;*` of the form `` has type `()`.
+
+        -   The last declaration in `;*` has type `T`.
+
+Declarations in `;*` are evaluated sequentially. The first declaration that traps causes the entire sequence to trap. Otherwise, the result of the declaration is the value of the last declaration in `;*`. In addition, the set of value bindings defined by `;*` is the union of the bindings introduced by each declaration in `;*`.
+
+It is a compile-time error if any declaration in `;*` might require the value of an identifier declared in `;*` before that identifier’s declaration has been evaluated. Such use-before-define errors are detected by a simple, conservative static analysis not described here.
+
+### Patterns
+
+Patterns bind function parameters, declare identifiers and decompose values into their constituent parts in the cases of a `switch` expression.
+
+Matching a pattern against a value may succeed, binding the corresponding identifiers in the pattern to their matching values, or fail. Thus the result of a match is either a successful binding, mapping identifiers of the pattern to values, or failure.
+
+The consequences of pattern match failure depends on the context of the pattern.
+
+-   In a function application or `let`-binding, failure to match the formal argument pattern or `let`-pattern causes a trap.
+
+-   In a `case` branch of a `switch` expression, failure to match that case’s pattern continues with an attempt to match the next case of the switch, trapping only when no such case remains.
+
+### Wildcard pattern
+
+The wildcard pattern `_` matches a single value without binding its contents to an identifier.
+
+### Identifier pattern
+
+The identifier pattern `` matches a single value and binds it to the identifier ``.
+
+### Literal pattern
+
+The literal pattern `? ` matches a single value against the constant value of literal `` and fails if they are not structurally equal values.
+
+For integer literals only, the optional `` determines the sign of the value to match.
+
+### Tuple pattern
+
+The tuple pattern `( ,* )` matches a n-tuple value against an n-tuple of patterns where both the tuple and pattern must have the same number of items. The set of identifiers bound by each component of the tuple pattern must be distinct.
+
+The empty tuple pattern `()` is called the **unit pattern**.
+
+Pattern matching fails if one of the patterns fails to match the corresponding item of the tuple value. Pattern matching succeeds if every pattern matches the corresponding component of the tuple value. The binding returned by a successful match is the disjoint union of the bindings returned by the component matches.
+
+### Object pattern
+
+The object pattern `{ ;* }` matches an object value, a collection of named field values and named type fields, against a sequence of named pattern fields. The set of identifiers bound by each field of the object pattern must be distinct. The names of the pattern fields in the object pattern must be distinct.
+
+A type `` binds a type component from the matched object for the containing block.
+
+Object patterns support punning for concision. A punned field `` is shorthand for ` = `. Similarly, a typed, punned field ` : ` is short-hand for ` =  : `. Both bind the matched value of the field named `` to the identifier ``.
+
+Pattern matching fails if one of the pattern fields fails to match the corresponding field value of the object value. Pattern matching succeeds if every pattern field matches the corresponding named field of the object value. The binding returned by a successful match is the union of the bindings returned by the field matches.
+
+The `` of the matched object type must be determined by an enclosing type annotation or other contextual type information.
+
+### Variant pattern
+
+The variant pattern `#  ?` matches a variant value (of the form `#  v`) against a variant pattern. An absent `?` is shorthand for the unit pattern (`()`). Pattern matching fails if the tag `` of the value is distinct from the tag `` of the pattern (i.e. `` \<\> ``); or the tags are equal but the value `v` does not match the pattern `?`. Pattern matching succeeds if the tag of the value is `` (i.e. `` = ``) and the value `v` matches the pattern `?`. The binding returned by a successful match is just the binding returned by the match of `v` against `?`.
+
+### Annotated pattern
+
+The annotated pattern ` : ` matches value of `v` type `` against the pattern ``.
+
+` : ` is not a dynamic type test, but is used to constrain the types of identifiers bound in ``, e.g. in the argument pattern to a function.
+
+### Option pattern
+
+The option `? ` matches a value of option type `? `.
+
+The match fails if the value is `null`. If the value is `? v`, for some value `v`, then the result of matching `? ` is the result of matching `v` against ``.
+
+Conversely, the `null` literal pattern may be used to test whether a value of option type is the value `null` and not `? v` for some `v`.
+
+### Or pattern
+
+The or pattern ` or ` is a disjunctive pattern.
+
+The result of matching ` or ` against a value is the result of matching ``, if it succeeds, or the result of matching ``, if the first match fails.
+
+An `or`-pattern may contain identifier (``) patterns with the restriction that both alternatives must bind the same set of identifiers. Each identifier's type is the least upper bound of its type in `` and ``.
+
+### Expression declaration
+
+The declaration `` has type `T` provided the expression `` has type `T` . It declares no bindings.
+
+The declaration `` evaluates to the result of evaluating `` typically for ``'s side-effect.
+
+Note that if `` appears within a sequence of declarations, but not as the last declaration of that sequence, then `T` must be `()`.
+
+### Let declaration
+
+The `let` declaration `let  = ` has type `T` and declares the bindings in `` provided:
+
+-   `` has type `T`, and
+
+-   `` has type `T`.
+
+The declaration `let  = ` evaluates `` to a result `r`. If `r` is `trap`, the declaration evaluates to `trap`. If `r` is a value `v` then evaluation proceeds by matching the value `v` against ``. If matching fails, then the result is `trap`. Otherwise, the result is `v` and the binding of all identifiers in `` to their matching values in `v`.
+
+All bindings declared by a `let` if any are immutable.
+
+### Let-else declaration
+
+The `let-else` declaration `let  =  else ` has type `T` and declares the bindings in `` provided:
+
+-   `` has type `T`,
+
+-   `` has type `T`, and
+
+-   `` has type `None`.
+
+The declaration `let  =  else ` evaluates `` to a result `r`.
+If `r` is `trap`, the declaration evaluates to `trap`.
+If `r` is a value `v` then evaluation proceeds by matching the value `v` against ``.
+If matching succeeds, the result is `v` and the binding of all identifiers in `` to their matching values in `v`.
+
+If matching fails, then evaluation continues with ``, which, having type `None`, cannot proceed to the end of the declaration but may still alter control-flow to, for example `return` or `throw` to exit an enclosing function, `break` from an enclosing expression or simply diverge.
+
+All bindings declared by a `let-else` if any are immutable.
+
+#### Handling pattern match failures
+
+In the presence of refutable patterns, the pattern in a `let` declaration may fail to match the value of its expression.
+In such cases, the `let`-declaration will evaluate to a trap.
+The compiler emits a warning for any `let`-declaration than can trap due to pattern match failure.
+
+Instead of trapping, a user may want to explicitly handle pattern match failures.
+The `let-else` declaration, `let  =  else `, has mostly identical static and dynamic semantics to `let`,
+but diverts the program's control flow to `` when pattern matching fails, allowing recovery from failure.
+The `else` expression, ``, must have type `None` and typically exits the declaration using imperative control flow
+constructs such as `throw`, `return`, `break` or non-returning functions such as `Debug.trap(...)` that all produce a result of type `None`.
+Any compilation warning that is produced for a `let` can be silenced by handling the potential pattern-match failure using `let-else`.
+
+### Var declaration
+
+The variable declaration `var  (: )? = ` declares a mutable variable `` with initial value ``. The variable’s value can be updated by assignment.
+
+The declaration `var ` has type `()` provided:
+
+-   `` has type `T`; and
+
+-   If the annotation `(:)?` is present, then `T` == ``.
+
+Within the scope of the declaration, `` has type `var T` (see [Assignment](#assignment)).
+
+Evaluation of `var  (: )? = ` proceeds by evaluating `` to a result `r`. If `r` is `trap`, the declaration evaluates to `trap`. Otherwise, the `r` is some value `v` that determines the initial value of mutable variable ``. The result of the declaration is `()` and `` is bound to a fresh location that contains `v`.
+
+### Type declaration
+
+The declaration `type  ? = ` declares a new type constructor ``, with optional type parameters `` and definition ``.
+
+The declaration `type C< X0 <: T0, …​, Xn <: Tn > = U` is well-formed provided:
+
+-   Type parameters `X0`, …​, `Xn` are distinct, and
+
+-   Assuming the constraints `X0 <: T0`, …​, `Xn <: Tn`:
+
+    -   Constraints `T0`, …​, `Tn` are well-formed.
+
+    -   Definition `U` is well-formed.
+
+    -   It is productive (see [Productivity](#productivity)).
+
+    -   It is non-expansive (see [Expansiveness](#expansiveness)).
+
+In scope of the declaration `type C< X0<:T0, …​, Xn <: Tn > = U`, any well-formed type `C< U0, …​, Un >` is equivalent to its expansion `U [ U0/X0, …​, Un/Xn ]`. Distinct type expressions that expand to identical types are inter-changeable, regardless of any distinction between type constructor names. In short, the equivalence between types is structural, not nominal.
+
+#### Productivity
+
+A type is **productive** if recursively expanding any outermost type constructor in its definition eventually produces a type other than the application of a type constructor.
+
+Motoko requires all type declarations to be productive.
+
+For example, the following type definitions are all productive and legal:
+
+``` motoko no-repl
+  type Person = { first : Text; last : Text };
+
+  type List = ?(T, List);
+
+  type Fst = T;
+
+  type Ok = Fst>;
+```
+
+But in contrast, the following type definitions are all non-productive, since each definition will enter a loop after one or more expansions of its body:
+
+``` motoko no-repl
+  type C = C;
+
+  type D = D;
+
+  type E = F;
+  type F = E;
+
+  type G = Fst, Any>;
+```
+
+
+#### Expansiveness
+
+A set of mutually recursive type or class declarations will be rejected if the set is **expansive**.
+
+Expansiveness is a syntactic criterion. To determine whether a set of singly or mutually recursive type definitions is expansive, for example:
+
+``` motoko no-repl
+  type C<...,Xi,...> = T;
+  ...
+  type D<...,Yj,...> = U;
+```
+
+Take these definitions and construct a directed graph whose vertices are the formal type parameters identified by position, `C#i`, with the following `{0,1}`-labeled edges:
+
+-   For each occurrence of parameter `C#i` as immediate, `j`-th argument to type `D<…​,C#i,…​>`, add a **non-expansive**, `0`-labeled edge,`C#i -0-> D#j`.
+
+-   For each occurrence of parameter `C#i` as a proper sub-expression of the `j`-th argument to type `D<…​,T[C#i],..>` add an **expansive** `1`-labeled edge, `C#i -1-> D#j`.
+
+The graph is expansive if, and only if, it contains a cycle with at least one expansive edge.
+
+For example, the type definition that recursively instantiates `List` at the same parameter `T`, is non-expansive and accepted:
+
+``` motoko no-repl
+  type List = ?(T, List);
+```
+
+A similar looking definition that recursively instantiates `Seq` with a larger type, `[T]`, containing `T`, is expansive and rejected:
+
+``` motoko no-repl
+  type Seq = ?(T, Seq<[T]>);
+```
+
+-   Type `List` is non-expansive because its graph, `{ List#0 -0-> List#0 }`, though cyclic, has no expansive edge.
+
+-   Type `Seq`, on the other hand, is expansive, because its graph, `{ Seq#0 -1-> Seq#0 }`, has a cycle that includes an expansive edge.
+
+### Object declaration
+
+Declaration ` ? (: )? =? `, where `` is of the form `{ ;* }`, declares an object with optional identifier `` and zero or more fields `;*`. Fields can be declared with `public` or `private` visibility; if the visibility is omitted, it defaults to `private`.
+
+The qualifier `` (one of `persistent? actor ?`, `module` or `object`) specifies the `` of the object’s type (`actor`, `module` or `object`, respectively).
+The sort imposes restrictions on the types of the public object fields.
+
+Let `T =  { [var0] id0 : T0, …​ , [varn] idn : T0 }` denote the type of the object. Let `;*` be the sequence of declarations embedded in `;*`. The object declaration has type `T` provided that:
+
+1.  Type `T` is well-formed for sort ``, and
+
+2.  Under the assumption that ` : T`,
+
+    -   The sequence of declarations `;*` has type `Any` and declares the disjoint sets of private and public identifiers, `Id_private` and `Id_public` respectively, with types `T(id)` for `id` in `Id == Id_private union Id_public`, and
+
+    -   `{ id0, …​, idn } == Id_public`, and
+
+    -   For all `i in 0 <= i <= n`, `[vari] Ti == T(idi)`.
+
+3.  If `` is `module`, then the declarations in `;*` must be *static* (see [static declarations](#static-declarations)).
+
+Note that the first requirement imposes further constraints on the field types of `T`. In particular, if the sort is `actor` then:
+
+-   All public fields must be non-`var` immutable `shared` functions. The public interface of an actor can only provide asynchronous messaging via shared functions.
+
+Because actor construction is asynchronous, an actor declaration can only occur in an asynchronous context, i.e. in the body of a non-`` `shared` function, `async` expression or `async*` expression.
+
+Evaluation of `? ? =? { ;* }` proceeds by binding ``, if present, to the eventual value `v`, and evaluating the declarations in `;*`. If the evaluation of `;*` traps, so does the object declaration. Otherwise, `;*` produces a set of bindings for identifiers in `Id`. let `v0`, …​, `vn` be the values or locations bound to identifiers ``, …​, ``. The result of the object declaration is the object `v ==  {  = v1, …​,  = vn}`.
+
+If `?` is present, the declaration binds `` to `v`. Otherwise, it produces the empty set of bindings.
+
+If `(: )?` is present, then `T` must be a subtype of ``.
+
+:::danger
+
+Actor declaration is implicitly asynchronous and the state of the enclosing actor may change due to concurrent processing of other incoming actor messages. It is the programmer’s responsibility to guard against non-synchronized state changes.
+
+:::
+
+#### Static declarations
+
+A declaration is **static** if it is:
+
+-   A `type` declaration.
+
+-   A `class` declaration.
+
+-   A `let` declaration with a static pattern and a static expression.
+
+-   A module, function or object declaration that de-sugars to a static `let` declaration.
+
+-   A static expression.
+
+An expression is static if it is:
+
+-   A literal expression.
+
+-   A tuple of static expressions.
+
+-   An object of static expressions.
+
+-   A variant or option with a static expression.
+
+-   An immutable array.
+
+-   Field access and projection from a static expression.
+
+-   A module expression.
+
+-   A function expression.
+
+-   A static declaration.
+
+-   An `ignore` of a static expression.
+
+-   A block, all of whose declarations are static.
+
+-   A type annotation with a static expression.
+
+A pattern is static if it is:
+
+-   An identifier.
+
+-   A wildcard.
+
+-   A tuple of static patterns.
+
+-   Type annotation with a static pattern.
+
+
+
+Static phrases are designed to be side-effect free, allowing the coalescing of duplicate library imports.
+
+### Function declaration
+
+The function declaration `? func ? ?  (: )? =? ` is syntactic sugar for a named `let` or anonymous declaration of a function expression.
+
+That is, when `?` is present and the function is named:
+
+``` bnf
+? func  ?  (: )? =?  :=
+  let  = ? func ?  (: )? =? 
+```
+
+But when `?` is absent and the function is anonymous:
+
+``` bnf
+? func ?  (: )? =?  :=
+  ? func ?  (: )? =? 
+```
+
+Named function definitions support recursion, i.e. a named function can call itself.
+
+:::note
+
+In compiled code, `shared` functions can only appear as public actor fields.
+
+:::
+
+### Class declaration
+
+The class declaration `? ? class ? ?  (: )? ` is sugar for pair of a type and function declaration:
+
+``` bnf
+? ? class  ?  (: )?  :=
+  type  ? =  { ;* };
+  ? func  ?  : async?   =
+    async?  ? 
+```
+
+where:
+
+-   `?`, when present, requires `` == `persistent? actor`, and provides access to the `caller` of an `actor` constructor, and
+
+-   `?` and `?` is the sequence of type identifiers bound by `?`, if any, and
+
+-   `;*` is the set of public field types inferred from `;*`.
+
+-   `` is the object body of ``.
+
+-   `?` is the optional **this** or **self** parameter of ``.
+
+-   `async?` is present, if only if, `` == `persistent? actor`.
+
+Note `?` must not be of the form `shared  ?`: a constructor, unlike a function, cannot be a `query` or `composite query`.
+
+An absent `?` defaults to `shared` when `` = `persistent? actor`.
+
+If `sort` is `persistent? actor`, then:
+
+-   `?` must be absent or empty, such that `actor` classes cannot have type parameters.
+
+-   ``'s type must be shared (see [shareability](#shareability)).
+
+-   `(: )?`, if present, must be of the form `: async T` for some actor type `T`. Actor instantiation is asynchronous.
+
+If `(: )` is present, then the type `  {  ;* }` must be a subtype of the annotation ``. In particular, the annotation is used only to check, but not affect, the inferred type of function ``. `` is just `` erasing any `persistent?` modifier.
+
+The class declaration has the same type as function `` and evaluates to the function value ``.
+
+### Mixin declaration
+
+The mixin declaration `mixin  ` declares a mixin and has no effect.
+It can only occur in the body of a library.
+
+The fields of a mixin are stable unless declared `transient`.
+
+### Mixin inclusion
+
+The mixin inclusion `include  ` instantiates a copy of the (imported) mixin ``
+with the value of argument ``.
+
+Mixin inclusion can only occur in the body of an actor, actor class, or another mixin.
+
+The inclusion extends the environment with all the declarations of the mixin body
+(with their declared visibility and stability modifiers).
+
+### Identifiers
+
+The identifier expression `` has type `T` provided `` is in scope, defined and declared with explicit or inferred type `T`.
+
+The expression `` evaluates to the value bound to `` in the current evaluation environment.
+
+### Literals
+
+A literal has type `T` only when its value is within the prescribed range of values of type `T`.
+
+The literal (or constant) expression `` evaluates to itself.
+
+### Unary operators
+
+The unary operator ` ` has type `T` provided:
+
+-   `` has type `T`, and
+
+-   The category of `` is a category of `T`.
+
+The unary operator expression ` ` evaluates `` to a result. If the result is a value `v`, it returns the result of ` v`. If the result is `trap`, the entire expression results in `trap`.
+
+### Binary operators
+
+The binary operator expression `  ` has type `T` provided:
+
+-   `` has type `T`.
+
+-   `` has type `T`.
+
+-   The category of `` is a category of `T`.
+
+The binary operator expression `  ` evaluates `exp1` to a result `r1`. If `r1` is `trap`, the expression results in `trap`.
+
+Otherwise, `exp2` is evaluated to a result `r2`. If `r2` is `trap`, the expression results in `trap`.
+
+Otherwise, `r1` and `r2` are values `v1` and `v2` and the expression returns the result of `v1  v2`.
+
+### Relational operators
+
+The relational expression `  ` has type [`Bool`](https://mops.one/core/docs/Bool) provided:
+
+-   `` has type `T`.
+
+-   `` has type `T`.
+
+-   `` is equality `==` or inequality `!=`, `T` is shared, and `T` is the least type such that `` and `` have type `T`.
+
+-   Ihe category O (Ordered) is a category of `T` and ``.
+
+The binary operator expression `  ` evaluates `` to a result `r1`. If `r1` is `trap`, the expression results in `trap`.
+
+Otherwise, `exp2` is evaluated to a result `r2`. If `r2` is `trap`, the expression results in `trap`.
+
+Otherwise, `r1` and `r2` are values `v1` and `v2` and the expression returns the Boolean result of `v1  v2`.
+
+For equality and inequality, the meaning of `v1  v2` depends on the compile-time, static choice of `T`. This means that only the static types of `` and `` are considered for equality, and not the run-time types of `v1` and `v2`, which, due to subtyping, may be more precise than the static types.
+
+### Pipe operators and placeholder expressions
+
+The pipe expression ` |> ` binds the value of `` to the special placeholder expression `_`, that can be referenced in `` and recursively in ``.
+Referencing the placeholder expression outside of a pipe operation is a compile-time error.
+
+The pipe expression ` |> ` is just syntactic sugar for a `let` binding to a placeholder identifier, `p`:
+
+``` bnf
+do { let p = ;  }
+```
+
+The placeholder expression `_` is just syntactic sugar for the expression referencing the placeholder identifier:
+
+``` bnf
+p
+```
+
+The placeholder identifier, `p`, is a fixed, reserved identifier that cannot be bound by any other expression or pattern other than a pipe operation, and can only be referenced using the placeholder expression `_`.
+
+`|>` has lowest precedence amongst all operators except `:` and associates to the left.
+
+Judicious use of the pipe operator allows one to express a more complicated nested expression by piping arguments of that expression into their nested positions within that expression.
+
+For example:
+
+``` motoko no-repl
+Iter.range(0, 10) |>
+  Iter.toList _ |>
+    List.filter(_, func n { n % 3 == 0 }) |>
+      { multiples = _ };
+```
+
+This may be a more readable rendition of:
+
+``` motoko no-repl
+{ multiples =
+   List.filter(
+     Iter.toList(Iter.range(0, 10)),
+     func n { n % 3 == 0 }) };
+```
+
+Above, each occurrence of `_` refers to the value of the left-hand-size of the nearest enclosing pipe operation, after associating nested pipes to the left.
+
+Note that the evaluation order of the two examples is different, but consistently left-to-right.
+
+:::note
+
+Although syntactically identical, the placeholder expression is semantically distinct from, and should not be confused with, the wildcard pattern `_`.
+
+Occurrences of the forms can be distinguished by their syntactic role as pattern or expression.
+
+:::
+
+### Tuples
+
+Tuple expression `(, …​, )` has tuple type `(T1, …​, Tn)`, provided ``, …​, `` have types `T1`, …​, `Tn`.
+
+The tuple expression `(, …​, )` evaluates the expressions `exp1` …​ `expn` in order, trapping as soon as some expression `` traps. If no evaluation traps and `exp1`, …​, `` evaluate to values `v1`,…​,`vn` then the tuple expression returns the tuple value `(v1, …​ , vn)`.
+
+The tuple projection ` . ` has type `Ti` provided `` has tuple type `(T1, …​, Ti, …​, Tn)`, `` == `i` and `1 <= i <= n`.
+
+The projection ` . ` evaluates `` to a result `r`. If `r` is `trap`, then the result is `trap`. Otherwise, `r` must be a tuple `(v1,…​,vi,…​,vn)` and the result of the projection is the value `vi`.
+
+The empty tuple expression `()` is called the **unit value**.
+
+### Option expressions
+
+The option expression `? ` has type `? T` provided `` has type `T`.
+
+The literal `null` has type `Null`. Since `Null <: ? T` for any `T`, literal `null` also has type `? T` and signifies the "missing" value at type `? T`.
+
+### Variant injection
+
+The variant injection `#  ` has variant type `{# id T}` provided:
+
+-   `` has type `T`.
+
+The variant injection `# ` is just syntactic sugar for `#  ()`.
+
+The variant injection `#  ` evaluates `` to a result `r`. If `r` is `trap`, then the result is `trap`. Otherwise, `r` must be a value `v` and the result of the injection is the tagged value `#  v`.
+
+The tag and contents of a variant value can be tested and accessed using a [variant pattern](#variant-pattern).
+
+### Objects
+
+Objects can be written in literal form `{ ;* }`, consisting of a list of expression fields:
+
+``` bnf
+ ::=                                Object expression fields
+  var?  (: ) =                     Field
+  var?  (: )                            Punned field
+```
+
+Such an object literal, sometimes called a record, is equivalent to the object declaration `object { ;* }` where the declaration fields are obtained from the expression fields by prefixing each of them with `public let`, or just `public` in case of `var` fields. However, unlike declarations, the field list does not bind each `` as a local name within the literal, i.e., the field names are not in scope in the field expressions.
+
+Object expressions support **punning** for concision. A punned field `` is shorthand for ` = `; Similarly, a typed, punned field ` : ` is short-hand for ` =  : `. Both associate the field named `` with the value of the identifier ``.
+
+### Object combination/extension
+
+Objects can be combined and/or extended using the `and` and `with` keywords.
+
+A record expression `{  (and )* (with ;+)? }` merges the objects or module) specified as base expressions, and augments the result to also contain the specified fields. The `with ;+` clause can be omitted when at least two bases appear and none have common field labels.
+Thus the field list serves to:
+
+-   Disambiguate field labels occurring more than once in the bases.
+-   Define new fields.
+-   Override existing fields and their types.
+-   Add new `var` fields.
+-   Redefine existing `var` fields from some base to prevent aliasing.
+
+The resulting type is determined by the bases' and explicitly given fields' static type.
+
+Any `var` field from some base must be overwritten in the explicit field list. This prevents introducing aliases of `var` fields.
+
+The record expression `{  and ...  with ; ... ; }` has type `T` provided:
+
+-  The record `{ ; ... ; }` has record type `{ field_tys } == { var?  : U1; ... var?  : Um }`.
+
+-  Let `newfields == {  , ...,  }` be the set of new field names.
+
+-   Considering value fields:
+
+    -   Base expression `` has object or module type `sorti { field_tysi } == sorti { var?  : Ti1, …​, var?  : Tik }` where `sorti <> Actor`.
+
+    Let `fields(i) == { , ...,  }` be the set of static field names of base `i`. Then:
+
+    -   `fields(i)` is disjoint from `newfields` (possibly by applying subtyping to the type of ``).
+
+    -   No field in `field_tysi` is a `var` field.
+
+    -  `fields(i)` is disjoint from `fields(j)` for `j < i`.
+
+-   Considering type fields:
+
+    -   Base expression `` has object or module type `sorti { typ_fieldsi } == sorti { type  = … , …, type  = … }` where `sorti <> Actor`.
+
+    -   `typ_fieldsi` _agrees_ with `typ_fieldsj` for `j < i`.
+
+-   `T` is `{ typ_fieldsi fields_tys1 ... typ_fieldsm fields_tysm field_tys }`.
+
+Here, two sequences of type fields agree only when any two type fields of the same name in each sequence have equivalent definitions.
+
+
+
+The record expression `{  and ...  with ; ... ; }` evaluates records `` through `` and `{ exp-field1; ... ) = fi()` if `` is in `fields(i)`, for some `i`, or `f()` if `` is in `newfields`.
+
+### Object projection (member access)
+
+The object projection ` . ` has type `var? T` provided `` has object type `sort { var1?  : T1, …​, var?  : T, …​, var?  : Tn }` for some sort `sort`.
+
+The object projection ` . ` evaluates `` to a result `r`. If `r` is `trap`, then the result is `trap`. Otherwise, `r` must be an object value `{  = v1,…​, id = v, …​,  = vm }` and the result of the projection is the value `w` obtained from value or location `v` in field `id`.
+
+If `var` is absent from `var? T` then the value `w` is just the value `v` of immutable field ``, otherwise:
+
+-   If the projection occurs as the target of an assignment expression then `w` is just `v`, the mutable location in field ``.
+
+-   Otherwise, `w` (of type `T`) is the value currently stored at the mutable location `v` in field ``.
+
+### Special member access
+
+The iterator access ` . ` has type `T` provided `` has type `U`, and `U`,`` and `T` are related by a row of the following table:
+
+|            |                 |                         |                                                 |
+| ---------- | --------------- | ----------------------- | ----------------------------------------------- |
+| U          | ``          | T                       | Description                                     |
+| [`Text`](https://mops.one/core/docs/Text)    | `size`  | [`Nat`](https://mops.one/core/docs/Nat) | Size (or length) in characters        |
+| [`Text`](https://mops.one/core/docs/Text)    | `chars` | `{ next: () -> Char? }` | Character iterator, first to last     |
+|            |                 |                         |                                                 |
+| [`Blob`](https://mops.one/core/docs/Blob)    | `size`  | [`Nat`](https://mops.one/core/docs/Nat) | Size in bytes                         |
+| [`Blob`](https://mops.one/core/docs/Blob)    | `get`   | `Nat -> Nat8`           | Indexed read function                 |
+| [`Blob`](https://mops.one/core/docs/Blob)    | `keys`  | `{ next: () -> Nat? }`  | Index iterator, by ascending index    |
+| [`Blob`](https://mops.one/core/docs/Blob)    | `vals`, `values` | `{ next: () -> Nat8? }` | Byte iterator, first to last |
+|            |                 |                         |                                                 |
+| `[var? T]` | `size`          | [`Nat`](https://mops.one/core/docs/Nat) | Number of elements                              |
+| `[var? T]` | `get`           | `Nat -> T`              | Indexed read function                           |
+| `[var? T]` | `keys`          | `{ next: () -> Nat? }`  | Index iterator, by ascending index              |
+| `[var? T]` | `vals`, `values`| `{ next: () -> T? }`    | Value iterator, by ascending index              |
+| `[var T]`  | `put`           | `(Nat, T) -> ()`        | Indexed write function (mutable arrays only)    |
+
+The projection ` . ` evaluates `` to a result `r`. If `r` is `trap`, then the result is `trap`. Otherwise, `r` must be a value of type `U` and the result of the projection is a value of type `T` whose semantics is given by the Description column of the previous table.
+
+:::note
+
+the `chars`, `vals`, `keys` and `vals` members produce stateful iterator objects than can be consumed by `for` expressions (see [for](#for)).
+
+:::
+
+
+### Assignment
+
+The assignment ` := ` has type `()` provided:
+
+-   `` has type `var T`.
+
+-   `` has type `T`.
+
+The assignment expression ` := ` evaluates `` to a result `r1`. If `r1` is `trap`, the expression results in `trap`.
+
+Otherwise, `exp2` is evaluated to a result `r2`. If `r2` is `trap`, the expression results in `trap`.
+
+Otherwise `r1` and `r2` are respectively a location `v1`, a mutable identifier, an item of a mutable array or a mutable field of an object, and a value `v2`. The expression updates the current value stored in `v1` with the new value `v2` and returns the empty tuple `()`.
+
+### Unary compound assignment
+
+The unary compound assignment `= ` has type `()` provided:
+
+-   `` has type `var T`.
+
+-   ``'s category is a category of `T`.
+
+The unary compound assignment `= ` evaluates `` to a result `r`. If `r` is `trap` the evaluation traps, otherwise `r` is a location storing value `v` and `r` is updated to contain the value ` v`.
+
+### Binary compound assignment
+
+The binary compound assignment ` = ` has type `()` provided:
+
+-   `` has type `var T`.
+
+-   `` has type `T`.
+
+-   ``'s category is a category of `T`.
+
+For binary operator ``, the compound assignment expression ` = ` evaluates `` to a result `r1`. If `r1` is `trap`, the expression results in `trap`. Otherwise, `exp2` is evaluated to a result `r2`. If `r2` is `trap`, the expression results in `trap`.
+
+Otherwise `r1` and `r2` are respectively a location `v1`, a mutable identifier, an item of a mutable array or a mutable field of object, and a value `v2`. The expression updates the current value, `w` stored in `v1` with the new value `w  v2` and returns the empty tuple `()`.
+
+### Arrays
+
+The expression `[ var? ,* ]` has type `[var? T]` provided each expression `` in the sequence `,*` has type T.
+
+The array expression `[ var , …​,  ]` evaluates the expressions `exp0` …​ `expn` in order, trapping as soon as some expression `` traps. If no evaluation traps and `exp0`, …​, `` evaluate to values `v0`,…​,`vn` then the array expression returns the array value `[var? v0, …​ , vn]` of size `n+1`.
+
+### Array indexing
+
+The array indexing expression ` [  ]` has type `var? T` provided:
+
+-   `` has mutable or immutable array type `[var? T1]`.
+
+The expression ` [  ]` evaluates `exp1` to a result `r1`. If `r1` is `trap`, then the result is `trap`.
+
+Otherwise, `exp2` is evaluated to a result `r2`. If `r2` is `trap`, the expression results in `trap`.
+
+Otherwise, `r1` is an array value, `var? [v0, …​, vn]`, and `r2` is a natural integer `i`. If `i > n` the index expression returns `trap`.
+
+Otherwise, the index expression returns the value `v`, obtained as follows:
+
+- If `var` is absent from `var? T` then the value `v` is the constant value `vi`.
+
+Otherwise,
+
+-   If the indexing occurs as the target of an assignment expression then `v` is the `i`-th mutable location in the array.
+
+-   Otherwise, `v` is `vi`, the value currently stored in the `i`-th location of the array.
+
+
+### Dotted function calls
+
+The dotted function call expression `? . ? ` has type `T` provided
+the expanded function call expression `?  ? ` has type `T`,
+where
+
+  * If the projection `.` has some function type then ` = .` and ` = `.
+
+  * Otherwise, the module environment is used to determine an appropriate function `` and argument `` by
+    constructing a set of candidates Cs and disambiguation Ds:
+
+      * If the receiver `` has type `R` and
+      * Cs = { `(, V1[Ts/Xs], a)` | `` has type `module {}` and `.` has type `(self : V1, ..., Va) -> V` and `R <: V1[Ts/Xs]` for `Ts` } and
+      * Ds = { `(, V, a)`  in Cs | for all `(_, W, _)` in Cs, `V <: W` } and
+      * { `(, _, _)` } = Ds and
+
+    Then ` = .` and ` = extend_args(, , a)`.
+
+    Here:
+
+    * `R` is the type of the receiver expression ``.
+    *  Cs is the set of candidate functions `.` in modules named ``, with explicitly name `self` parameter that matches the receiver type `R`.
+    *  Ds is the disambiguated set of candidates, filtered by specifity.
+    * `` is the name of the unique disambiguation, if one exists (that is, when Ds is a singleton set).
+    *  Finally `extend_args` is the following auxilliary function that inserts the receiver into arguments ``, using the candidate's arity `a`:
+
+    ```
+    extend_args( : exp,  : exp, arity : Nat) : exp
+    extend_args(, , 2) = (, )
+    extend_args(, (), arity) = 
+    extend_args(, , ... ), a) = (, , , ..., )
+    ```
+
+The dotted function call expression `? . ? ` evaluates
+as its expanded function call expression `?  ? `.
+
+### Function calls
+
+
+Function types can specify `implicit` parameters.
+The _arity_ of a function is its number of parameters.
+The _implicit arity_ of a function is its number of `implicit` parameters.
+
+An argument expression has arity n if it is a parenthesized sequence of `n` arguments, and arity 1 otherwise.
+
+A function call can either supply a tuple for all parameters, one argument per parameter, or one argument per non-implicit parameter, omitting arguments for all implicit parameters.
+The values of omitted arguments are inferred statically from the context.
+
+The function call expression `?  ? ` has type `T` provided the
+the expanded function call expression `?  ? ` has type `T` where:
+
+-   The function `` has function type `F = ? < X0 <: V0, ..., Xn <: Vn > U1 -> U2`.
+
+-   If `F` has implicit arity 0 then ` = `, otherwise:
+
+    * ` = ( exp21, ..., exp2a )`; and
+    * `a = arity(F) - implicit_arity(F)`; and
+    * ` = ( insert_holes(0 ; U1 ; (exp21,...,exp2a)) )`;
+
+    where `insert_holes` extends the actual arguments list with placeholders `hole(i, , U)` for missing implicit parameters:
+
+    ```
+    insert_holes(n ;  ; ) =
+      
+    insert_holes(n ; ( ( : (implicit : ( : U))), Us) ; ) =
+      hole(n, , U), insert_holes(n + 1 ; Us ; exps)
+    insert_holes(n ; ( ( : (implicit : U)), Us) ; ) =
+      hole(n, , U), insert_holes(n + 1 ; Us ; exps)
+    insert_holes(n ; (U, Us);  (, )) =
+      , insert_holes(n ; Us ; )
+    ```
+
+    (These equations are applied in order; semicolon is just as argument separator.)
+
+-   If `?` is absent but `n > 0` then there exists minimal `T0, …​, Tn` inferred by the compiler such that:
+
+-   Each type argument satisfies the corresponding type parameter's bounds: for each `1 <= i <= n`, `Ti <: [T0/X0, …​, Tn/Xn]Vi`.
+
+-   The argument `` has type `[T0/X0, …​, Tn/Xn]U1`, and
+
+-   `T == [T0/X0, …​, Tn/Xn]U2`.
+
+-   For each `i` in `(0..implicit_arity(F)]`:
+
+      * ` : [T0/X0, …​, Tn/Xn]Ui`; and
+      * `hole(i, , Ui) = `; and
+
+      Otherwise:
+
+      * Cs = { `(, V)` | `` has type `module {}` and `.` has type `V` and `V <: [T0/X0, …​, Tn/Xn]U1` }; and
+      * Ds = { `(, V)`  in Cs | for all `(_, W)` in Cs, `W <: V` }; and
+      * { `(, _)` } = Ds; and
+      * `hole(i, , Ui) = .`.
+
+    Here:
+
+    * `hole(i, , Ui)` is the description of the `ith` hole, a placeholder for an expression `` or `.`.
+    *  `` is the resolution of the hole from the local context, if any;
+    *  Cs is the set of candidate module `` named ``, with type `V` whose field `.` matches hole type `Ui` (after type instantiation).
+    *  Ds is the disambiguated set of candidates, filtered by generality.
+    * `.` is the name of the unique disambiguation, if one exists (that is, when Ds is a singleton set).
+
+The call expression ` ? ` evaluates `` to a result `r1`. If `r1` is `trap`, then the result is `trap`.
+
+Otherwise, `` (the hole expansion of ``) is evaluated to a result `r2`. If `r2` is `trap`, the expression results in `trap`.
+
+Otherwise, `r1` is a function value, `? func   {  }` (for some implicit environment), and `r2` is a value `v2`. If `` is present and of the form `shared ? ` then evaluation continues by matching the record value `{caller = p}` against ``, where `p` is the [`Principal`](https://mops.one/core/docs/Principal) invoking the function, typically a user or canister. Matching continues by matching `v1` against ``. If pattern matching succeeds with some bindings, then evaluation returns the result of `` in the environment of the function value not shown extended with those bindings. Otherwise, some pattern match has failed and the call results in `trap`.
+
+A ``, when present, modifies dynamic attributes of the message send (provided that the return type `T` is of form `async U`, i.e. a future). The recognized attributes are
+- `cycles : Nat` to attach cycles
+- `timeout : Nat32` to introduce a timeout for best-effort message execution.
+
+:::note
+
+The exhaustiveness side condition on `shared` function expressions ensures that argument pattern matching cannot fail (see [functions](#functions)).
+
+:::
+
+:::note
+
+Calls to local functions with `async` return type and `shared` functions can fail due to a lack of canister resources.
+Such failures will result in the call immediately throwing an error with  `code` `#call_error { err_code = n }`, where `n` is the non-zero `err_code` value returned by ICP.
+
+Earlier versions of Motoko would trap in such situations, making it difficult for the calling canister to mitigate such failures.
+Now, a caller can handle these errors using enclosing `try ... catch ...` expressions, if desired.
+
+:::
+
+### Functions
+
+The function expression `? func < X0 <: T0, …​, Xn <: Tn >  (: U2)? =? ` has type `? < X0 <: T0, ..., Xn <: Tn > U1-> U2` if, under the assumption that `X0 <: T0, …​, Xn <: Tn`:
+
+-   `?` is of the form `shared ? ` if and only if `?` is `shared ?` (the `` modifiers must agree, i.e. are either both absent, both `query`, or both `composite query`).
+
+-   All the types in `T0, …​, Tn` and `U2` are well-formed and well-constrained.
+
+-   Pattern `` has *context type* `{ caller : Principal }`.
+
+-   Pattern `` has type `U1`.
+
+-   If the function is `shared` then `` and `` must be exhaustive.
+
+-   Expression `` has type return type `U2` under the assumption that `` has type `U1`.
+
+`? func ?  (: )? =? ` evaluates to a function value denoted `? func ?  = `, that stores the code of the function together with the bindings from the current evaluation environment needed to evaluate calls to the function value.
+
+Note that a `` function may itself be `shared ` or `shared query ` or  `shared composite query `.
+
+-   A `shared ` function may be invoked from a remote caller. Unless causing a trap, the effects on the callee persist beyond completion of the call.
+
+-   A `shared query ` function may be also be invoked from a remote caller, but the effects on the callee are transient and discarded once the call has completed with a result (whether a value or error).
+
+-   A `shared composite query ` function may only be invoked as an ingress message, not from a remote caller.
+    Like a query, the effects on the callee are transient and discarded once the call has completed with a result, whether a value or error.
+    In addition, intermediate state changes made by the call are not observable by any of its own `query`  or `composite query` callees.
+
+
+In either case, `` provides access to a context value identifying the *caller* of the shared function.
+
+:::note
+
+The context type is a record to allow extension with further fields in future releases.
+
+:::
+
+Shared functions have different capabilities dependent on their qualification as `shared`, `shared query` or `shared composite query`.
+
+A `shared` function may call any `shared` or `shared query` function, but no `shared composite query` function.
+A `shared query` function may not call any `shared`, `shared query` or `shared composite query` function.
+A `shared composite query` function may call any `shared query` or `shared composite query` function, but no `shared` function.
+
+All varieties of shared functions may call unshared functions.
+
+Composite queries, though composable, can only be called externally such as from a frontend and cannot be initiated from an actor.
+
+
+### Blocks
+
+The block expression `{ ;* }` has type `T` provided the last declaration in the sequence `;*` has type `T`. All identifiers declared in block must be distinct type identifiers or distinct value identifiers and are in scope in the definition of all other declarations in the block.
+
+The bindings of identifiers declared in `{ dec;* }` are local to the block.
+
+The type system ensures that a value identifier cannot be evaluated before its declaration has been evaluated, precluding run-time errors at the cost of rejection some well-behaved programs.
+
+Identifiers whose types cannot be inferred from their declaration, but are used in a forward reference, may require an additional type annotation (see [annotated pattern](#annotated-pattern)) to satisfy the type checker.
+
+The block expression `{ ;* }` evaluates each declaration in `;*` in sequence (program order). The first declaration in `;*` that results in a trap causes the block to result in `trap`, without evaluating subsequent declarations.
+
+### Do
+
+The do expression `do ` allows the use of a block as an expression, in positions where the syntax would not directly allow a block.
+
+The expression `do ` has type `T` provided `` has type `T`.
+
+The `do` expression evaluates by evaluating `` and returning its result.
+
+### Option block
+
+The option block `do ? ` introduces scoped handling of null values.
+
+The expression `do ? ` has type `?T` provided `` has type `T`.
+
+The `do ? ` expression evaluates `` and returns its result as an optional value.
+
+Within `` the null break expression ` !` exits the nearest enclosing `do ?` block with value `null` whenever `` has value `null`, or continues evaluation with the contents of ``'s option value. (See [Null break](#null-break).)
+
+Option blocks nest with the target of a null break determined by the nearest enclosing option block.
+
+### Null break
+
+The null break expression ` !` invokes scoped handling of null values and returns the contents of an option value or changes control-flow when the value is `null`.
+
+It has type `T` provided:
+
+-   The expression appears in the body, ``, of an enclosing option block of the form `do ? ` (see [option block](#do-opt)).
+
+-   `` has option type `? T`.
+
+The expression ` !` evaluates `` to a result `r`. If `r` is `trap`, then the result is `trap`; if `r` is `null`, execution breaks with value `null` from the nearest enclosing option block of form `do ? `; otherwise, `r` is `? v` and execution continues with value `v`.
+
+### Not
+
+The not expression `not ` has type [`Bool`](https://mops.one/core/docs/Bool) provided `` has type [`Bool`](https://mops.one/core/docs/Bool).
+
+If `` evaluates to `trap`, the expression returns `trap`. Otherwise, `` evaluates to a Boolean value `v` and the expression returns `not v`, the Boolean negation of `v`.
+
+### And
+
+The and expression ` and ` has type [`Bool`](https://mops.one/core/docs/Bool) provided `` and `` have type [`Bool`](https://mops.one/core/docs/Bool).
+
+The expression ` and ` evaluates `exp1` to a result `r1`. If `r1` is `trap`, the expression results in `trap`. Otherwise `r1` is a Boolean value `v`. If `v == false` the expression returns the value `false` (without evaluating ``). Otherwise, the expression returns the result of evaluating ``.
+
+### Or
+
+The or expression ` or ` has type [`Bool`](https://mops.one/core/docs/Bool) provided `` and `` have type [`Bool`](https://mops.one/core/docs/Bool).
+
+The expression ` and ` evaluates `exp1` to a result `r1`. If `r1` is `trap`, the expression results in `trap`. Otherwise `r1` is a Boolean value `v`. If `v == true` the expression returns the value `true` without evaluating ``. Otherwise, the expression returns the result of evaluating ``.
+
+### If
+
+The expression `if   (else )?` has type `T` provided:
+
+-   `` has type [`Bool`](https://mops.one/core/docs/Bool).
+
+-   `` has type `T`.
+
+-   `` is absent and `() <: T`.
+
+-   `` is present and has type `T`.
+
+The expression evaluates `` to a result `r1`. If `r1` is `trap`, the result is `trap`. Otherwise, `r1` is the value `true` or `false`. If `r1` is `true`, the result is the result of evaluating ``. Otherwise, `r1` is `false` and the result is `()` (if `` is absent) or the result of `` (if `` is present).
+
+### Switch
+
+The switch expression `switch  { (case  ;)+ }` has type `T` provided:
+
+-   `exp` has type `U`.
+
+-   For each case `case  ` in the sequence `(case  ;)+`.
+
+-   Pattern `` has type `U`.
+
+-   Expression `` has type `T`.
+
+The expression evaluates `` to a result `r`. If `r` is `trap`, the result is `trap`. Otherwise, `r` is some value `v`. Let `case  ;` be the first case in `(case  ;)+` such that `` matches `v` for some binding of identifiers to values. Then result of the `switch` is the result of evaluating `` under that binding. If no case has a pattern that matches `v`, the result of the switch is `trap`.
+
+### While
+
+The expression `while  ` has type `()` provided:
+
+-   `` has type [`Bool`](https://mops.one/core/docs/Bool).
+
+-   `` has type `()`.
+
+The expression evaluates `` to a result `r1`. If `r1` is `trap`, the result is `trap`. Otherwise, `r1` is the value `true` or `false`. If `r1` is `true`, the result is the result of re-evaluating `while  `. Otherwise, the result is `()`.
+
+### Loop
+
+The expression `loop ` has type `None` provided `` has type `()`.
+
+The expression evaluates `` to a result `r1`. If `r1` is `trap`, the result is `trap`. Otherwise, the result is the result of re-evaluating `loop `.
+
+### Loop-while
+
+The expression `loop  while ` has type `()` provided:
+
+-   `` has type `()`.
+
+-   `` has type [`Bool`](https://mops.one/core/docs/Bool).
+
+The expression evaluates `` to a result `r1`. If `r1` is `trap`, the result is `trap`. Otherwise, evaluation continues with ``, producing result `r2`. If `r2` is `trap` the result is `trap`. Otherwise, if `r2` is `true`, the result is the result of re-evaluating `loop  while `. Otherwise, `r2` is false and the result is `()`.
+
+### For
+
+The iterator expression `for (  in  ) ` has type `()` provided:
+
+-   `` has type `{ next : () → ?T }`.
+
+-   pattern `` has type `T`.
+
+-   expression `` has type `()` (in the environment extended with the bindings of ``).
+
+The `for`-expression is syntactic sugar for the following, where `x` and `l` are fresh identifiers:
+
+``` bnf
+for (  in  )  :=
+  {
+    let x = ;
+    label l loop {
+      switch (x.next()) {
+        case (? ) ;
+        case (null) break l;
+      }
+    }
+  }
+```
+
+In particular, the `for` loop will trap if evaluation of `` traps; as soon as `x.next()` traps, or the value of `x.next()` does not match pattern ``, or when `` traps.
+
+:::note
+
+Although general purpose, `for` loops are commonly used to consume iterators produced by [special member access](#special-member-access) to, for example, loop over the indices (`a.keys()`) or values (`a.values()`) of some array, `a`.
+
+:::
+
+### Label
+
+The label-expression `label  (: )? ` has type `T` provided:
+
+-   `(: )?` is absent and `T` is unit; or `(: )?` is present and `T == `.
+
+-   `` has type `T` in the static environment extended with `label l : T`.
+
+The result of evaluating `label  (: )? ` is the result of evaluating ``.
+
+### Labeled loops
+
+If `` in `label  (: )? ` is a looping construct:
+
+-   `while (exp2) `.
+
+-   `loop  (while ())?`.
+
+-   `for ( in ) `.
+
+The body, ``, of the loop is implicitly enclosed in `label  (…​)` allowing early continuation of the loop by the evaluation of expression `continue `.
+
+`` is a fresh identifier that can only be referenced by `continue `, through its implicit expansion to `break `.
+
+### Break
+
+The expression `break` (without an identifier) is equivalent to `break `, where `` is the implicitly declared label around the innermost loop.
+
+The expression `break ` is equivalent to `break  ()`.
+
+The expression `break  ` has type `None` provided:
+
+-   The label `` is declared with type `label  : T`.
+
+-   `` has type `T`.
+
+The evaluation of `break  ` evaluates `` to some result `r`. If `r` is `trap`, the result is `trap`. If `r` is a value `v`, the evaluation abandons the current computation up to the dynamically enclosing declaration `label  …​` using the value `v` as the result of that labelled expression.
+
+### Continue
+
+The expression `continue` is equivalent to `continue `, where `` is the implicitly declared label around the body of the innermost loop.
+
+The expression `continue ` is equivalent to `break `, where `` is implicitly declared around the bodies of ``-labelled looping constructs (see [labeled loops](#labeled-loops)).
+
+### Return
+
+The expression `return` is equivalent to `return ()`.
+
+The expression `return ` has type `None` provided:
+
+-   `` has type `T`.
+
+-  and either one of:
+
+   -  `T` is the return type of the nearest enclosing function with no intervening `async` expression.
+
+   -  `async T` is the type of the nearest enclosing, perhaps implicit, `async` expression with no intervening function declaration.
+
+
+The `return` expression exits the corresponding dynamic function invocation or completes the corresponding dynamic `async` or `async*` expression with the result of ``.
+
+### Async
+
+The async expression `? async ` has type `async T` provided:
+
+-   `` has type `T`.
+
+-   `T` is shared.
+
+Any control-flow label in scope for `async ` is not in scope for ``. However, `` may declare and use its own, local, labels.
+
+The implicit return type in `` is `T`. That is, the return expression, ``, implicit or explicit, to any enclosed `return ?` expression, must have type `T`.
+
+Evaluation of `async ` queues a message to evaluate `` in the nearest enclosing or top-level actor. It immediately returns a future of type `async T` that can be used to `await` the result of the pending evaluation of ``.
+
+The presence of `` modifies the semantics of the async expression to
+- attach cycles with attribute `cycles : Nat`
+- impose a timeout (observed when awaiting the result) with attribute `timeout : Nat32`.
+
+:::note
+
+Because it involves messaging, evaluating an `async` expression can fail due to a lack of canister resources.
+
+Such failures will result in the call immediately throwing an error with  `code` `#call_error { err_code = n }`, where `n` is the non-zero `err_code` value returned by ICP.
+
+Earlier version of Motoko would trap in such situations, making it difficult for the producer of the async expression to mitigate such failures. Now, the producer can handle these errors using an enclosing `try ... catch ...` expression, if desired.
+
+:::
+
+
+### Await
+
+The `await` expression `await ` has type `T` provided:
+
+-   `` has type `async T`.
+
+-   `T` is shared.
+
+-   The `await` is explicitly enclosed by an `async`-expression or appears in the body of a `shared` function.
+
+Expression `await ` evaluates `` to a result `r`. If `r` is `trap`, evaluation returns `trap`. Otherwise `r` is a future. If the `future` is incomplete, that is, its evaluation is still pending, `await ` suspends evaluation of the neared enclosing `async` or `shared`-function, adding the suspension to the wait-queue of the `future`. Execution of the suspension is resumed once the future is completed, if ever. If the future is complete with value `v`, then `await ` suspends evaluation and schedules resumption of execution with value `v`. If the future is complete with thrown error value `e`, then `await ` suspends evaluation and schedules resumption of execution by re-throwing the error `e`.
+
+Suspending computation on `await`, regardless of the dynamic status of the future, ensures that all tentative state changes and message sends prior to the `await` are committed and irrevocable.
+
+:::danger
+
+Between suspension and resumption of a computation, the state of the enclosing actor may change due to concurrent processing of other incoming actor messages. It is the programmer’s responsibility to guard against non-synchronized state changes.
+
+Using `await` signals that the computation will commit its current state and suspend execution.
+
+:::
+
+:::note
+
+Because it involves additional messaging, an `await` on a completed future can, in rare circumstances, fail due to a lack of canister resources.
+Such failures will result in the call immediately throwing an error with `code` `#call_error { err_code = n }`, where `n` is the non-zero `err_code` value returned by ICP.
+
+The error is produced eagerly, without suspending nor committing state.
+Earlier versions of Motoko would trap in such situations, making it difficult for the consumer of the `await` to mitigate such failures. Now, the consumer can handle these errors by using an enclosing `try ... catch ...` expression, if desired.
+
+:::
+
+### Await?
+
+Similar to `await`, the `await?` expression `await? ` has type `T` provided:
+
+-   `` has type `async T`.
+
+-   `T` is shared.
+
+-   The `await?` is explicitly enclosed by an `async` expression or appears in the body of a `shared` function.
+
+Expression `await? ` evaluates `` to a result `r`. If `r` is `trap`, evaluation returns `trap`. Otherwise `r` is a future. If the `future` is incomplete, that is, its evaluation is still pending, `await? ` suspends evaluation of the neared enclosing `async` or `shared` function, adding the suspension to the wait-queue of the `future`. Execution of the suspension is resumed once the future is completed, if ever.
+If the future is complete with value `v`, then `await? ` immediately continues execution with the value `v`.
+If the future is complete with thrown error value `e`, then `await? ` immediately continues execution by re-throwing the error `e`.
+
+Thus `await?` behaves like `await` on an incomplete future, but does not suspend execution and simply continues when the future is already complete.
+
+This conditional suspension, dependent on the state of the future, enables performance optimization in cases where a definite commit point is not required.
+
+:::danger
+
+As with `await`, between suspension and resumption of a computation, the state of the enclosing actor may change due to concurrent processing of other incoming actor messages. It is the programmer’s responsibility to guard against non-synchronized state changes.
+
+Using `await?` signals that the computation may commit its current state and suspend execution, potentially allowing concurrent modification of state.
+
+:::
+
+
+### Async*
+
+The async expression `async* ` has type `async* T` provided:
+
+-   `` has type `T`.
+
+-   `T` is shared.
+
+Any control-flow label in scope for `async* ` is not in scope for ``. However, `` may declare and use its own, local, labels.
+
+The implicit return type in `` is `T`. That is, the return expression, ``, implicit or explicit, to any enclosed `return ?` expression, must have type `T`.
+
+Evaluation of `async* ` produces a delayed computation to evaluate ``. It immediately returns a value of type `async* T`.
+The delayed computation can be executed using `await*`, producing one evaluation of the computation ``.
+
+:::danger
+
+Note that `async ` has the effect of scheduling a single asynchronous computation of ``, regardless of whether its result, a future, is consumed with an `await`.
+Moreover, each additional consumption by an `await` just returns the previous result, without repeating the computation.
+
+In comparison, `async* `, has no effect until its value is consumed by an `await*`.
+Moreover, each additional consumption by an `await*` will trigger a new evaluation of ``, including repeated effects.
+
+Be careful of this distinction, and other differences, when refactoring code.
+
+:::
+
+:::note
+
+The `async*` and corresponding `await*` constructs are useful for efficiently abstracting asynchronous code into re-useable functions.
+In comparison, calling a local function that returns a proper `async` type requires committing state and suspending execution with each `await` of its result, which can be undesirable.
+
+:::
+
+
+### Await*
+
+The `await*` expression `await* ` has type `T` provided:
+
+-   `` has type `async* T`.
+
+-   `T` is shared.
+
+-   the `await*` is explicitly enclosed by an `async`-expression or appears in the body of a `shared` function.
+
+Expression `await* ` evaluates `` to a result `r`. If `r` is `trap`, evaluation returns `trap`. Otherwise `r` is a delayed computation ``. The evaluation of `await* ` proceeds with the evaluation of ``, executing the delayed computation.
+
+:::danger
+
+During the evaluation of ``, the state of the enclosing actor may change due to concurrent processing of other incoming actor messages. It is the programmer’s responsibility to guard against non-synchronized state changes.
+
+:::
+
+:::note
+
+Unlike `await`, which, regardless of the dynamic status of the future, ensures that all tentative state changes and message sends prior to the `await` are committed and irrevocable, `await*` does not, in itself, commit any state changes, nor does it suspend computation.
+Instead, evaluation proceeds immediately according to ``, the value of ``, committing state and suspending execution whenever `` does, but not otherwise.
+
+:::
+
+:::note
+
+Evaluation of a delayed `async*` block is synchronous while possible, switching to asynchronous when necessary due to a proper `await`.
+
+Using `await*` signals that the computation *may* commit state and suspend execution during the evaluation of ``, that is, that evaluation of `` may perform zero or more proper `await`s and may be interleaved with the execution of other, concurrent messages.
+
+:::
+
+### Throw
+
+The `throw` expression `throw ` has type `None` provided:
+
+-   `` has type [`Error`](https://mops.one/core/docs/Error).
+
+-   The `throw` is explicitly enclosed by an `async`-expression or appears in the body of a `shared` function.
+
+Expression `throw ` evaluates `` to a result `r`. If `r` is `trap`, evaluation returns `trap`. Otherwise `r` is an error value `e`. Execution proceeds from the `catch` clause of the nearest enclosing `try  catch  ` whose pattern `` matches value `e`. If there is no such `try` expression, `e` is stored as the erroneous result of the `async` value of the nearest enclosing `async`, `async*` expression or `shared` function invocation.
+
+### Try
+
+The `try` expression `try  catch  ` has type `T` provided:
+
+-   `` has type `T`.
+
+-   `` has type [`Error`](https://mops.one/core/docs/Error) and `` has type `T` in the context extended with ``.
+
+-   The `try` is explicitly enclosed by an `async`-expression or appears in the body of a `shared` function.
+
+Expression `try  catch  ` evaluates `` to a result `r`. If evaluation of `` throws an uncaught error value `e`, the result of the `try` is the result of evaluating `` under the bindings determined by the match of `e` against `pat`.
+
+:::note
+
+Because the [`Error`](https://mops.one/core/docs/Error) type is opaque, the pattern match cannot fail. Typing ensures that `` is an irrefutable wildcard or identifier pattern.
+
+:::
+
+The `try` expression can be provided with a `finally` cleanup clause to facilitate structured rollback of temporary state changes (e.g. to release a lock).
+The preceding `catch` clause may be omitted in the presence of a `finally` clause.
+
+This form is `try  (catch  )? finally `, and evaluation proceeds as above with the crucial addition that every control-flow path leaving `` or `` will execute the unit-valued `` before the entire `try` expression produces its result. The cleanup expression will additionally also be executed when the processing after an intervening `await` (directly, or indirectly as `await*`) traps.
+
+:::danger
+
+The code within a `finally` block should terminate promptly and not trap.
+A trapping finally block will fail to free its callback table slot which
+can prevent a future upgrade.
+In this situation, the canister should be explicitly stopped before re-attempting the upgrade.
+In addition, care should be taken to release any resources that may have remained acquired due to the trap.
+The canister may be re-started after the upgrade.
+
+:::
+
+
+See [Error type](#error-type).
+
+### Assert
+
+The assert expression `assert ` has type `()` provided `` has type [`Bool`](https://mops.one/core/docs/Bool).
+
+Expression `assert ` evaluates `` to a result `r`. If `r` is `trap` evaluation returns `trap`. Otherwise `r` is a Boolean value `v`. The result of `assert ` is:
+
+-   The value `()`, when `v` is `true`.
+
+-   `trap`, when `v` is `false`.
+
+### Type annotation
+
+The type annotation expression ` : ` has type `T` provided:
+
+-   `` is `T`.
+
+-   `` has type `U` where `U <: T`.
+
+Type annotation may be used to aid the type-checker when it cannot otherwise determine the type of `` or when one wants to constrain the inferred type, `U` of `` to a less-informative super-type `T` provided `U <: T`.
+
+The result of evaluating ` : ` is the result of evaluating ``.
+
+:::note
+
+Type annotations have no-runtime cost and cannot be used to perform the checked or unchecked `down-casts` available in other object-oriented languages.
+
+:::
+
+### Candid serialization
+
+The Candid serialization expression `to_candid ( ,*)` has type [`Blob`](https://mops.one/core/docs/Blob) provided:
+
+-   `(,*)` has type `(T1,…​,Tn)`, and each `Ti` is shared.
+
+Expression `to_candid ( ,* )` evaluates the expression sequence `( ,* )` to a result `r`. If `r` is `trap`, evaluation returns `trap`. Otherwise, `r` is a sequence of Motoko values `vs`. The result of evaluating `to_candid ( ,* )` is some Candid blob `b = encode((T1,...,Tn))(vs)`, encoding `vs`.
+
+The Candid deserialization expression `from_candid ` has type `?(T1,…​,Tn)` provided:
+
+-   `?(T1,…​,Tn)` is the expected type from the context.
+
+-   `` has type [`Blob`](https://mops.one/core/docs/Blob).
+
+-   `?(T1,…​,Tn)` is shared.
+
+Expression `from_candid ` evaluates `` to a result `r`. If `r` is `trap`, evaluation returns `trap`. Otherwise `r` is a binary blob `b`. If `b` Candid-decodes to Candid value sequence `Vs` of type `ea((T1,...,Tn))` then the result of `from_candid` is `?v` where `v = decode((T1,...,Tn))(Vs)`. If `b` Candid-decodes to a Candid value sequence `Vs` that is not of Candid type `ea((T1,...,Tn))` (but well-formed at some other type) then the result is `null`. If `b` is not the encoding of any well-typed Candid value, but some arbitrary binary blob, then the result of `from_candid` is a trap.
+
+Informally, here `ea(_)` is the Motoko-to-Candid type sequence translation and `encode/decode((T1,...,Tn))(_)` are type-directed Motoko-Candid value translations.
+
+
+
+:::note
+
+Operation `from_candid` returns `null` when the argument is a valid Candid encoding of the wrong type. It traps if the blob is not a valid Candid encoding at all.
+
+:::
+
+:::note
+
+Operations `to_candid` and `from_candid` are syntactic operators, not first-class functions, and must be fully applied in the syntax.
+
+:::
+
+:::danger
+
+The Candid encoding of a value as a blob is not unique and the same value may have many different Candid representations as a blob. For this reason, blobs should never be used to, for instance, compute hashes of values or determine equality, whether across compiler versions or even just different programs.
+
+:::
+
+### Declaration
+
+The declaration expression `` has type `T` provided the declaration `` has type `T`.
+
+Evaluating the expression `` proceeds by evaluating ``, returning the result of `` but discarding the bindings introduced by ``, if any.
+
+The expression `` is actually shorthand for the block expression `do {  }`.
+
+### Ignore
+
+The expression `ignore ` has type `()` provided the expression `` has type `Any` .
+
+The expression `ignore ` evaluates ``, typically for some side-effect, but discards its value.
+
+The `ignore` declaration is useful for evaluating an expression within a sequence of declarations when that expression has non-`unit` type, and the simpler `` declaration would be ill-typed. Then the semantics is equivalent to `let _ =  : Any`.
+
+### Debug
+
+The debug expression `debug ` has type `()` provided the expression `` has type `()`.
+
+When the program is compiled or interpreted with (default) flag `--debug`, evaluating the expression `debug ` proceeds by evaluating ``, returning the result of ``.
+
+When the program is compiled or interpreted with flag `--release`, evaluating the expression `debug ` immediately returns the unit value `()`. The code for `` is never executed, nor is its code included in the compiled binary.
+
+### Actor references
+
+The actor reference `actor ` has expected type `T` provided:
+
+-   The expression is used in a context expecting an expression of type `T`, typically as the subject of a type annotation, typed declaration or function argument.
+
+-   `T` is an some actor type `actor { …​ }`.
+
+-   `` has type [`Text`](https://mops.one/core/docs/Text).
+
+The argument `` must be, or evaluate to, the textual format of a canister identifier, specified elsewhere, otherwise the expression traps. The result of the expression is an actor value representing that canister.
+
+The validity of the canister identifier and its asserted type `T` are promises and taken on trust.
+
+An invalid canister identifier or type may manifest itself, if at all, as a later dynamic failure when calling a function on the actor’s proclaimed interface, which will either fail or be rejected.
+
+:::note
+
+The argument to `actor` should not include the `ic:` resource locator used to specify an `import`. For example, use `actor "lg264-qjkae"`, not `actor "ic:lg264-qjkae"`.
+
+:::
+
+:::danger
+
+Although they do not compromise type safety, actor references can easily introduce latent, dynamic errors. Accordingly, actor references should be used sparingly and only when needed.
+
+:::
+
+### Parentheses
+
+The parenthesized expression `(  )` has type `T` provided `` has type `T`.
+
+The result of evaluating `(  )` is the result of evaluating ``.
+
+### Subsumption
+
+Whenever `` has type `T` and `T <: U`, with `T` subtypes `U`, then by virtue of implicit subsumption, `` also has type `U` without extra syntax.
+
+In general, this means that an expression of a more specific type may appear wherever an expression of a more general type is expected, provided the specific and general types are related by subtyping. This static change of type has no runtime cost.
+
+## References
+
+-   **IEEE Standard for Floating-Point Arithmetic**, in IEEE Std 754-2019 (Revision of IEEE 754-2008), vol., no., pp.1-84, 22 July 2019, doi: 10.1109/IEEESTD.2019.8766229.
diff --git a/docs/languages/motoko/reference/style-guide.md b/docs/languages/motoko/reference/style-guide.md
new file mode 100644
index 00000000..62fdc274
--- /dev/null
+++ b/docs/languages/motoko/reference/style-guide.md
@@ -0,0 +1,897 @@
+---
+sidebar_position: 14
+description: "Motoko language documentation"
+title: "Motoko style guidelines"
+---
+
+To increase readability and uniformity of Motoko source code, the style guide provides suggestions for formatting Motoko sources and other basic conventions.
+
+## Layout
+
+### Spacing
+
+-   Put spaces around arithmetic operators, except to visually group sub-expressions of more tightly binding operators.
+
+    ``` motoko no-repl
+    let z = - 2*x + 3*y + 4*(x*x + y*y);
+    ```
+
+-   Put spaces around comparison operators, Boolean operators, and assignment operators.
+
+    ``` motoko no-repl
+    4 + 5 <= 5 + 4;
+    not (a or b and not c);
+    v := 0;
+    v += 1;
+    ```
+
+-   Put spaces around '='.
+
+    ``` motoko no-repl
+    var v = 0;
+    let r = { a = 1; b = 2 };
+    ```
+
+-   Analogously, put spaces around `:`.
+
+    ``` motoko no-repl
+    var v : Nat = 0;
+    func foo(x : Nat, y : Nat) : Nat { x + y }
+    func bar((x, y) : (Nat, Nat)) : Nat { x + y }
+    let w = 1 ^ 0xff : Nat16;
+    ```
+
+    Rationale: ':' is to declarations what '=' is to definitions. Moreover, the left-hand of a type annotation may generally be an arbitrary complex expression or pattern.
+
+-   Put a space after a comma or semicolon, but not before.
+
+    ``` motoko no-repl
+    let tuple = (1, 2, 3);
+    let record = { a = 1; b = 2; c = 3 };
+    ```
+
+-   Put spaces inside braces, unless they are a simple variant or record.
+
+    ``` motoko no-repl
+    func f() { 0 };
+    f({ a = 1; b = 2; c = 3 });
+    f({a = 1; b = 2});  // okay as well
+
+    type Vec3D = { x : Float; y : Float; y : Float };
+    type Order = { #less; #equal; #more };
+
+    type Order = {#less; #equal; #more};  // okay as well
+    type Proc = {h : Nat; w : Nat} -> {#ok; #fail};
+    ```
+
+-   Put spaces inside brackets if they stretch multiple lines.
+
+    ``` motoko no-repl
+    foo(
+      firstArgument,
+      ( longTupleComponent, anotherLongExpression,
+        moreLongExpression
+      ),
+      [ 1, 2, 3,
+        4, 5, 6,
+      ],
+      { field1 = 4; field2 = 5;
+        field3 = 6;
+      }
+    );
+    ```
+
+-   Put a space between statement keywords and their operands.
+
+    ``` motoko no-repl
+    if (f()) A else B;
+    for (x in xs.values()) { ... };
+    switch (compare(x, y)) {
+      case (#less) { A };
+      case (_) { B };
+    }
+
+    assert (x < 100);
+    await (async (0));
+    ```
+
+-   Do not put a space between a function or variant tag and its argument tuple or around a generic type parameter list.
+
+    ``` motoko no-repl
+    type Pair = (X, X);
+    type Id = (X) -> X;
+
+    let ok = #ok(5);
+
+    func id(x : X) : X { x };
+    id(5);
+    ```
+
+-   Put a space between a function and its argument if it is not a tuple or parenthesized expression (see [parentheses](#parentheses)) or a record used as a named parameter list (see [picking types](#picking-types)).
+
+    ``` motoko no-repl
+    sin 0.0;
+    g [1, 2, 3];
+    f{arg1 = 0; arg2 = 0};
+    ```
+
+Rationale: `g[1]` in particular will be misparsed as an indexing operation.
+
+-   Do not put a space around access operators like `.`, `?`, `!`, or index brackets.
+
+    ``` motoko no-repl
+    foo(bar).baz[5]().boo;
+    foom(?(bam()! + 1));
+    ```
+
+### Line breaks
+
+-   Pick a fixed right margin for lines and break definitions or expressions. 80 still is considered a good limit by many.
+
+    ``` motoko no-repl
+    let sum = a + b + 2*c + d +
+      e + f + g + h + i + k +
+      l + m + n + o + p;
+
+    // Or:
+    let sum =
+      a + b + 2*c + d + e +
+      f + g + h + i + k + l +
+      m + n + o + p;
+    ```
+
+    Rationale: Among other reasons, this style of formatting:
+
+    1.  Avoids code being hidden to the right in a window.
+
+    2.  Avoids random line breaks in side-by-side diffs. For example, as shown by GitHub or similar code review tools.
+
+    3.  Allows prettier display on paper, web sites, or other media.
+
+-   Break lines after an operator.
+
+    ``` motoko no-repl
+    a + b + c +
+      d + f;
+
+    foo(bar, baz).
+      boo();
+    ```
+
+-   When breaking function definitions or calls with long argument lists, put each argument on a separate line.
+
+    Also, consider using records for long parameter lists, see [picking types](#picking-types).
+
+    ``` motoko no-repl
+    func someFunction(
+      arg1 : FirstType,
+      arg2 : SecondType,
+      anotherArg : Nat,
+      yetAnother : [Type],
+      func : Nat -> Nat,
+    ) : Nat {
+      ...
+    };
+
+    someFunction(
+      veryLongArgumentExpression,
+      anotherVeryLongArgumentExpression,
+      3,
+      aNestedFunctionCall(
+        alsoWithLongArguments,
+        andMoreSuchArguments,
+      ),
+      moreLongishArgument,
+    );
+    ```
+
+    Rationale: This prevents overlooking an argument when reading code and avoids re-breaking lines when changing one of the expressions.
+
+### Indentation
+
+-   Each level of indentation should be 2 spaces.
+
+    ``` motoko no-repl
+    actor A {
+      public func f() {
+        return;
+      }
+    }
+    ```
+
+    Rationale: There may be a lot of nesting. Using only 2 spaces avoids wasting screen estate.
+
+-   Indentation should not depend on the lexical contents of previous lines.
+
+    In particular, do not vertically align indentation with inner characters from previous lines.
+
+    ``` motoko no-repl
+    let x = someFunction(
+      arg1, arg2, arg3, arg4, arg5);               // Do this.
+
+    let x = someFunction(arg1, arg2, arg3,
+      arg4, arg5);                                 // Or this.
+
+    let x =
+      someFunction(arg1, arg2, arg3, arg4, arg5);  // Or this.
+
+    let x = someFunction(                          // Or this.
+      longArg1,
+      longArg2,
+      longArg3,
+      longArg4,
+      longArg5,
+    );
+
+    // COUNTER EXAMPLE!
+    let x = someFunction(arg1, arg2, arg3,
+                         arg4, arg5);              // DO NOT DO THIS!
+    ```
+
+    Rationale: There are many problems with vertical alignment, for example:
+
+    1.  It wastes a lot of horizontal space.
+
+    2.  It creates wildly inconsistent indentation levels that obfuscate the structure of the code.
+
+    3.  It can produce realignment churn when changing a line, which, even when automated by editors, inflates and obfuscates diffs.
+
+    4.  It completely breaks with variable-width fonts.
+
+    Rule of thumb: there should be no indentation that is not a multiple of 2.
+
+-   Do not use tabs.
+
+    Rationale: The interpretation of tabs varies wildly across tools and they get lost or are displayed incorrectly in many contexts, such as web pages, diffs, etc.
+
+### Grouping
+
+-   Separate complex multi-line definitions with empty lines. One-liners can be put on consecutive lines.
+
+    ``` motoko no-repl
+    func foo() {
+      // This function does a lot of interesting stuff.
+      // It's definition takes multiple lines.
+    }
+
+    func boo() {
+      // This is another complicated function.
+      // It's definition also takes multiple lines.
+    }
+
+    func add(x : Nat, y : Nat) { return x + y };
+    func mul(x : Nat, y : Nat) { return x * y };
+    ```
+
+-   Separate logic groups of definitions with two empty lines. Add a one-line comment as a "section header" for each group.
+
+    ``` motoko no-repl
+    // A very large class
+    class MuffleMiff(n : Nat) {
+
+      // Accessors
+
+      public func miffMuff() : Text {
+        ...
+      }
+
+      public func sniffMiff() : Nat {
+        ...
+      }
+
+      // Mutators
+
+      public func clearMurk() {
+        ...
+      }
+
+      public func addMuff(name : Text) {
+        ...
+      }
+
+      // Processing
+
+      public func murkMuffle(param : List) {
+        ...
+      }
+
+      public func transformSneezler() {
+        ...
+      }
+
+      // Internal State
+
+      var miffCount = 0;
+      var mabbleMap = Map();
+
+    }
+    ```
+
+### Comments
+
+-   Use line comments (`//…​`). Use block comments (`/* …​ */`) only when commenting in the middle of a line or for commenting out pieces of code during development.
+
+    ``` motoko no-repl
+    // The following function runs the current
+    // pallaboom on a given snibble. It returns
+    // suitable plexus if it can.
+    func paBoom(s : Snibble) : Handle {
+      let puglet = initPugs(s.crick, 0 /* size */, #local);
+    /* Don't do the odd stuff yet...
+      ...
+      ...
+    */
+      return polyfillNexus(puglet);  // for now
+    }
+    ```
+
+    Rationale: Line comments make it easier to insert, remove or swap individual lines.
+
+-   Put short comments explaining a single line at the end of the line, separated by at least 2 spaces.
+
+    ``` motoko no-repl
+    paBoom(getSnibble()));  // create new snibble
+    ```
+
+-   Put multi-line comments before a line of code, with the same indentation as the code it is describing.
+
+    ``` motoko no-repl
+    func f() {
+      // Try to invoke the current pallaboom with
+      // the previous snibble. If that succeeds,
+      // we have the new plexus; if not, complain.
+      let plexusHandle = paBoom(getSnibble()));
+    }
+    ```
+
+-   Capitalize comments that are on separate lines. Use a proper full stop for sentences.
+
+## Punctuation
+
+### Semicolons
+
+-   Motoko uniformly requires a semicolon to separate expressions or local declarations in a block, regardless of whether the preceding declaration ends in a closing '}'.
+
+    Rationale: This is unlike other C-style languages, which tend to have rather ad-hoc rules.
+
+-   Put a semicolon after the last expression in a block, unless the whole block is written on a single line.
+
+    Similarly for types.
+
+    ``` motoko no-repl
+    // No ; needed before closing } on same line
+
+    type Vec3D = {x : Float; y : Float; z : Float};
+    type Result = {#ok : A; #error : Text};
+
+    func add(x : Nat, y : Nat) : Nat { return x + y };
+
+    // End last case with ;
+
+    type Address = {
+      first : Text;
+      last : Text;
+      street : Text;
+      nr : Nat;
+      zip : Nat;
+      city : Text;
+    };
+
+    type Expr = {
+      #const : Float;
+      #add : (Expr, Expr);
+      #mul : (Expr, Expr);
+    };
+
+    func eval(e : Expr) : Float {
+      switch (e) {
+        case (#const(x)) { x };
+        case (#add(e1, e2)) { eval(e1) + eval(e2) };
+        case (#mul(e1, e2)) { eval(e1) * eval(e2) };
+      };
+    }
+    ```
+
+    Rationale: Consistently ending lines with semicolon simplifies adding, removing, or swapping lines.
+
+### Braces
+
+-   Put braces around function bodies, `if` or `case` branches, and loop bodies, unless they appear nested as an expression and only contain a single expression.
+
+    ``` motoko no-repl
+    func f(x) { f1(x); f2(x) };
+
+    let abs = if (v >= 0) v else -v;
+    let val = switch (f()) { case (#ok(x)) x; case (_) 0 };
+    func succ(x : Nat) : Nat = x + 1;
+    ```
+
+-   Use "C-style" layout for braced sub-expressions stretching multiple lines.
+
+    ``` motoko no-repl
+    func f() {
+      return;
+    };
+
+    if (cond) {
+      foo();
+    } else {
+      bar();
+    };
+
+    switch (opt) {
+      case (?x) {
+        f(x);
+      };
+      case (null) {};
+    };
+    ```
+
+### Parentheses
+
+-   Motoko supports "parenless" style, meaning that parentheses are optional in most places, such as function parameter lists, or statement operands, when they enclose an expression that either is bracketed already. For example, a tuple, object, or array, or a simple constant or identifier.
+
+    ``` motoko no-repl
+    type Op = Nat -> Nat;
+    let a2 = Array.map(func x { x + 1 }, a);
+
+    let y = f x;
+    let z = f {};
+    let choice = if flag { f1() } else { f2() };
+
+    switch opt {
+      case null { tryAgain() };
+      case _ { proceed() };
+    };
+    ```
+
+-   Avoid overuse of parenless style.
+
+    In particular, do not omit parentheses and braces on statements at the same time.
+
+    ``` motoko no-repl
+    // COUNTER EXAMPLES!
+    let choice = if flag x + y else z;  // DO NOT DO THIS!
+
+    switch val {
+      case 0 f();    // DO NOT DO THIS!
+      case n n + 1;  // OR THIS!
+    };
+    ```
+
+    Rationale: Omitting both at the same time makes the code harder to read, since there is less visual clue how it groups.
+
+-   Similarly, do not omit parentheses around function parameters if the function also has type parameters.
+
+    ``` motoko no-repl
+    // COUNTER EXAMPLE!
+    foo 0;   // DO NOT DO THIS!
+    ```
+
+-   Omit parentheses around argument types of a function type with a single argument and no type parameters.
+
+    But do not omit them around when functions or classes also have type parameters.
+
+    ``` motoko no-repl
+    type Inv = Nat -> Nat;
+    type Id = (T) -> T;
+    type Get = (C) -> X;
+
+    // COUNTER EXAMPLE!
+    type Get = C -> X;   // DO NOT DO THIS!
+    ```
+
+### Miscellaneous
+
+-   Use `_` to group digits in numbers.
+
+    Group by 3 digits in decimal numbers and by 4 in hexadecimal notation.
+
+    ``` motoko no-repl
+    let billion = 1_000_000_000;
+    let pi = 3.141_592_653_589_793_12;
+    let mask : Nat32 = 0xff00_ff0f;
+    ```
+
+## Naming
+
+### Style
+
+-   Use `UpperCamelCase` for type names (including classes or type parameters), module names, and actor names.
+
+-   Use `lowerCamelCase` for all other names, including constants and variant fields.
+
+    ``` motoko no-repl
+    module MoreMuff {
+      type FileSize = Nat;
+      type Weekday = {#monday; #tuesday; #wednesday};
+      type Pair = (X, X);
+
+      class Container() { ... };
+
+      func getValue(name : Name) : Pair { ... };
+
+      let zero = 0;
+      let pair = getValue("opus");
+      var nifty : Nat = 0;
+
+      object obj { ... };
+
+      actor ServerProxy { ... };
+    };
+    ```
+
+    Rationale: The general convention is upper case for "static" entities like types and lower case for "dynamic" values. Modules and actors are fairly static and can export types. Objects usually don’t export types and tend to be used mostly as dynamic values.
+
+-   Spell acronyms as regular words.
+
+    ``` motoko no-repl
+    type HttpHeader = ...;
+    func getUrl() { ... };
+    let urlDigest = ...;
+    ```
+
+-   Do not use identifier names that start with an underscore `_`, except to document that a variable in a pattern is intentionally unused.
+
+    ``` motoko no-repl
+    let (width, _color, name) = rumpler();
+    ...  // _color is not used here
+
+    func foo(x : Nat, _futureFlag : Bool) { ... };
+    ```
+
+    Rationale: A type checker can warn about unused identifiers, which can be suppressed by explicitly prepending `_` to its name to document intention.
+
+    This aligns with the use of the keyword `_` for pattern wildcards.
+
+### Conventions
+
+-   The name of functions returning a value should describe that value.
+
+    Avoid redundant `get` prefixes.
+
+    ``` motoko no-repl
+    dict.size();
+    list.first();
+    sum(array);
+    ```
+
+-   The name of functions performing side effects or complex operations should describe that operation.
+
+    ``` motoko no-repl
+    dict.clear();
+    dict.set(key, value);
+    let result = traverse(graph);
+    ```
+
+-   The name of predicate functions returning [`Bool`](https://mops.one/core/docs/Bool) should use an `is` or `has` prefix or a similar description of the tested property.
+
+    ``` motoko no-repl
+    class Set() {
+      public func size() : Nat { ... };
+
+      public func add(x : X) { ... };
+      public func remove(x : X) { ... };
+
+      public func isEmpty() : Bool { ... };
+      public func contains(x : X) : Bool { ... };
+    };
+    ```
+
+-   Functions converting to or from a type `X` are named `toX` and `fromX`, respectively, if the source, resp. target, is either the object the function is a method of, or the primary type of the module this function appears in.
+
+-   In classes or objects, use a name ending with `_` to distinguish private variables from getters.
+
+    ``` motoko no-repl
+    class Cart(length_ : Nat) {
+      var width_ = 0;
+
+      public func length() : Nat { return length_ };
+      public func width() : Nat { return width_ };
+    }
+    ```
+
+    Rationale: In Motoko, functions are first-class values, so functions and other value identifiers share the same name space.
+
+    Identifiers with a leading `_` should *not* be used for private state, since that indicates an unused name (see [style](#style)).
+
+-   Use longer, more descriptive names for global or public identifier or ones with large scope, and short names for local ones with small scope.
+
+    It is fine to use single character identifiers when there is nothing interesting to say, especially when using the same naming scheme consistently.
+
+    ``` motoko no-repl
+    func map(x : Nat, y : Nat) : Nat { x + y };
+
+    func eval(e : Expr) : Nat {
+      let n =
+        switch (e) {
+          case (#neg(e1)) { - eval(e1) };
+          case (#add(e1, e2)) { eval(e1) + eval(e2) };
+          case (#mul(e1, e2)) { eval(e1) * eval(e2) };
+        };
+      Debug.print(n);
+      return n;
+    };
+    ```
+
+    Rationale: Contrary to popular belief, overly chatty local names can decrease readability instead of increasing it, by increasing the noise level.
+
+-   In suitable cases, use plural form for describing a collection of items, such as a list or array.
+
+    This also works for short names.
+
+    ``` motoko no-repl
+    func foreach(xs : [X], f : X -> ()) {
+      for (x in xs.values()) { f(x) }
+    }
+    ```
+
+## Types
+
+### Type annotations
+
+-   Put type annotations on definitions that involve fixed-width numeric types, to disambiguate the type of overloaded arithmetic operators and constants.
+
+    ``` motoko no-repl
+    let mask : Nat32 = 0xfc03_ff00;
+    let pivot : Nat32 = (size + 1)/2;
+    let vec : [Int16] = [1, 3, -4, 0];
+    ```
+
+    :::note
+
+    Use floating point constants to enforce type `Float` without an extra annotation. Similarly, use an explicit `+` sign to produce a positive value of type [`Int`](https://mops.one/core/docs/Int) instead of [`Nat`](https://mops.one/core/docs/Nat), if desired.
+
+    :::
+
+    ``` motoko no-repl
+    let zero = 1.0;    // type Float
+    let offset = +1;   // type Int
+    ```
+
+-   Similarly, put inline type annotations on arithmetic expressions with types other than [`Nat`](https://mops.one/core/docs/Nat) or [`Int`](https://mops.one/core/docs/Int).
+
+    ``` motoko no-repl
+    if (x & mask == (1 : Nat32)) { ... };
+    ```
+
+    :::note
+
+    The need to annotate constants in cases like this is a short-coming of Motoko’s type system that we hope to address soon.
+
+    :::
+
+    An annotation is not needed on function arguments, since their type is usually inferred from the function. The only exception is when that argument has generic type and the type arguments have been omitted.
+
+    ``` motoko no-repl
+    func foo(len : Nat32, vec : [Nat16]) { ... };
+    func bar(x : X) { ... };
+
+    foo(3, [0, 1, 2]);
+    bar(0);
+    bar(0 : Nat16);
+    ```
+
+-   Put type annotations on mutable variables, unless their type is obvious.
+
+    ``` motoko no-repl
+    var name = "Motoko";
+    var balance = 0;
+
+    func f(i : Int) {
+      var j = i;
+    };
+
+    var balance : Int = 0;
+    var obj : Class = foo();
+    ```
+
+    Rationale: Due to subtyping, inferring the type from the initialization would not necessarily deduce the intended type. For example, `balance` would have type [`Nat`](https://mops.one/core/docs/Nat) without the annotation, ruling out assignments of integers.
+
+-   Put type annotations on all public fields in a class.
+
+    ``` motoko no-repl
+    class C(init_ : Nat) {
+      public let init : Nat = init_;
+      public var count : Nat = 0;
+    }
+    ```
+
+-   Omit return type annotations of functions when the type is `()`.
+
+    ``` motoko no-repl
+    func twiceF() { f(); f() };  // no need to write ": ()"
+    ```
+
+-   Omit type annotations on functions when they are passed as arguments.
+
+    ``` motoko no-repl
+    Array.map(func n {n + 1}, a);
+    ```
+
+-   Put type annotations on definitions that involve numeric types other than [`Nat`](https://mops.one/core/docs/Nat) or [`Int`](https://mops.one/core/docs/Int), to resolve the overloading between arithmetic operators and constants.
+
+    ``` motoko no-repl
+    let mask : Nat32 = 0xfc03_ff00;
+    let offset : Nat32 = size + 1;
+    ```
+
+### Picking types
+
+-   Use [`Nat`](https://mops.one/core/docs/Nat) for any integral value that cannot be negative.
+
+-   Use fixed-width `NatN` or `IntN` only when storing many values and space usage matters, when bit-fiddling requires the low-level interpretation of a number as a vector of bits or when matching types imposed by external requirements, such as other canisters.
+
+-   Avoid proliferation of option types, and therefore `null`.
+
+    Limit their use to as small a scope as possible. Rule out the `null` case and use non-option types wherever possible.
+
+-   Consider using records instead of tuples when there are more than 2 or 3 components. Records are just simple objects with named fields.
+
+    Note that record types need not be declared but can be used in place.
+
+    ``` motoko no-repl
+      func nodeInfo(node : Node) : {parent : Node; left : Node; right : Node} { ... }
+    ```
+
+-   Consider using variants instead of [`Bool`](https://mops.one/core/docs/Bool) to represent binary choices.
+
+    Note that variant types need not be declared but can be used in place.
+
+    ``` motoko no-repl
+    func capitalization(word : Text) : {#upper; #lower} { ... }
+    ```
+
+-   Where possible, use return type `()` for functions whose primary purpose is to mutate state or cause other side effects.
+
+    ``` motoko no-repl
+    class Set() {
+      public func add(x : X) { ... };
+      public func remove(x : X) { ... };
+      ...
+    };
+    ```
+
+-   Consider using a record (an object with just data) as argument for long parameter lists.
+
+    ``` motoko no-repl
+    func process({seed : Float; delta : Float; data : [Record]; config : Config}) : Thing {
+      ...
+    };
+
+    process{config = Config(); data = read(); delta = 0.01; seed = 1.0};
+    ```
+
+    Rationale: This expresses named parameters. This way, arguments can be freely reordered at the call site and callers are prevented from accidentally passing them in the wrong order.
+
+-   Higher-order functions, such as functions that take a callback argument, should put the function parameter last.
+
+    Rationale: Makes call sites more readable, and in the absence of currying, there is no point in putting the function first, like you often would in functional languages.
+
+-   Do not use sentinel values, such as `-1`, to represent invalid values.
+
+    Use the option type instead.
+
+    ``` motoko no-repl
+    func lookup(x : key) : ?Nat { ... }
+    ```
+
+-   Data is immutable in Motoko unless explicitly stated otherwise.
+
+    Use mutability types and definitions (`var`) with care and only where needed.
+
+    Rationale: Mutable data cannot be communicated or share across actors. It is more error-prone and much more difficult to formally reason about, especially when concurrency is involved.
+
+## Features
+
+### Statements
+
+-   Use `for` loops instead of `while` loops for iterating over a numeric range or a container.
+
+    ``` motoko no-repl
+    for (i in Iter.range(1, 10)) { ... };
+    for (x in array.values()) { ... };
+    ```
+
+    Rationale: For loops are less error-prone and easier to read.
+
+-   Use `if` or `switch` as expressions where appropriate.
+
+    ``` motoko no-repl
+    func abs(i : Int) : Int { if (i < 0) -i else i };
+
+    let delta = switch mode { case (#up) +1; case (#dn) -1 };
+    ```
+
+-   Motoko requires that all expressions in a block have type `()`, in order to prevent accidentally dropped results.
+
+    Use `ignore` to explicitly drop results. Do *not* use `ignore` when it’s not needed.
+
+    ``` motoko no-repl
+    ignore async f();  // fire of a computation
+    ```
+
+-   Motoko allows to omit the `return` at the end of a function, because a block evaluates to its last expression.
+
+    Use this when a function is short and in "functional" style, that is, the function does not contain complex control flow or side effects.
+
+    Use explicit `return` at the end when the function contains other `return` statements or imperative control flow.
+
+    ``` motoko no-repl
+    func add(i : Nat, j : Nat) : Nat { i + j };
+
+    func foo(a : Float, b : Float) : Float {
+      let c = a*a + b*b;
+      c + 2*c*c;
+    };
+
+    func gcd(i : Nat, j : Nat) : Nat {
+      if (j == 0) i else gcd(j, i % j);
+    };
+
+    func gcd2(i : Nat, j : Nat) : Nat {
+      var a = i;
+      var b = j;
+      while (b > 0) {
+        let c = a;
+        a := b;
+        b := c % b;
+      };
+      return a;
+    };
+    ```
+
+### Objects and records
+
+-   Use the short-hand object syntax `{x1 = e1; …​ ; xN = eN}` when using objects as simple records, i.e., data structures with no private state and no methods.
+
+-   Use `object` when creating singleton objects.
+
+-   Limit the use of objects to records where possible.
+
+    Rationale: Only records can be sent as message parameters or results and can be stored in stable variables. Objects with methods are also more expensive to create and represent in memory.
+
+-   Use full objects only as a means for encapsulating state or behavior.
+
+### Classes
+
+-   Use `class` to create multiple objects of the same shape.
+
+-   Name classes after their conceptual functionality, not their implementation, except when having to distinguish multiple different implementations of the same concept. For example, `OrderedMap` vs `HashMap`).
+
+-   Classes are both type definitions and factory functions for objects.
+
+    Do not use classes unless both these roles are intended; use plain type aliases or functions returning an object in other cases.
+
+-   Do not overuse classes.
+
+    Use a module defining a plain type and functions on it where appropriate. Use classes only as a means for encapsulating state or behavior.
+
+    Rationale: Objects with methods have disadvantages over simple record types with separate functions (see above).
+
+-   If values of a class are meant to be sendable (shared), the class needs to provide a pair of `share`/`unshare` methods that convert to/from a sharable representation, for example, as a record.
+
+    :::note
+
+    For immutable classes it may seem more natural to make `unshare` a kind of static function. However, even for immutable ones it may depend on constructor arguments (such as an ordering function), so that the a pattern like `Map(compareInt).unshare(x)` seems appropriate.
+
+    :::
+
+-   For the time being, avoid overloading classes with too many methods, since that is currently expensive.
+
+    Restrict to a sufficiently small set of canonical methods and make less essential ones that can be implemented on top of those into functions in the enclosing module.
+
+-   Use modules for "static" classes or methods.
+
+### Modules
+
+-   Use `module` to group definitions, including types, and create a name spae for them.
+
+-   Where applicable, name modules after the main type or class they implement or provide functions for.
+
+-   Limit each module to a single main concept/type/class or closely entangled family of concepts/types/classes.
+
+
+
diff --git a/docs/references/message-execution-properties.md b/docs/references/message-execution-properties.md
index ee482a36..b8906e50 100644
--- a/docs/references/message-execution-properties.md
+++ b/docs/references/message-execution-properties.md
@@ -36,7 +36,7 @@ For example, consider the following Motoko code:
 The first message execution spans the lines 2-3, until the inter-canister call is made using the `await` syntax (orange box). The second message execution spans lines 3-5 when the inter-canister call returns (blue box). This part is called the _callback_ of the inter-canister call. The two message executions involved in this example will always be scheduled sequentially.
 
 :::note
-An `await` in the code does not necessarily mean that an inter-canister call is made and thus a message execution ends and the code after the `await` is executed as a separate message execution (callback). Async code with the `await` syntax (e.g. in Rust or Motoko) can also be used "internally" in the canister, without issuing an inter-canister call. In that case, the code part including the `await` will be processed within a single message execution. For Rust, both cases are possible if `await` is used. An inter-canister call is only made if the system API `ic0.call_perform` is called, e.g. when awaiting result of the CDK's `call` method. In Motoko, `await` always commits the current state and triggers a new message send, while `await*` does not necessarily commit the current state or trigger new message sends. See [Motoko actors and async programming](../languages/motoko/fundamentals/actors-async.md) for details on `await` vs. `await*`.
+An `await` in the code does not necessarily mean that an inter-canister call is made and thus a message execution ends and the code after the `await` is executed as a separate message execution (callback). Async code with the `await` syntax (e.g. in Rust or Motoko) can also be used "internally" in the canister, without issuing an inter-canister call. In that case, the code part including the `await` will be processed within a single message execution. For Rust, both cases are possible if `await` is used. An inter-canister call is only made if the system API `ic0.call_perform` is called, e.g. when awaiting result of the CDK's `call` method. In Motoko, `await` always commits the current state and triggers a new message send, while `await*` does not necessarily commit the current state or trigger new message sends. See [Motoko actors and async programming](../languages/motoko/fundamentals/actors/actors-async.md) for details on `await` vs. `await*`.
 :::
 
 :::note
diff --git a/scripts/postprocess-motoko.mjs b/scripts/postprocess-motoko.mjs
index ad1b71bc..475c3391 100644
--- a/scripts/postprocess-motoko.mjs
+++ b/scripts/postprocess-motoko.mjs
@@ -2,37 +2,44 @@
 /**
  * Post-process synced Motoko docs:
  * 1. Remove duplicate H1 headings (Starlight renders title from frontmatter)
- * 2. Rewrite relative links to match the flattened directory structure
- * 3. Redirect core library links to mops.one
- * 4. Remove _category_.yml and sub-section index.md files
- * 5. Expand Docusaurus file-embed blocks (```lang file=[#L-L])
- * 6. Convert Docusaurus remote-reference blocks (```md reference) to links
- * 7. Normalize Starlight aside syntax
+ * 2. Rewrite relative links to match the new directory structure
+ * 3. Rewrite external internetcomputer.org/docs links to internal paths
+ * 4. Redirect core library links to mops.one
+ * 5. Redirect motoko-tooling links to docs.motoko.org (section is not synced)
+ * 6. Remove _category_.yml and sub-section index.md files
+ * 7. Expand Docusaurus file-embed blocks (```lang file=[#L-L])
+ * 8. Convert Docusaurus remote-reference blocks (```md reference) to links
+ * 9. Normalize Starlight aside syntax
  *
- * Docusaurus patterns handled vs. left as-is:
- *   file=        EXPANDED — inline file content (step 5). Supports extra attrs
- *                      (no-repl, title=) and #L-L line ranges.
- *   title=""     LEFT — Starlight renders code block titles natively.
- *   name=