From 60edaa63c751bf6ee65668432e901e414d805ad6 Mon Sep 17 00:00:00 2001 From: Marco Walz Date: Wed, 20 May 2026 17:34:56 +0200 Subject: [PATCH 1/8] infra: simplify Motoko sync after upstream PR #6132 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upstream caffeinelabs/motoko PR #6132 transformed doc/md/ into a Starlight-ready state: clean filenames, sidebar.order frontmatter, aside syntax normalized, mo:base→mo:core rewrites, numeric prefixes removed, and index.md stubs added for subdirectory groups. This PR adopts those changes in the developer-docs sync pipeline. Changes: - scripts/sync-motoko.sh: rewrite as plain rsync (~35 lines vs ~180). All the complex bash transforms (frontmatter injection, .mdx→.md conversion, numeric prefix stripping, slug collision guards) are no-ops now that upstream handles them. - scripts/postprocess-motoko.mjs: remove seven steps that upstream now handles. Critical fix: the old script explicitly deleted the new index.md stubs PR #6132 added, breaking autogenerate. Also adds a general docs.internetcomputer.org/ prefix rule to handle links that upstream PR #6132 §5 rewrote from the retired portal format to the current docs.internetcomputer.org/ domain. - sidebar-motoko.mjs: replace 130-line explicit page list with a section-level autogenerate config. Uses explicit section labels ("ICP features") to avoid the "Icp Features" label that plain autogenerate would produce for the icp-features/ directory. - ec.config.mjs + syntaxes/bnf.tmLanguage.json: register BNF grammar for Shiki so the 30 BNF blocks in language-manual.md no longer emit language-not-found warnings. - .docs-plan/motoko-repo-sync-proposal.md: delete (resolved by PR #6132; tracked in issue #265). - .sources/motoko: bump to a9cc50f (master after PR #6132 merge; no release tag cut yet — this is a pre-release test pin). - docs/languages/motoko/**: full resync from upstream (77 content files updated + 6 new index.md stubs for autogenerate groups). Build: 208 pages, no errors. --- .docs-plan/motoko-repo-sync-proposal.md | 1070 ------- .sources/motoko | 2 +- docs/languages/motoko/base-core-migration.md | 60 +- .../fundamentals/actors/actors-async.md | 19 +- .../fundamentals/actors/compatibility.md | 51 +- .../fundamentals/actors/data-persistence.md | 15 +- .../actors/enhanced-multi-migration.md | 23 +- .../motoko/fundamentals/actors/index.md | 6 + .../motoko/fundamentals/actors/messaging.md | 7 +- .../motoko/fundamentals/actors/mixins.md | 4 +- .../orthogonal-persistence/classical.md | 7 +- .../actors/orthogonal-persistence/enhanced.md | 11 +- .../actors/orthogonal-persistence/index.md | 6 + .../actors/orthogonal-persistence/overview.md | 9 +- .../motoko/fundamentals/actors/state.md | 6 +- .../basic-syntax/characters-text.md | 19 +- .../fundamentals/basic-syntax/comments.md | 7 +- .../basic-syntax/defining-an-actor.md | 18 +- .../fundamentals/basic-syntax/functions.md | 16 +- .../fundamentals/basic-syntax/identifiers.md | 8 +- .../fundamentals/basic-syntax/imports.md | 8 +- .../motoko/fundamentals/basic-syntax/index.md | 6 + .../fundamentals/basic-syntax/literals.md | 10 +- .../fundamentals/basic-syntax/numbers.md | 11 +- .../fundamentals/basic-syntax/operators.md | 11 +- .../basic-syntax/printing-values.md | 12 +- .../motoko/fundamentals/basic-syntax/traps.md | 12 +- .../fundamentals/basic-syntax/whitespace.md | 11 +- .../motoko/fundamentals/contextual-dot.md | 14 +- .../control-flow/basic-control-flow.md | 15 +- .../fundamentals/control-flow/blocks.md | 5 +- .../fundamentals/control-flow/conditionals.md | 9 +- .../motoko/fundamentals/control-flow/index.md | 6 + .../motoko/fundamentals/control-flow/loops.md | 7 +- .../fundamentals/control-flow/switch.md | 22 +- .../declarations/class-declarations.md | 9 +- .../declarations/expression-declarations.md | 11 +- .../declarations/function-declarations.md | 9 +- .../motoko/fundamentals/declarations/index.md | 6 + .../declarations/module-declarations.md | 11 +- .../declarations/object-declaration.md | 13 +- .../declarations/type-declarations.md | 13 +- .../declarations/variable-declarations.md | 11 +- .../motoko/fundamentals/error-handling.md | 11 +- .../motoko/fundamentals/hello-world.md | 18 +- .../fundamentals/implicit-parameters.md | 28 +- .../motoko/fundamentals/modules-imports.md | 15 +- .../motoko/fundamentals/pattern-matching.md | 11 +- .../fundamentals/types/advanced-types.md | 41 +- .../fundamentals/types/function-types.md | 31 +- .../fundamentals/types/immutable-arrays.md | 21 +- .../motoko/fundamentals/types/index.md | 6 + .../fundamentals/types/mutable-arrays.md | 33 +- .../fundamentals/types/objects-classes.md | 19 +- .../motoko/fundamentals/types/options.md | 31 +- .../fundamentals/types/primitive-types.md | 19 +- .../motoko/fundamentals/types/records.md | 29 +- .../motoko/fundamentals/types/results.md | 13 +- .../motoko/fundamentals/types/shared-types.md | 21 +- .../motoko/fundamentals/types/stable-types.md | 17 +- .../motoko/fundamentals/types/subtyping.md | 41 +- .../motoko/fundamentals/types/tuples.md | 21 +- .../fundamentals/types/type-conversions.md | 13 +- .../motoko/fundamentals/types/variants.md | 23 +- .../icp-features/caller-identification.md | 8 +- .../icp-features/candid-serialization.md | 6 +- .../motoko/icp-features/randomness.md | 4 +- .../motoko/icp-features/stable-memory.md | 6 +- .../motoko/icp-features/system-functions.md | 12 +- docs/languages/motoko/icp-features/timers.md | 6 +- .../motoko/icp-features/view-queries.md | 22 +- docs/languages/motoko/index.md | 49 +- docs/languages/motoko/reference/changelog.md | 2509 +---------------- .../motoko/reference/compiler-ref.md | 7 +- .../languages/motoko/reference/error-codes.md | 13 +- .../motoko/reference/language-manual.md | 43 +- .../motoko/reference/motoko-grammar.md | 7 +- .../languages/motoko/reference/style-guide.md | 5 +- ec.config.mjs | 6 +- scripts/postprocess-motoko.mjs | 357 +-- scripts/sync-motoko.sh | 297 +- sidebar-motoko.mjs | 131 +- syntaxes/bnf.tmLanguage.json | 66 + 83 files changed, 763 insertions(+), 4859 deletions(-) delete mode 100644 .docs-plan/motoko-repo-sync-proposal.md create mode 100644 docs/languages/motoko/fundamentals/actors/index.md create mode 100644 docs/languages/motoko/fundamentals/actors/orthogonal-persistence/index.md create mode 100644 docs/languages/motoko/fundamentals/basic-syntax/index.md create mode 100644 docs/languages/motoko/fundamentals/control-flow/index.md create mode 100644 docs/languages/motoko/fundamentals/declarations/index.md create mode 100644 docs/languages/motoko/fundamentals/types/index.md create mode 100644 syntaxes/bnf.tmLanguage.json diff --git a/.docs-plan/motoko-repo-sync-proposal.md b/.docs-plan/motoko-repo-sync-proposal.md deleted file mode 100644 index 61de5b70..00000000 --- a/.docs-plan/motoko-repo-sync-proposal.md +++ /dev/null @@ -1,1070 +0,0 @@ -# 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 -``` -```` - -This site has a `remark-include-file` plugin that runs at build time and handles -`file=` syntax. Both historical gaps have been resolved on the developer-docs -side: - -- **Line-range slicing**: the plugin now supports `#L-L` suffixes. Of - the file-embed blocks in the Motoko source, roughly 9 use line ranges and 38 - embed whole files — both forms now work. -- **Path incompatibility**: synced files land in `docs/languages/motoko/...` while - examples stay in `.sources/motoko/doc/md/examples/`. The `` - placeholder bridges this: `postprocess-motoko.mjs` rewrites `../examples/` → - `/` at sync time, and `remark-include-file` resolves the - placeholder to the examples directory inside the pinned submodule at build time. - -The upstream change (Proposed Change §3 below) makes this bridge permanent by -adopting `` paths directly in the source, after which the sync-time -rewrite becomes a no-op. - -### 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/` and `core/` library links - -Several files link to `./base/.md` or `./core/.md` — both -excluded sections. These are post-processed to `https://mops.one/core/docs/` -because `mo:base` is deprecated in favour of `mo:core`. Using the mops.one URL -directly in the source removes the need for this rewrite. - -The `core/` directory (49 files: `Array.md`, `Map.md`, etc.) is auto-generated -from `caffeinelabs/motoko-core` using `mo-doc` as a separate CI step in the -motoko repo. Once all `./core/.md` links are replaced with mops.one -URLs, the generated `doc/md/core/` directory is no longer needed in the docs -tree and the CI generation step can be dropped from the motoko repo. - -### 6. Docusaurus-specific aside types - -``` -:::info ← ~21 occurrences in synced sections (60+ across full doc/md tree) -:::warn ← 1 occurrence in synced sections -:::info [Link](url) ← link in aside title (Starlight titles are plain text) -``` - -Starlight supports `:::note`, `:::tip`, `:::caution`, `:::danger`, and -`:::warning` (the full word). It does NOT support `:::info` (renders as plain -text) or `:::warn` (the shortened form — also renders as plain text). The -post-processor maps `:::info` → `:::note` and `:::warn` → `:::caution`. Aside -titles that are markdown links (`:::info [Iter](url)`) are also rewritten to -strip the URL (Starlight titles cannot contain links). - -**Important distinction:** `:::warning` (full word) IS a valid Starlight type -(rendered as `:::caution`). Only `:::warn` (three-letter shorthand) is invalid -in Starlight. The source currently uses both — `:::warn` appears once -(`fundamentals/3-types/12-advanced-types.md:235`) and `:::warning` appears twice -(`fundamentals/3-types/9-mutable-arrays.md:89`, `12-base-core-migration.md:31`). -Only `:::warn` needs to be replaced; `:::warning` is already valid. - -Docusaurus supports all four Starlight types natively, so switching `:::info` → -`:::note` and `:::warn` → `:::caution` in the upstream source is a safe change -with no effect on the Docusaurus site. - -### 7. Docusaurus REPL meta flags - -The old DFINITY developer portal (`internetcomputer.org/docs`) wrapped Docusaurus's -`CodeBlock` component with a custom React component that embedded the `moc` -interpreter in the browser. It added the following code-fence meta flags: - -| Flag | Docusaurus behaviour | -|---|---| -| `` ```motoko `` (bare, no flag) | Syntax highlighting + **Run** button; output shown on click | -| `` ```motoko run `` | Same as bare but auto-runs on page load | -| `` ```motoko no-repl `` | Syntax highlighting only; no button | -| `` ```motoko name=X `` | Saves block as `X.mo` so other blocks can `include=X` it | -| `` ```motoko include=X,Y `` | Runs `X.mo`, `Y.mo` as context before executing this block | -| `` ```motoko _include=X `` | Like `include=X` but the included code is not shown | - -This site uses Astro + Starlight with the Expressive Code syntax highlighter. -**No REPL or interpreter exists on this site.** Expressive Code silently ignores -all unrecognised meta flags. This has been verified in the built HTML output: -the `figcaption` for a `name=int` block is empty, no Run button is injected, and -the code renders as plain syntax-highlighted Motoko — indistinguishable from a -`no-repl` block. - -**Distribution in the sections this site syncs** (counted against the source): - -| Section | `no-repl` | bare `motoko` | `name=X` | `_include=X` | `run` / `include=` | -|---|---|---|---|---|---| -| `fundamentals/` | 216 | 97 | ~15 (8 files) | ~5 (2 files) | 0 | -| `icp-features/` | 20 | 8 | 0 | 0 | 0 | -| `language-manual.md` | 1 | 19 | 0 | 0 | 0 | -| **Total synced** | **237** | **124** | **~15** | **~5** | **0** | - -The `run` and `include=` (without underscore) flags — the most REPL-intensive — do -not appear in any of the synced sections. They exist only in `core/` (35 files), -`base/` (25 files), and `old/` — all of which are deliberately excluded from sync. - -**The `name=` blocks that appear in `fundamentals/`** are standalone, complete -examples that each make sense on their own. The `name=` label was only meaningful -to the REPL cross-reference mechanism; on this site it does nothing. Examples: -`name=int` labels the `Int.toText` snippet, `name=List` labels a recursive list -type definition, `name=max` labels a generic max function. - -**The `_include=X no-repl` blocks** show a usage example of a named block without -re-executing it. The `_include=` part is a no-op without the REPL; `no-repl` is -already the correct flag for this site. - -**The bare `` ```motoko `` blocks** (97 in `fundamentals/`, 8 in `icp-features/`, -19 in `language-manual.md`) implicitly had a Run button in the portal. On this -site they render identically to `no-repl` blocks — Expressive Code ignores the -missing flag. However, they signal intent incorrectly to anyone reading the source. - -### 8. Internal relative links use numeric-prefixed paths - -Every relative cross-reference in the source uses the current numeric-prefixed -directory and file names. For example, from `fundamentals/3-types/14-subtyping.md`: - -```markdown -[immutable arrays (`[T]`)](../3-types/8-immutable-arrays.md) -[mutable arrays](../3-types/9-mutable-arrays.md) -[functions](../3-types/3-functions.md) -``` - -And from top-level fundamentals files like `0-hello-world.md`: - -```markdown -[actor](../fundamentals/2-actors/1-actors-async.md) -[stable variable](../fundamentals/3-types/13-stable-types.md) -``` - -After the directory and file renames in Proposed Change §1, all of these paths -become invalid. The consuming site's post-processor (`postprocess-motoko.mjs`) -currently rewrites every relative link by stripping numeric prefixes and doing a -slug-index lookup. For a transform-free sync, the upstream must update all -relative links to reflect the post-rename paths. - -In the sections this site syncs, **~146 relative links across ~20 files** use -numeric-prefixed paths. The affected files are concentrated in `fundamentals/` -(subdirs `types/`, `actors/`, `declarations/`, `control-flow/`, `basic-syntax/` -and top-level standalone files) and `reference/1-error-codes.md`. - -**Content quality issue to fix during this pass:** `fundamentals/1-basic-syntax/3-printing-values.md` -links to `../3-types/3-functions.md` (post-rename: `types/function-types.md`) using -the link text "pure functions". However, `function-types.md` has no heading or -anchor for "pure functions" — the concept is only implicit in the "## Local functions" -section. When updating this link's path in Change §8, also fix the link destination: -either add a `{#pure-functions}` anchor inside `function-types.md` (preferred — makes -the concept explicit) or point to `function-types.md#local-functions` and adjust the -link text to "local functions". Without this fix, readers who click "pure functions" -land at the top of `function-types.md` with no indication where the concept is. - -### 9. `changelog.mdx` contains a Docusaurus `md reference` block - -`doc/md/reference/3-changelog.mdx` contains: - -```` -```md reference -https://github.com/caffeinelabs/motoko/blob/master/Changelog.md -``` -```` - -This is a Docusaurus-specific directive that fetches the content of -`Changelog.md` from GitHub at build time. It has no equivalent in Starlight or -standard Markdown — the page renders blank on this site (except for the title) -unless the post-processor inlines the content at sync time. - -The post-processor currently reads `Changelog.md` from the pinned submodule -(`./sources/motoko/Changelog.md`) and inlines it. This works but creates a -dependency on postprocess-motoko.mjs for what should be a simple file copy. - -`Changelog.md` is 2474 lines and grows with every release. The consumer site -is pinned to a specific submodule commit. If the changelog content lived -directly in `doc/md/reference/changelog.md` at the same commit, there can be -no drift: the file always reflects exactly the entries up to that release. - -### 10. `motoko-tooling` links in `comments.md` - -`doc/md/fundamentals/1-basic-syntax/10-comments.md` links to the `motoko-tooling/` -section (excluded from sync) via two relative paths: - -```markdown -[mo-doc](../../motoko-tooling/3-mo-doc.md) -``` - -The `motoko-tooling/` section covers: Canpack, dev containers, mo-doc, and the -Motoko VS Code extension. It is excluded from sync because it uses `dfx` commands -(banned in developer-docs) and contains Docusaurus JSX (`import Tabs`). - -The post-processor previously rewrote these links to `https://docs.motoko.org`, -which does not exist. This is now fixed: the postprocessor redirects both -`motoko-tooling/` relative paths and the `docs.motoko.org` domain to the -internal developer-docs page at `/developer-tools/#mo-doc`. - ---- - -## Proposed changes to `caffeinelabs/motoko` - -### 1. Remove numeric prefixes from all directories and files - -> **Optional for the current sync.** `sync-motoko.sh` already strips numeric -> prefixes via `strip_num()` and handles the one slug collision -> (`types/functions.md` → `function-types.md`) with an explicit rename rule. -> §1 is only *required* if the goal is a fully transform-free rsync with no -> post-processing at all. If the Motoko team prefers to keep numbers for local -> navigation clarity, they can skip §1 and §8 entirely — the sync handles both -> automatically. The remaining 9 changes (§2–§7, §9–§11) are independent of -> whether files are numbered. - -Change the directory structure from: - -``` -doc/md/ - 12-base-core-migration.md - 14-style.md - 15-compiler-ref.md - 16-language-manual.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/ - base-core-migration.md - style-guide.md ← also rename style.md → style-guide.md for clarity - compiler-ref.md - language-manual.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 distinct names -(the one collision today is `types/functions.md` vs `basic-syntax/functions.md`; -proposed rename: `types/function-types.md`). - -`fundamentals/2-actors/6-orthogonal-persistence/index.md` must be renamed to -`overview.md` (not just stripped of its prefix). Unlike the other `index.md` files -in `fundamentals/` subdirs — which are Docusaurus navigation pages replaced by -metadata stubs in §11 — this file contains real overview content comparing both -persistence modes. Renaming it to `overview.md` distinguishes it as a content page -rather than an ordering stub. - -### 2. Replace `sidebar_position` with Starlight-native `sidebar.order` - -In every file, replace: - -```yaml ---- -sidebar_position: 8 ---- -``` - -with: - -```yaml ---- -sidebar: - order: 8 ---- -``` - -This allows `icp-features/` and `reference/` to use Starlight `autogenerate`. -`fundamentals/` must stay as an explicitly listed sidebar (see below for why). - -**Section-specific notes:** - -`icp-features/` — flat structure, autogenerate works. `sidebar_position` maps -directly to `sidebar.order` 1–1. `icp-features/7-view-queries.md` has no -`sidebar_position`; add `sidebar: { order: 7 }` to fix. - -`reference/` — after the rename, all six files share one directory but come from -two different legacy position namespaces (reference/ subdir had 1–3; top-level -files had 14–16). Mechanical substitution gives the wrong order. The six files -must be renumbered to match the desired display order: - -| File (post-rename) | Old `sidebar_position` | Correct `sidebar.order` | -|---|---|---| -| `language-manual.md` | 16 | 1 | -| `error-codes.md` | 1 | 2 | -| `motoko-grammar.md` | 2 | 3 | -| `style-guide.md` | 14 | 4 | -| `compiler-ref.md` | 15 | 5 | -| `changelog.md` | 3 | 6 | - -`fundamentals/` — **cannot use autogenerate** without the subdir `index.md` -ordering stubs from Change §11. After removing numeric prefixes, subdirectory -names sort alphabetically: `actors`, `basic-syntax`, `control-flow`, `declarations`, -`types` — but the desired display order is `basic-syntax`, `actors`, `types`, -`declarations`, `control-flow`. Starlight overrides alphabetical directory order -only via `sidebar.order` in a directory's `index.md`. Change §11 adds these -stubs; the new sync uses `--exclude='/index.md'` (anchored to the transfer root), -which keeps the subdir stubs while dropping only the top-level -`fundamentals/index.md` section landing page. - -**Without Change §11:** keep the explicit `sidebar-motoko.mjs` enumeration. -**With Change §11 (recommended):** switch `fundamentals/` to `autogenerate` and -delete `sidebar-motoko.mjs`. - -`actors/` duplicate values — both `4-compatibility.md` and `5-messaging.md` -carry `sidebar_position: 4`. Fix so values are unique and match the numeric -filename order. - -**Add `title:` and `description:` frontmatter to every file, and remove the H1 -heading from the body.** Starlight requires `title:` as a schema field — without -it the build fails. All 68 synced upstream files currently carry `# Title` as an -H1 heading (Docusaurus convention) but have no `title:` in frontmatter. The -developer-docs postprocessor currently bridges this by extracting the H1 as -`title:` and adding a generic `description: "Motoko language documentation"` -fallback. Moving this into the upstream source eliminates that extraction step and -is a prerequisite for the symlink approach. - -The `title:` value is derived from the existing H1 heading. `description:` should -be a genuine one-line summary for each page; the postprocessor's generic fallback -is acceptable as a placeholder during the transition. - -After adding `title:` frontmatter, remove the `# Title` H1 from the body — Starlight -renders the page heading from `title:` frontmatter and would show it twice otherwise. - -Three files have no frontmatter at all: - -- `fundamentals/2-actors/7-mixins.md` — add `title`, `description`, and `sidebar: { order: 7 }` -- `fundamentals/10-contextual-dot.md` — add `title`, `description`, and `sidebar: { order: N }` -- `fundamentals/11-implicit-parameters.md` — add `title`, `description`, and `sidebar: { order: N }` - -### 3. Use `` paths for file-embed blocks - -Replace Docusaurus-relative paths in file-embed blocks: - -```` -```motoko file=../examples/counter.mo -```motoko file=../../examples/todo-error.mo#L49-L58 -``` -```` - -with the `` placeholder: - -```` -```motoko file=/counter.mo -```motoko file=/todo-error.mo#L49-L58 -``` -```` - -`` is a path placeholder recognised by the `remark-include-file` -build plugin on `docs.internetcomputer.org`. It resolves to -`.sources/motoko/doc/md/examples/` — the examples directory inside the pinned -`caffeinelabs/motoko` submodule — at Astro build time. This means: - -- Examples are always live: the plugin reads from the pinned submodule at build - time, so a submodule bump automatically picks up updated examples. -- No sync-time processing: the path rewrite that `postprocess-motoko.mjs` - currently performs (`../examples/` → `/`) will become a - no-op once the upstream source uses `` paths directly, and - can then be removed from the postprocess script. -- `#L-L` line-range suffixes are supported as-is; the plugin slices - the specified lines and raises a hard build error if the range is out of bounds. - -This is a mechanical search-and-replace in the upstream source: -```bash -# In caffeinelabs/motoko — replace all relative example paths -find doc/md -name '*.md' -o -name '*.mdx' | \ - xargs sed -i 's|file=\(\.\./\)*examples/|file=/|g' -``` - -### 4. Replace `./core/` and `./base/` links with mops.one URLs, then remove those directories - -A core maintainer confirmed: "I'd honestly prefer that. Mops docs should be the -single source of truth." — mops.one is the intended canonical home for `mo:core` -library docs. This makes the link replacement + directory removal the actively -desired outcome, not just a side-effect. - -**Step 1 — replace links:** Replace all `./base/.md` and -`./core/.md` links with `https://mops.one/core/docs/`. The -module name matches the source file name exactly; the mapping is mechanical. - -```markdown -[Map](./core/Map.md) → [Map](https://mops.one/core/docs/Map) -[Bool](./base/Bool.md) → [Bool](https://mops.one/core/docs/Bool) -``` - -**Step 2 — remove `doc/md/core/` and its CI generation step:** Once all -`./core/.md` links are replaced, the auto-generated `doc/md/core/` -directory (49 files) is no longer needed and should be deleted. The CI step -that runs `mo-doc` to generate those files from `caffeinelabs/motoko-core` can -be dropped at the same time. This removes a CI dependency and keeps the doc tree -clean. - -**Step 3 — consider removing `doc/md/base/`:** `mo:base` is deprecated in -favour of `mo:core`. Once `./base/.md` links are replaced with mops.one -URLs, the `doc/md/base/` directory is also redundant and can be removed. - -The mops.one URL pattern uses the exact module name: `https://mops.one/core/docs/Map`, -`https://mops.one/core/docs/List`, etc. The module name matches the source file -name in `caffeinelabs/motoko-core/src/.mo` exactly, so the mapping is -mechanical and stable across releases. - -### 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: - -All `internetcomputer.org/docs/...` URLs currently in the synced source files -(verified against source at time of writing), with specific section anchors -wherever the target page has a matching section: - -| Old portal URL | Current developer-docs path | -|---|---| -| `building-apps/essentials/canisters` | `/concepts/canisters` | -| `building-apps/essentials/message-execution` | `/references/message-execution-properties` | -| `building-apps/interact-with-canisters/update-calls` | `/concepts/canisters#update-calls` | -| `building-apps/interact-with-canisters/query-calls` | `/concepts/canisters#query-calls` | -| `building-apps/interact-with-canisters/query-calls#composite-queries` | `/concepts/canisters#composite-queries` | -| `building-apps/interact-with-canisters/candid/candid-concepts` | `/guides/canister-calls/candid` | -| `building-apps/interact-with-canisters/candid/using-candid` | `/guides/canister-calls/candid` | -| `building-apps/interact-with-canisters/agents/overview` | `/guides/canister-calls/calling-from-clients` | -| `building-apps/canister-management/upgrade` | `/guides/canister-management/lifecycle#upgrade-a-canister` | -| `building-apps/canister-management/snapshots` | `/guides/canister-management/snapshots` | -| `building-apps/canister-management/storage` | `/concepts/orthogonal-persistence` | -| `building-apps/canister-management/storage#heap-memory` | `/concepts/orthogonal-persistence#heap-wasm-linear-memory` | -| `building-apps/canister-management/storage#stable-memory` | `/concepts/orthogonal-persistence#stable-memory` | -| `building-apps/canister-management/storage#motoko-storage-handling` | `/concepts/orthogonal-persistence#motoko-true-orthogonal-persistence` | -| `building-apps/canister-management/resource-limits` | `/guides/canister-management/large-wasm` | -| `building-apps/network-features/periodic-tasks-timers` | `/guides/backends/timers` | -| `building-apps/network-features/periodic-tasks-timers#timers` | `/guides/backends/timers#recurring-timers` | -| `building-apps/network-features/randomness` | `/guides/backends/randomness` | -| `references/async-code` | `/references/message-execution-properties` | -| `references/ic-interface-spec` | `/references/ic-interface-spec/` | -| `references/ic-interface-spec#ic-raw_rand` | `/references/ic-interface-spec/management-canister#ic-raw_rand` | -| `references/ic-interface-spec#global-timer` | `/references/ic-interface-spec/canister-interface#global-timer` | -| `references/ic-interface-spec#system-api-inspect-message` | `/references/ic-interface-spec/canister-interface#system-api-inspect-message` | -| `references/ic-interface-spec#heartbeat` | `/references/ic-interface-spec/canister-interface#heartbeat` | -| `references/candid-ref` | `/references/candid-spec` | -| `references/system-canisters/management-canister` | `/references/management-canister` | - -Notes on anchored entries: -- The ic-interface-spec is split across multiple pages on developer-docs. Old - portal anchors map to specific sub-files. `#heartbeat` has no explicit - `{#heartbeat}` attribute in `canister-interface.md` — Starlight auto-generates - the slug `heartbeat` from the `#### Heartbeat` heading, so the link resolves. -- `building-apps/canister-management/storage` (with and without fragments) maps - to `/concepts/orthogonal-persistence`. The old portal anchors differ: `#heap-memory` - → `#heap-wasm-linear-memory`, `#motoko-storage-handling` → `#motoko-true-orthogonal-persistence`, - `#stable-memory` is an exact match. The postprocessor handles these with explicit - anchored entries in the rewrite map and tries the full URL (with anchor) before - stripping — entries without anchors act as a fallback for bare URLs. -- `building-apps/canister-management/logs` and `building-apps/security/iam/` - appeared in an earlier version of the source but are no longer present. No - action needed for those two. - -**developer-docs side — postprocessor update when §5 lands:** the current -`externalToInternal` map in `postprocess-motoko.mjs` handles the old -`internetcomputer.org/docs/...` pattern. After §5 replaces those with -`docs.internetcomputer.org/...` paths, add a general prefix rule to the map: -```javascript -['docs.internetcomputer.org/', '/'] -``` -This single entry rewrites all `docs.internetcomputer.org/` links to -root-relative `/` internal paths, replacing the entire set of specific -entries above. Remove the `internetcomputer.org/docs/...` entries at the same -time — they will no longer appear in the upstream source. - -### 6. Use Starlight-native aside types - -Replace Docusaurus-only aside types with their Starlight equivalents: - -- `:::info` → `:::note` (both are supported by Docusaurus; no effect on the Docusaurus site) -- `:::warn` → `:::caution` (same: Docusaurus supports both). **Do not change `:::warning`** (full word) — it is already a valid Starlight type and renders correctly on both sites. -- `:::info [LinkText](url)` → `:::note[LinkText]` (strip URL from title; link text becomes plain-text title) - -### 7. Normalize REPL meta flags to `no-repl` - -The REPL meta flags are Docusaurus-specific and have no effect on this site (see -Problem §7). Cleaning them up makes the source readable without assuming any -REPL infrastructure: - -- **Bare `` ```motoko ``** → `` ```motoko no-repl ``: the implicit Run button - no longer exists; `no-repl` makes the intent explicit. Scope: all files in the - sections this site syncs (`fundamentals/`, `icp-features/`, `language-manual.md`). - This is safe for the Docusaurus site too — Docusaurus renders bare `motoko` - and `no-repl` identically when no REPL component is mounted. - -- **`` ```motoko name=X ``** → `` ```motoko no-repl ``: the `name` label has no - purpose without the REPL. The code itself is a self-contained example and - should render as a static block. Applies to all `name=X` blocks in the synced - sections (~15 occurrences in 8 files under `fundamentals/`). - -- **`` ```motoko name=X no-repl ``** → `` ```motoko no-repl ``: strip the unused - `name=X` attribute, keep `no-repl`. - -- **`` ```motoko _include=X no-repl ``** → `` ```motoko no-repl ``: strip the - `_include=X` attribute (it was a no-op display hint for the REPL; the block - already carries `no-repl`). Applies to ~5 occurrences in `fundamentals/`. - -- **`` ```motoko run ``**: not present in any synced section — no action needed. - Only appears in `core/` and `base/` which are excluded from sync. - -- **`` ```motoko include=X ``** (without underscore): not present in any synced - section — no action needed. - -**Important:** a significant portion of code fences in the source use -`` ``` motoko `` (with a space between the backticks and the language name), -not `` ```motoko ``. This space variant must be normalised first, otherwise -the subsequent `sed` commands that anchor to `^```motoko` will miss those blocks. - -This cleanup can be done with the following targeted commands, scoped to the -sections this site syncs: - -```bash -# In caffeinelabs/motoko — scoped to synced sections only -# (do NOT apply to core/, base/, old/ — they have active REPL usage) - -SYNCED_DIRS="doc/md/fundamentals doc/md/icp-features doc/md/reference" -SYNCED_TOP="doc/md/16-language-manual.md doc/md/14-style.md doc/md/15-compiler-ref.md doc/md/12-base-core-migration.md" - -# Step 1: normalise the space-before-language variant (``` motoko → ```motoko) -# This is required first so the patterns below can match consistently. -for dir in $SYNCED_DIRS; do - find "$dir" \( -name '*.md' -o -name '*.mdx' \) \ - | xargs sed -i 's/^``` motoko/```motoko/g' -done -sed -i 's/^``` motoko/```motoko/g' $SYNCED_TOP - -# Step 2: bare ```motoko → ```motoko no-repl -for dir in $SYNCED_DIRS; do - find "$dir" \( -name '*.md' -o -name '*.mdx' \) \ - | xargs sed -i 's/^```motoko$/```motoko no-repl/' -done -sed -i 's/^```motoko$/```motoko no-repl/' $SYNCED_TOP - -# Step 3: strip name=X attribute (with or without no-repl) -for dir in $SYNCED_DIRS; do - find "$dir" \( -name '*.md' -o -name '*.mdx' \) \ - | xargs sed -i 's/^```motoko\(.*\) name=[^ ]*/```motoko\1/g' -done - -# Step 4: strip _include=X attribute (always paired with no-repl) -for dir in $SYNCED_DIRS; do - find "$dir" \( -name '*.md' -o -name '*.mdx' \) \ - | xargs sed -i 's/ _include=[^ ]*//g' -done -``` - -`no-repl` is already recognised by both Docusaurus (disables the Run button) and -this site (syntax highlighting only). The cleanup is a safe no-op for the -Docusaurus site. - -### 8. Update all internal relative links to use post-rename paths - -> **Only needed if §1 is done.** If numeric prefixes are kept, skip this -> section — `postprocess-motoko.mjs` already rewrites all numeric-prefixed -> relative links via its `syncRenames` map and slug-index lookup. - -After the directory and file renames in Change §1, every relative cross-reference -in the source that uses numeric-prefixed path components must be updated. This -applies to ~146 links across ~20 files in the synced sections. - -The pattern is mechanical: strip the numeric prefix from each path component in -relative links, and apply the special renames from Change §1 (`3-functions.md` → -`function-types.md`, `index.md` → `overview.md`, `14-style.md` → `style-guide.md`). - -Examples of required rewrites: - -| Before | After | -|---|---| -| `../3-types/8-immutable-arrays.md` | `../types/immutable-arrays.md` | -| `../2-actors/1-actors-async.md` | `../actors/actors-async.md` | -| `../fundamentals/3-types/13-stable-types.md` | `./types/stable-types.md` | -| `../fundamentals/2-actors/6-orthogonal-persistence/enhanced.md` | `./actors/orthogonal-persistence/enhanced.md` | -| `../5-control-flow/5-switch.md` | `../control-flow/switch.md` | - -This step **must be completed alongside Change §1** — the renames and link -updates form one atomic change. A broken intermediate state (files renamed but -links not yet updated) would prevent the Docusaurus site from building. - -There is no single `sed` command for this — the correct replacement depends on -each link's context (depth in the tree, target file, special renames). The -recommended approach is to run the renames first, then use a link-checker to -enumerate broken links, and update each one. The consuming site's -`postprocess-motoko.mjs` contains the full mapping table in `syncRenames` and -the slug index logic, which can serve as a reference for the expected post-rename -paths. - -### 9. Replace the `changelog.mdx` Docusaurus `md reference` block - -`doc/md/reference/3-changelog.mdx` (after prefix removal: `reference/changelog.mdx`) -contains the following Docusaurus-specific directive that has no standard Markdown -equivalent: - -```` -```md reference -https://github.com/caffeinelabs/motoko/blob/master/Changelog.md -``` -```` - -Docusaurus fetches the content of `Changelog.md` from GitHub and renders it -inline. Starlight and standard Markdown processors ignore this block entirely, -leaving the changelog page blank except for the frontmatter title. - -The post-processor currently handles this by reading `Changelog.md` from the -pinned submodule (`.sources/motoko/Changelog.md`) and inlining its full contents. - -There is no need to copy `Changelog.md` — it already exists at exactly the right -version in the submodule root at the pinned commit. The fix has two parts: - -**developer-docs side (already done with this PR):** `remark-include-file` now -supports inline markdown inclusion. A code fence with language `md` and a `file=` -attribute is replaced with the parsed AST of the referenced file, so the content -renders as prose (headings, lists, etc.), not as a code block. The new -`` placeholder resolves to `.sources/motoko/` at build time. - -**Upstream fix:** replace the `md reference` block with a single inline include -directive and rename the file from `changelog.mdx` to `changelog.md`: - -```markdown ---- -title: "Changelog" -description: "Motoko compiler changelog" -sidebar: - order: 3 ---- - -```md file=/Changelog.md -``` -``` - -(The `` placeholder is developer-docs-specific and is a no-op on -the Docusaurus site — Docusaurus ignores unknown code fence attributes and will -render this as an empty fenced block. The Docusaurus site can keep its `md reference` -block separately, or the two directives can coexist in the same file since only one -will be processed at a time depending on the build environment.) - -The post-processor's changelog inlining step can be removed once the upstream -adopts this. The `changelog.mdx` file can be renamed `changelog.md` at the same -time (the MDX extension was only needed for the `md reference` directive). - -### 10. Replace `motoko-tooling` links with a valid URL - -`doc/md/fundamentals/1-basic-syntax/10-comments.md` (after rename: -`fundamentals/basic-syntax/comments.md`) contains two links to the -`motoko-tooling/` section, which is excluded from sync: - -```markdown -[mo-doc](../../motoko-tooling/3-mo-doc.md) -``` - -These appear twice: once inline in the text (line 17) and once in a "See also" -list (line 49). - -The post-processor previously rewrote these to `https://docs.motoko.org`, which -does not exist. This is now fixed: both `motoko-tooling/` relative paths and the -`docs.motoko.org` domain redirect to `/developer-tools/#mo-doc`. - -**Upstream fix:** replace both occurrences with the developer-docs mo-doc page: - -```markdown -[mo-doc](https://docs.internetcomputer.org/developer-tools/#mo-doc) -``` - -**developer-docs side (done):** `docs/developer-tools/index.md` now has a -dedicated `### mo-doc` section covering what it does, how to install it from the -Motoko compiler tarball, and usage examples. The `motoko-tooling/` section -remains excluded from sync because it still contains `dfx` commands and -Docusaurus JSX — see the note on `dfx` references below. - ---- - -## Known content issues — outside the sync scope - -The items below are content quality issues found in synced files. They are upstream -problems that cannot be fixed on the developer-docs side (synced files must not be -edited directly). They should be addressed in a separate upstream PR, independent -of the sync reorganization effort. - -### `dfx` references in prose - -Several synced files contain `dfx` and `dfx.json` references in prose and code -examples: `compatibility.md`, `data-persistence.md`, -`orthogonal-persistence/classical.md`, `orthogonal-persistence/enhanced.md`, -`modules-imports.md`, and `reference/changelog.md` (historical entries). - -Upstream PR [caffeinelabs/motoko#6069](https://github.com/caffeinelabs/motoko/pull/6069) -is a first attempt at replacing these. **It should not be merged before the sync -reorganization PR (§1–§11) lands**: §1 renames files, so #6069's branch needs to -be rebased on the post-reorganization state and extended with any remaining `dfx` -references before merging. Em-dash fixes (see below) can be included in the same -follow-up PR. - -### Em-dashes in prose - -`enhanced-multi-migration.md` and `compatibility.md` contain em-dashes in body -prose. Em-dashes are banned in developer-docs content. These should be replaced -with colons, semicolons, or commas in the upstream source. - ---- - -## What the sync becomes after these changes - -With the above changes in place, `sync-motoko.sh` reduces to a plain file copy: - -```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/language-manual.md docs/languages/motoko/reference/language-manual.md -cp .sources/motoko/doc/md/style-guide.md docs/languages/motoko/reference/style-guide.md -cp .sources/motoko/doc/md/compiler-ref.md docs/languages/motoko/reference/compiler-ref.md -cp .sources/motoko/doc/md/base-core-migration.md docs/languages/motoko/base-core-migration.md -``` - -No exclude flags needed: upstream deletes `_category_.yml` files (§11) and the -top-level section `index.md` nav pages as part of the Docusaurus cleanup. - -### Symlink alternative - -Once all upstream changes are in place, the copy step could be replaced entirely -with committed symlinks: - -``` -docs/languages/motoko/fundamentals → ../../.sources/motoko/doc/md/fundamentals -docs/languages/motoko/icp-features → ../../.sources/motoko/doc/md/icp-features -docs/languages/motoko/reference → ../../.sources/motoko/doc/md/reference -``` - -Astro follows symlinks (the site already uses them for `src/content/docs/`), so -this works. Bumping the submodule is the entire update — no sync script runs. - -**The copy approach is preferred.** Three reasons: - -1. **Internal links**: the postprocessor converts `docs.internetcomputer.org/` - absolute URLs to root-relative `/` internal paths. Internal paths are - validated at Astro build time, work in local dev (`npm run dev`), and work in - preview deployments. Symlinks leave these as absolute external URLs, which skip - build-time validation and always point to production regardless of environment. -2. **Anchor routing**: the postprocessor maps old portal anchor slugs to the - correct developer-docs sub-page (e.g. `#global-timer` → - `canister-interface#global-timer`). Upstream cannot encode this mapping — - it requires knowledge of the developer-docs structure that lives here. -3. **Auditability**: every submodule bump produces a reviewable `git diff` showing - exactly what changed in the docs. With symlinks, content changes are invisible - in this repo. - -`postprocess-motoko.mjs` can be deleted entirely once §2 is fully completed -upstream, including adding `title:` and `description:` frontmatter to every file -and removing the `# Title` H1 heading from the body. Without `title:` in the -upstream frontmatter, Starlight's build schema validation fails; this is a hard -prerequisite for the symlink approach. - -Once §2 lands, the postprocessor's H1-extraction step becomes a no-op and the -remaining tasks split by approach: - -- **Copy approach (preferred for auditability):** the postprocessor rewrites - `docs.internetcomputer.org/` links to root-relative `/` internal - links. Every submodule bump produces a reviewable `git diff`. -- **Symlink approach:** `docs.internetcomputer.org/` links remain as absolute - external URLs pointing to the consumer site itself (self-referential but - acceptable). Bumping the submodule is the entire update. - -In both cases, `` paths are handled by `remark-include-file` at -build time — no sync-time file expansion is needed. - -`sidebar.mjs` changes after the upstream PR: -- `icp-features/` — switch to `autogenerate: { directory: "languages/motoko/icp-features" }`. - Already autogenerated today; no change to this block. -- `reference/` — switch to `autogenerate: { directory: "languages/motoko/reference" }`. - Correct because all six files will have sequential `sidebar.order` 1–6. -- `fundamentals/` — switch to `autogenerate: { directory: "languages/motoko/fundamentals" }` - once Change §11 lands. The subdir `index.md` stubs copied by the anchored - `--exclude='/index.md'` carry the `sidebar.order` values Starlight needs to - override alphabetical sort. Delete `sidebar-motoko.mjs` at the same time. - ---- - -## Migration path - -**developer-docs side (already done):** -- `remark-include-file` supports `` and `#L-L` ranges. -- `postprocess-motoko.mjs` rewrites `../examples/` → `/` at - sync time as a bridge until the upstream adopts the placeholder directly. - -**upstream side (one PR in `caffeinelabs/motoko`):** - -**Required (fix rendering/content bugs in the consumer site):** §2, §3, §4, §5, §6, §9, §10 -**Required for `fundamentals/` autogenerate (eliminates manual sidebar maintenance):** §11 -**Optional — only needed for a fully transform-free rsync:** §1 + §8 (do both or neither) -**Optional cleanup (silently handled today):** §7 -_(Note: §4 also includes removing `doc/md/core/`, `doc/md/base/`, and the CI generation step once links are replaced — confirmed as desired by a core maintainer.)_ - -1. Remove numeric prefixes from all directories and files (including top-level - `14-style.md` → `style-guide.md`, `15-compiler-ref.md` → `compiler-ref.md`, - `16-language-manual.md` → `language-manual.md`, - `12-base-core-migration.md` → `base-core-migration.md`). - Rename `fundamentals/2-actors/6-orthogonal-persistence/index.md` → - `overview.md` to distinguish it as a content page from the ordering stubs - added in step 11. -2. Replace `sidebar_position: N` with `sidebar: { order: N }` in every file. - Fix duplicate `sidebar_position` values in `2-actors/`. Add `sidebar_position` - to `icp-features/7-view-queries.md` (currently missing). Add complete - frontmatter (`title`, `description`, `sidebar_position`) to `7-mixins.md`, - `10-contextual-dot.md`, and `11-implicit-parameters.md` (currently have none). -3. Replace `file=../examples/` (and `file=../../examples/`) with - `file=/` throughout — one `sed` command covers all cases. -4. Replace `./base/.md` and `./core/.md` links with - `https://mops.one/core/docs/`. -5. Replace `internetcomputer.org/docs/...` links using the mapping table above. -6. Replace `:::info` → `:::note` and `:::warn` → `:::caution` throughout. - Do NOT change `:::warning` (full word) — it is already valid in Starlight. - Strip URLs from aside titles that use a markdown link as the title - (`:::info [LinkText](url)` → `:::note[LinkText]`). -7. Normalize REPL meta flags in `fundamentals/`, `icp-features/`, `reference/`, - and the four top-level synced files: normalise space variant - (`` ``` motoko `` → `` ```motoko ``); bare `` ```motoko `` → `` ```motoko no-repl ``; - strip `name=X` and `_include=X` attributes (use `no-repl` instead). -8. Update all ~146 internal relative links to use the post-rename paths (no - numeric prefixes, apply the special renames from step 1). Do this atomically - with the renames — the Docusaurus site must not have broken links at any - intermediate commit. -9. Replace the `md reference` block in `reference/changelog.mdx` with - `` ```md file=/Changelog.md ``` `` plus frontmatter. - Rename `changelog.mdx` → `changelog.md` (MDX was only needed for the - Docusaurus directive). No release automation needed — the file is a static - stub; `Changelog.md` at the same commit is always the correct version. -10. Replace the two `../../motoko-tooling/3-mo-doc.md` links in - `fundamentals/basic-syntax/comments.md` with - `https://docs.internetcomputer.org/developer-tools/#mo-doc`. -11. Replace the `index.md` files in each `fundamentals/` subdirectory with a - metadata-only version containing just `sidebar.order` and `sidebar.label` - frontmatter (no content). Also add a new `fundamentals/actors/index.md` - which currently does not exist. Add `sidebar: { hidden: true }` to - `base-core-migration.md`. These three changes are what allow developer-docs - to switch `fundamentals/` from an explicit sidebar list to `autogenerate`. - See the table below. Without this step, developer-docs must maintain an - explicit fundamentals page list in `sidebar-motoko.mjs` and update it - manually every time a fundamentals page is added or removed. - - | Subdir | Action | `sidebar.order` | - |---|---|---| - | `fundamentals/basic-syntax/` | replace `index.md` with metadata stub | 1 | - | `fundamentals/actors/` | add new `index.md` (currently missing) | 2 | - | `fundamentals/types/` | replace `index.md` with metadata stub | 3 | - | `fundamentals/declarations/` | replace `index.md` with metadata stub | 4 | - | `fundamentals/control-flow/` | replace `index.md` with metadata stub | 5 | - | `base-core-migration.md` | add `sidebar: { hidden: true }` | n/a | - - The metadata stub format: - ```yaml - --- - sidebar: - order: 1 - label: "Basic syntax" - --- - ``` - - The `fundamentals/index.md` (top-level section landing page) is still - excluded by the sync — only subdir `index.md` files are kept. - -**developer-docs side (done in PR 261 — `docs/motoko-sync-fixes`):** -- `remark-include-file` supports `` placeholder and inline markdown - inclusion (`md` language code fence → rendered prose, not a code block). -- `remark-include-file` supports `` and `#L-L` ranges. -- `postprocess-motoko.mjs` rewrites `../examples/` → `/` at - sync time as a bridge until the upstream adopts the placeholder directly. -- `sidebar-motoko.mjs` contains the explicit Motoko sidebar as a transitional - file. It is deleted in the step below once step 11 above lands. - -**developer-docs side (separate PR — do after upstream PR merges):** - -The following changes must NOT be merged until the upstream reorganization PR -has landed and the submodule has been bumped. Merging them early permanently -breaks the automated weekly sync CI (`sync-motoko.yml` runs `npm run sync:motoko` -weekly; it would fail on the structure guard with every new Motoko release until -the upstream changes are in place). - -1. Replace `sync-motoko.sh` with the simplified rsync version shown above. Add a - structure guard at the top: if `$SOURCE_DIR/fundamentals/1-basic-syntax` still - exists (old numeric-prefix layout), exit with a clear error. Once upstream - deletes the top-level section `index.md` files, the `--exclude='index.md'` flags - become no-ops and can be removed. Remove the postprocess call. -2. Delete `postprocess-motoko.mjs`. -3. Delete `sidebar-motoko.mjs`. Replace its import in `sidebar.mjs` with: - ```js - export const motokoSidebar = { - label: "Motoko", - collapsed: true, - autogenerate: { directory: "languages/motoko" }, - }; - ``` - New pages in any section appear automatically. No sidebar config to maintain. - -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. - ---- - -## Appendix: additional decisions - -### If Docusaurus is dropped from the upstream repo - -The motoko team is considering moving away from Docusaurus in `caffeinelabs/motoko`. -If that happens, some of the changes above become simpler or can be deferred: - -- **§2 (sidebar.order)**: If Docusaurus is dropped, `sidebar_position` can be - removed entirely rather than migrated. `sidebar.order` in Starlight frontmatter - remains the right replacement. -- **§6 (aside types)**: Without Docusaurus compatibility to maintain, `:::info` can - simply become `:::note` with no concern about backward breakage on the docs site. -- **§7 (REPL flags)**: `no-repl` is Docusaurus-specific. Without Docusaurus, REPL - flags can be removed entirely rather than normalized. Bare `` ```motoko `` is the - correct form for a static site. -- **§9 (changelog)**: The `md reference` block is Docusaurus-specific and would - need replacing regardless of which framework replaces it. -- **§1, §3, §4, §5, §8, §10**: Framework-independent — required regardless of - which docs tool the upstream uses. - -In practice: proceed with this plan without waiting for a Docusaurus decision. The -changes are safe whether Docusaurus stays or goes. - -### Upstream agent instructions: `_category_.yml` and `index.md` - -The upstream `caffeinelabs/motoko` currently uses two Docusaurus-specific -constructs for sidebar navigation that have no equivalent in Starlight. Both -must be replaced as part of the reorganization (or removed if Docusaurus is -dropped). - -#### `_category_.yml` files - -Each `_category_.yml` defines the label, position, and collapsed state for a -directory in the Docusaurus sidebar. In Starlight, this information goes into -an `index.md` file in the same directory with `sidebar.order` and -`sidebar.label` frontmatter. - -**Mapping for all `_category_.yml` files in the synced sections:** - -| Directory (post-rename) | `_category_.yml` | Action | -|---|---|---| -| `fundamentals/` | `position: 3, label: 'Fundamentals'` | Delete — label comes from `sidebar.mjs` in developer-docs, not from upstream | -| `fundamentals/basic-syntax/` | `position: 2, label: 'Basic syntax'` | Create `index.md` stub with `sidebar: { order: 1, label: "Basic syntax" }` | -| `fundamentals/actors/` | `position: 3, label: 'Actors'` | Create `index.md` stub with `sidebar: { order: 2, label: "Actors" }` | -| `fundamentals/types/` | `position: 4, label: 'Types'` | Create `index.md` stub with `sidebar: { order: 3, label: "Types" }` | -| `fundamentals/declarations/` | `position: 5, label: 'Declarations'` | Create `index.md` stub with `sidebar: { order: 4, label: "Declarations" }` | -| `fundamentals/control-flow/` | `position: 6, label: 'Control flow'` | Create `index.md` stub with `sidebar: { order: 5, label: "Control flow" }` | -| `icp-features/` | `position: 4, label: 'ICP features'` | Delete — label comes from `sidebar.mjs` | -| `reference/` | `position: 13, label: 'Motoko references'` | Delete — label comes from `sidebar.mjs` | - -Note: the Starlight `sidebar.order` values (1–5) for fundamentals subdirs do -not match the Docusaurus `position` values (2–6). The difference is that -Docusaurus counts `hello-world.md` (position 1) as a sibling, while Starlight -uses the subdir `index.md` order only among subdirs. What matters is the -relative order among the five subdirs, not the absolute number. - -The metadata stub format: -```yaml ---- -sidebar: - order: 1 - label: "Basic syntax" ---- -``` -No title, description, or body content. This is a Starlight navigation -control file only. - -After creating the `index.md` stubs, delete every `_category_.yml` in the repo -(they have no meaning outside Docusaurus). - -#### `index.md` files in `fundamentals/` subdirs - -The current `index.md` files in `fundamentals/1-basic-syntax/`, -`fundamentals/3-types/`, `fundamentals/4-declarations/`, and -`fundamentals/5-control-flow/` are Docusaurus section landing pages. Their -content is a numbered list of links to pages in the section — useful in -Docusaurus where the section heading is a clickable link. In Starlight, the -sidebar handles navigation automatically; these pages are not needed. - -**Replace** each of these `index.md` files with the metadata stub described -above (matching the `_category_.yml` values for that directory). The existing -list content is Docusaurus navigation scaffold and can be discarded. - -`fundamentals/2-actors/` currently has no `index.md`. **Create** one with the -stub for order 2 / label "Actors" (the `_category_.yml` position and label). - -**Do NOT touch** `fundamentals/2-actors/6-orthogonal-persistence/index.md` — -this file contains real conceptual content comparing both persistence modes. -It must be **renamed** to `overview.md` (Change §1) to distinguish it as a -content page from the ordering stubs. - -The top-level `fundamentals/index.md`, `icp-features/index.md`, and -`reference/index.md` are Docusaurus section landing pages (nav scaffold with -no Starlight equivalent). **Delete them** as part of the Docusaurus cleanup. - -### `base-core-migration.md` in the sidebar - -`base-core-migration.md` is currently excluded from the sidebar and linked from -the Motoko overview (`docs/languages/motoko/index.md`) only. This is the right -call: `mo:base` has been deprecated for a while and most new developers will never -need the migration guide. Keeping it off the sidebar avoids adding a dead-weight -entry that implies the base library is still relevant. The guide remains fully -discoverable via site search and via the overview link for developers who do need -it. No change recommended. diff --git a/.sources/motoko b/.sources/motoko index 75c4123f..a9cc50f3 160000 --- a/.sources/motoko +++ b/.sources/motoko @@ -1 +1 @@ -Subproject commit 75c4123f4d117f334d174656d049423efe6dcaab +Subproject commit a9cc50f36fc516d8f4ab73445cac9bb6fced4780 diff --git a/docs/languages/motoko/base-core-migration.md b/docs/languages/motoko/base-core-migration.md index 6185e780..70bf783b 100644 --- a/docs/languages/motoko/base-core-migration.md +++ b/docs/languages/motoko/base-core-migration.md @@ -1,11 +1,13 @@ --- -sidebar_position: 12 -description: "Motoko language documentation" title: "Motoko `base` to `core` migration guide" +description: "Comprehensive guide for migrating from the Motoko base package to the new core package." +sidebar: + order: 12 + hidden: true --- -* [GitHub repository](https://github.com/dfinity/motoko-core) -* [Documentation](https://mops.one/core) +* [GitHub repository](https://github.com/caffeinelabs/motoko-core) +* [Documentation](https://mops.one/core/docs/) The `core` package is a new and improved standard library for Motoko, focusing on: * AI-friendly design patterns. @@ -28,7 +30,7 @@ If you are migrating an existing project, you can keep the `base` import and gra ### Important considerations -:::warning[Version requirements] +:::caution[Version requirements] The `core` package depends on new language features, so make sure to update to the latest dfx (0.28+) or Motoko compiler (0.15+) before migrating. ::: @@ -40,9 +42,9 @@ When updating to the `core` package: - Hash-based data structures are no longer included in the standard library. It is encouraged to use ordered maps and sets for improved security. - In some cases, it won't be possible to fully migrate to `core` due to removal of some features in `base`. In these cases, you can continue using both packages side-by-side or search for [Mops packages](https://mops.one/) built by the community. -For details on function signatures, please refer to the official [documentation](https://mops.one/core). +For details on function signatures, please refer to the official [documentation](https://mops.one/core/docs/). -Also, feel free to ask for help by posting on the [ICP developer forum](https://forum.dfinity.org/c/developers) or opening a GitHub issue on the [`dfinity/motoko-core`](https://github.com/dfinity/motoko-core/issues) repository. +Also, feel free to ask for help by posting on the [ICP developer forum](https://forum.dfinity.org/c/developers) or opening a GitHub issue on the [`caffeinelabs/motoko-core`](https://github.com/caffeinelabs/motoko-core/issues) repository. ## Module changes @@ -158,7 +160,7 @@ The `core` package brings significant changes to data structures, making a clear - `sortInPlace()` - Use `VarArray.sortInPlace()` instead - `tabulateVar()` - Use `VarArray.tabulate()` instead -### [`Blob`](https://mops.one/core/docs/Blob) +### [`Blob`](https://mops.one/core/docs/Blo) #### Modified functions - `fromArrayMut()` → `fromVarArray()` @@ -187,7 +189,7 @@ The `core` package brings significant changes to data structures, making a clear - `isLowercase()` → `isLower()` - `isUppercase()` → `isUpper()` -### [`Debug`](https://mops.one/core/docs/Debug) +### [`Debug`](https://mops.one/core/docs/Deug) #### Added functions - `todo()` - Replaces `Prelude.nyi()` @@ -258,7 +260,7 @@ Helper functions have been added, such as `allValues()`, for each finite type in - `rangeBy()`, `rangeByInclusive()` - Range with step - `toInt()` - Convert to Int -### [`Int8`, `Int16`, `Int32`, `Int64`, `Nat8`, `Nat16`, `Nat32`, `Nat64`](https://mops.one/core) +### [`Int8`, `Int16`, `Int32`, `Int64`, `Nat8`, `Nat16`, `Nat32`, `Nat64`](https://mops.one/core/docs/) #### Renamed fields @@ -293,7 +295,7 @@ Helper functions have been added, such as `allValues()`, for each finite type in The `Random` module has been completely redesigned in the core package with a new API that provides better control over random number generation and supports both pseudo-random and cryptographic random number generation. -```motoko +```motoko no-repl import Random "mo:core/Random"; persistent actor { @@ -370,7 +372,7 @@ The new migration pattern allows you to automatically convert existing stable da The `with migration` syntax follows this structure: -```motoko +```motoko no-repl ( with migration = func( state : { @@ -389,7 +391,7 @@ persistent actorApp { It's also possible to use a function defined in an imported module: -```motoko +```motoko no-repl import { migrate } "Migration"; (with migration = migrate) @@ -404,7 +406,7 @@ This pattern ensures that existing stable data is preserved and converted to the #### Original (`base`) -```motoko +```motoko no-repl import Buffer "mo:base/Buffer"; persistent actor{ @@ -433,7 +435,7 @@ persistent actor{ #### Updated (`core`) -```motoko +```motoko no-repl import List "mo:core/List"; ( @@ -466,7 +468,7 @@ persistent actorApp { #### Original (`base`) -```motoko +```motoko no-repl import Deque "mo:base/Deque"; persistent actor{ @@ -492,7 +494,7 @@ persistent actor{ #### Updated (`core`) -```motoko +```motoko no-repl import Deque "mo:base/Deque"; // For migration import Queue "mo:core/Queue"; @@ -537,7 +539,7 @@ import Queue "mo:core/Queue"; #### Original (`base`) -```motoko +```motoko no-repl import HashMap "mo:base/HashMap"; import Text "mo:base/Text"; import Iter "mo:base/Iter"; @@ -570,7 +572,7 @@ persistent actor{ #### Updated (`core`) -```motoko +```motoko no-repl import Map "mo:core/Map"; import Text "mo:core/Text"; import Iter "mo:core/Iter"; @@ -607,7 +609,7 @@ persistent actor{ #### Original (`base`) -```motoko +```motoko no-repl import OrderedMap "mo:base/OrderedMap"; import Text "mo:base/Text"; import Iter "mo:base/Iter"; @@ -634,7 +636,7 @@ persistent actor{ #### Updated (`core`) -```motoko +```motoko no-repl import OrderedMap "mo:base/OrderedMap"; // For migration import Map "mo:core/Map"; import Text "mo:core/Text"; @@ -675,7 +677,7 @@ persistent actor{ #### Original (`base`) -```motoko +```motoko no-repl import OrderedSet "mo:base/OrderedSet"; import Text "mo:base/Text"; import Iter "mo:base/Iter"; @@ -704,7 +706,7 @@ persistent actor{ #### Updated (`core`) -```motoko +```motoko no-repl import OrderedSet "mo:base/OrderedSet"; // For migration import Set "mo:core/Set"; import Text "mo:core/Text"; @@ -747,7 +749,7 @@ persistent actorApp { #### Original (`base`) -```motoko +```motoko no-repl import Trie "mo:base/Trie"; import Text "mo:base/Text"; import Iter "mo:base/Iter"; @@ -778,7 +780,7 @@ persistent actor{ #### Updated (`core`) -```motoko +```motoko no-repl import Trie "mo:base/Trie"; // For migration import Map "mo:core/Map"; import Text "mo:core/Text"; @@ -816,7 +818,7 @@ persistent actor{ #### Original (`base`) -```motoko +```motoko no-repl import TrieMap "mo:base/TrieMap"; import Text "mo:base/Text"; import Iter "mo:base/Iter"; @@ -849,7 +851,7 @@ persistent actor{ #### Updated (`core`) -```motoko +```motoko no-repl import Map "mo:core/Map"; import Text "mo:core/Text"; import Iter "mo:core/Iter"; @@ -886,7 +888,7 @@ persistent actor{ #### Original (`base`) -```motoko +```motoko no-repl import TrieSet "mo:base/TrieSet"; import Text "mo:base/Text"; @@ -913,7 +915,7 @@ persistent actor{ #### Updated (`core`) -```motoko +```motoko no-repl import Set "mo:core/Set"; import Text "mo:core/Text"; import Iter "mo:core/Iter"; diff --git a/docs/languages/motoko/fundamentals/actors/actors-async.md b/docs/languages/motoko/fundamentals/actors/actors-async.md index a1594095..a293fff1 100644 --- a/docs/languages/motoko/fundamentals/actors/actors-async.md +++ b/docs/languages/motoko/fundamentals/actors/actors-async.md @@ -1,10 +1,11 @@ --- -sidebar_position: 1 -description: "Motoko language documentation" title: "Actors & async data" +description: "The actor programming model was designed to solve concurrency issues by encapsulating state and computation within independent units called actors." +sidebar: + order: 1 --- -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 programming model was designed to solve concurrency issues by encapsulating [state](./state.md) and computation within independent units called **actors**. The actor model is built on four key principles: @@ -105,7 +106,7 @@ To access the result of an `async` value, the receiver of the future uses an `aw For example, to use the result of `Counter.read()` above, we can first bind the future to an identifier `a`, and then `await a` to retrieve the underlying [`Nat`](https://mops.one/core/docs/Nat), `n`: -``` motoko no-repl +```motoko no-repl let a : async Nat = Counter.read(); let n : Nat = await a; ``` @@ -116,7 +117,7 @@ The second line `await`s this future and extracts the result, a natural number. Typically, one rolls the two steps into one and just awaits an asynchronous call directly: -``` motoko no-repl +```motoko no-repl let n : Nat = await Counter.read(); ``` @@ -130,7 +131,7 @@ An `await` will always suspend execution and commit state, even if its future is When several futures are issued in parallel and racing to complete, it can be more efficient to opt out of the unconditional behavior of `await` and immediately continue with a result when it is available: -``` motoko no-repl +```motoko no-repl let a : async Nat = CounterA.read(); let b : async Nat = CounterB.read(); let sum : Nat = (await a) + (await? b); @@ -177,7 +178,7 @@ A function that does not use `await` runs atomically, meaning nothing else can c For example, the implementation of `bump()` above is guaranteed to increment and read the value of `count`, in one atomic step. The following alternative implementation does not have the same semantics and allows another client of the actor to interfere with its operation. -``` motoko no-repl +```motoko no-repl public shared func bump() : async Nat { await inc(); await read(); @@ -216,7 +217,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/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](./actors-async.md#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"; @@ -287,7 +288,7 @@ Use `async*` and `await*` carefully. In Motoko, a regular `await` is a commit po ### Example -``` motoko no-repl +```motoko no-repl persistent actor class (Logger : actor { log : Text -> async () }) { var logging = true; diff --git a/docs/languages/motoko/fundamentals/actors/compatibility.md b/docs/languages/motoko/fundamentals/actors/compatibility.md index bb918ff8..382ff27d 100644 --- a/docs/languages/motoko/fundamentals/actors/compatibility.md +++ b/docs/languages/motoko/fundamentals/actors/compatibility.md @@ -1,18 +1,17 @@ --- -sidebar_position: 4 -description: "Motoko language documentation" title: "Verifying upgrade compatibility" +description: "When upgrading a canister, it is important to verify that the upgrade can proceed without:" +sidebar: + order: 4 --- - - When upgrading a canister, it is important to verify that the upgrade can proceed without: - Introducing an incompatible change in stable declarations. - 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/actors/orthogonal-persistence/enhanced), Motoko rejects incompatible changes of stable declarations. +Moreover, with [enhanced orthogonal persistence](./orthogonal-persistence/enhanced.md), Motoko rejects incompatible changes of stable declarations. ## Upgrade example @@ -52,12 +51,12 @@ You can think of this as the interior interface of the actor, that it presents t For example, `v1`'s stable types: -```motoko no-repl file=/count-v1.most +```motoko no-repl title="count-v1.most" file=/count-v1.most ``` An upgrade from `v1` to `v2`'s stable types consumes a [`Nat`](https://mops.one/core/docs/Nat) as an [`Int`](https://mops.one/core/docs/Nat), which is valid because `Nat <: Int`, that is, `Nat` is a subtype of `Int`. -```motoko no-repl file=/count-v2.most +```motoko no-repl title="count-v2.most" file=/count-v2.most ``` ## Evolving the Candid interface @@ -74,38 +73,38 @@ An upgrade is safe provided that both the Candid interface and stable type signa does not involve promotion to `Any` or dropping object fields. * The Candid interface evolves to a subtype. -Consider the following four versions of the counter example: +Consider the following four versions of the counter example. The `// Version: 1.0.0` comment at the top of each `.most` file is the stable signature format version, not the application version. See [Stable signature versions](#stable-signature-versions) below for the full taxonomy. Version `v0` with Candid interface `v0.did` and stable type interface `v0.most`: -```candid file=/count-v0.did +``` candid file=/count-v0.did ``` -```motoko no-repl file=/count-v0.most +```motoko no-repl title="count-v0.most" file=/count-v0.most ``` Version `v1` with Candid interface `v1.did` and stable type interface `v1.most`, -```candid file=/count-v1.did +``` candid file=/count-v1.did ``` -```motoko no-repl file=/count-v1.most +```motoko no-repl title="count-v1.most" file=/count-v1.most ``` Version `v2` with Candid interface `v2.did` and stable type interface `v2.most`, -```candid file=/count-v2.did +``` candid file=/count-v2.did ``` -```motoko no-repl file=/count-v2.most +```motoko no-repl title="count-v2.most" file=/count-v2.most ``` Version `v3` with Candid interface `v3.did` and stable type interface `v3.most`: -```candid file=/count-v3.did +``` candid file=/count-v3.did ``` -```motoko no-repl file=/count-v3.most +```motoko no-repl title="count-v3.most" file=/count-v3.most ``` ## Incompatible upgrade @@ -121,7 +120,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/actors/orthogonal-persistence/enhanced), Motoko actively rejects any upgrades that require type-incompatible state changes. +With [enhanced orthogonal persistence](./orthogonal-persistence/enhanced.md), Motoko actively rejects any upgrades that require type-incompatible state changes. This is to guarantee that the stable state is always kept safe. @@ -134,7 +133,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/actors/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](./orthogonal-persistence/classical.md) 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`. ::: @@ -232,7 +231,7 @@ The stable signature of an actor with a migration function now consists of two o For example, this is the combined signature of the previous example: -```motoko no-repl file=/count-v9.most +```motoko no-repl title="count-v9.most" file=/count-v9.most ``` The second signature is determined solely by the actor's stable variable declarations. @@ -244,7 +243,7 @@ The migration function can be deleted or adjusted on the next upgrade. ## Enhanced stable signatures -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. +When using [enhanced multi-migration](./enhanced-multi-migration.md), 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 @@ -252,12 +251,12 @@ Motoko uses three versions of the stable signature format, each corresponding to **Version 1.0.0: Single.** The original format, listing the actor's stable fields. Used when the actor has no migration function. -```motoko no-repl file=/count-v1.most +```motoko no-repl title="count-v1.most" file=/count-v1.most ``` **Version 3.0.0: Pre/Post.** Used when the actor declares a single migration function via `(with migration = ...)`. The signature contains a pre-signature (the fields the migration function consumes from the old actor) and a post-signature (the new actor's stable fields): -```motoko no-repl file=/count-v9.most +```motoko no-repl title="count-v9.most" file=/count-v9.most ``` Fields marked `in` are required inputs that must be present in the previous actor. Fields marked `stable` are carried through or newly declared. @@ -368,10 +367,10 @@ cannot be consumed at new type var Float ``` -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. +With [enhanced orthogonal persistence](./orthogonal-persistence/enhanced.md), 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/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. +With [classical orthogonal persistence](./orthogonal-persistence/classical.md), 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 @@ -403,8 +402,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/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. +It is recommended not to continue, as you will lose the state in older versions of Motoko that use [classical orthogonal persistence](./orthogonal-persistence/classical.md). +Upgrading with [enhanced orthogonal persistence](./orthogonal-persistence/enhanced.md) 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/actors/data-persistence.md b/docs/languages/motoko/fundamentals/actors/data-persistence.md index 598e812f..b97eed2c 100644 --- a/docs/languages/motoko/fundamentals/actors/data-persistence.md +++ b/docs/languages/motoko/fundamentals/actors/data-persistence.md @@ -1,7 +1,8 @@ --- -sidebar_position: 3 -description: "Motoko language documentation" title: "Data persistence" +description: "One key feature of Motoko is its ability to automatically persist the program's state without explicit user instruction." +sidebar: + order: 3 --- One key feature of Motoko is its ability to automatically persist the program's state without explicit user instruction. This is called **orthogonal persistence**. Data persists across transactions and canister upgrades. @@ -80,7 +81,7 @@ __Discouraged and not recommended__: [Pre- and post-upgrade hooks](#preupgrade-a The collection of stable variable declarations in an actor can be summarized in a stable signature. The textual representation of an actor’s stable signature resembles the internals of a Motoko actor type. It specifies the names, types, and mutability of the actor’s stable fields, possibly preceded by relevant Motoko type declarations. -``` motoko no-repl +```motoko no-repl actor { stable x : Nat; stable var y : Int; @@ -120,7 +121,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/actors/orthogonal-persistence/enhanced), Motoko rejects incompatible changes of stable declarations during an upgrade attempt. +With [enhanced orthogonal persistence](./orthogonal-persistence/enhanced.md), 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: @@ -129,7 +130,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/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. +With [classical orthogonal persistence](./orthogonal-persistence/classical.md), 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. ::: @@ -178,8 +179,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/actors/compatibility#explicit-migration-using-a-migration-function) and the -reference material on [migration expressions](/languages/motoko/reference/language-manual#migration-expressions). +For more information, see the [example of explicit migration](./compatibility.md#explicit-migration-using-a-migration-function) and the +reference material on [migration expressions](../../language-manual.md#migration-expressions). ## Legacy features diff --git a/docs/languages/motoko/fundamentals/actors/enhanced-multi-migration.md b/docs/languages/motoko/fundamentals/actors/enhanced-multi-migration.md index 3d6340a6..1275b77a 100644 --- a/docs/languages/motoko/fundamentals/actors/enhanced-multi-migration.md +++ b/docs/languages/motoko/fundamentals/actors/enhanced-multi-migration.md @@ -1,12 +1,13 @@ --- -sidebar_position: 8 -description: "Motoko language documentation" title: "Enhanced multi-migration" +description: "Enhanced multi-migration lets you manage canister state changes over time through a series of migration modules, each stored in its own file." +sidebar: + order: 8 --- Enhanced multi-migration lets you manage canister state changes over time through a series of migration modules, each stored in its own file. Instead of writing a single inline migration function, one builds up a chain of small, self-contained migrations that the compiler and runtime apply in order. -This approach is especially useful for long-lived canisters whose data shape evolves across many deployments. Each migration captures one logical change: adding a field, renaming a field, changing a type: and the compiler verifies that the entire chain is consistent. +This approach is especially useful for long-lived canisters whose data shape evolves across many deployments. Each migration captures one logical change (adding a field, renaming a field, or changing a type), and the compiler verifies that the entire chain is consistent. ## Overview @@ -17,10 +18,10 @@ With enhanced multi-migration you: 3. Each migration module exports a `public func migration({...}) : {...}` that transforms a subset of stable fields. 4. Pass `--enhanced-migration ./migrations` to `moc` when compiling. -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. +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/actors/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](./compatibility.md#explicit-migration-using-a-migration-function). ::: ## Getting started @@ -52,7 +53,7 @@ module { } ``` -The input record describes which stable fields this migration reads from the current state. The output record describes which fields this migration produces. The input field types must be compatible with the state at that point in the chain, and the output field types must ultimately be compatible with the new actor's declared stable fields. A migration only needs to mention the fields it cares about: all other stable fields are carried through unchanged. +The input record describes which stable fields this migration reads from the current state. The output record describes which fields this migration produces. The input field types must be compatible with the state at that point in the chain, and the output field types must ultimately be compatible with the new actor's declared stable fields. A migration only needs to mention the fields it cares about; all other stable fields are carried through unchanged. ### The actor @@ -71,7 +72,7 @@ actor { } ``` -The initial value of each uninitialized variable is determined entirely by the migration chain. When the canister is first deployed, every migration runs in order and the final state provides the values. On subsequent upgrades, only newly added migrations execute, but the result is the same: the migration chain: not the actor source: is the single source of truth for stable variable values. +The initial value of each uninitialized variable is determined entirely by the migration chain. When the canister is first deployed, every migration runs in order and the final state provides the values. On subsequent upgrades, only newly added migrations execute, but the result is the same: the migration chain (not the actor source) is the single source of truth for stable variable values. The compiler rejects any stable variable that carries an initializer when `--enhanced-migration` is enabled. This prevents ambiguity about whether the value comes from the migration chain or from the inline expression. @@ -256,7 +257,7 @@ Migrations can perform arbitrary computation. For example, splitting a full name ```motoko no-repl // migrations/20250601_000000_SplitName.mo -import Text "mo:base/Text"; +import Text "mo:core/Text"; module { public func migration(old : { name : Text }) : { firstName : Text; lastName : Text } { @@ -412,6 +413,6 @@ moc --enhanced-orthogonal-persistence \ ## See also -- [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) +- [Data persistence](./data-persistence.md) +- [Verifying upgrade compatibility](./compatibility.md) +- [Enhanced orthogonal persistence](./orthogonal-persistence/enhanced.md) diff --git a/docs/languages/motoko/fundamentals/actors/index.md b/docs/languages/motoko/fundamentals/actors/index.md new file mode 100644 index 00000000..3d1af31b --- /dev/null +++ b/docs/languages/motoko/fundamentals/actors/index.md @@ -0,0 +1,6 @@ +--- +title: "Actors" +sidebar: + order: 3 + label: "Actors" +--- diff --git a/docs/languages/motoko/fundamentals/actors/messaging.md b/docs/languages/motoko/fundamentals/actors/messaging.md index c3c057bd..6810a3e1 100644 --- a/docs/languages/motoko/fundamentals/actors/messaging.md +++ b/docs/languages/motoko/fundamentals/actors/messaging.md @@ -1,14 +1,15 @@ --- -sidebar_position: 4 -description: "Motoko language documentation" title: "Messaging" +description: "ICP enforces rules on when and how canisters communicate." +sidebar: + order: 5 --- 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. -Only async contexts support [error handling](/languages/motoko/fundamentals/error-handling) with `try/catch` because messaging errors only occur asynchronously. +Only async contexts support [error handling](../error-handling.md) with `try/catch` because messaging errors only occur asynchronously. In Motoko, an expression is considered to be in an async context if it appears inside an `async` function. Query functions are read-only, so they do not create an async context and therefore cannot use `await` or send messages. diff --git a/docs/languages/motoko/fundamentals/actors/mixins.md b/docs/languages/motoko/fundamentals/actors/mixins.md index cd8b9800..0d677846 100644 --- a/docs/languages/motoko/fundamentals/actors/mixins.md +++ b/docs/languages/motoko/fundamentals/actors/mixins.md @@ -1,6 +1,8 @@ --- title: "Mixins" -description: "Motoko language documentation" +description: "Using mixins to compose reusable actor components in Motoko." +sidebar: + order: 7 --- Mixins allow defining parts of actors in separate re-usable files that can be combined/included into a complete actor. diff --git a/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/classical.md b/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/classical.md index 5d87d27b..efd2e311 100644 --- a/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/classical.md +++ b/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/classical.md @@ -1,7 +1,8 @@ --- -sidebar_position: 3 -description: "Motoko language documentation" title: "Classical orthogonal persistence" +description: "Classical orthogonal persistence is the legacy implementation of Motoko's orthogonal persistence." +sidebar: + order: 3 --- Classical orthogonal persistence is the legacy implementation of Motoko's orthogonal persistence. Classical persistence is deprecated in favor of enhanced orthogonal persistence. @@ -20,7 +21,7 @@ Therefore, it is absolutely necessary to thoroughly test how much data an upgrad 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/actors/orthogonal-persistence/enhanced). +These issues are solved by [enhanced orthogonal persistence](./enhanced.md). :::note diff --git a/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced.md b/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced.md index ba4c49be..ee739b68 100644 --- a/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced.md +++ b/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced.md @@ -1,7 +1,8 @@ --- -sidebar_position: 2 -description: "Motoko language documentation" title: "Enhanced orthogonal persistence" +description: "Enhanced orthogonal persistence implements the vision of efficient and scalable orthogonal persistence in Motoko that combines:" +sidebar: + order: 2 --- Enhanced orthogonal persistence implements the vision of efficient and scalable orthogonal persistence in Motoko that combines: @@ -19,8 +20,8 @@ Moreover, it is advised to have a backup possibility for rescuing data even when ::: :::note -[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/fundamentals/actors/orthogonal-persistence/overview) for a comparison. +[Classical orthogonal persistence](./classical.md) 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](./index.md) for a comparison. ::: ## Design @@ -53,7 +54,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/actors/data-persistence#explicit-migration). +Any more complex change can be performed with programmatic instruction, see [explicit migration](../data-persistence.md#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/actors/orthogonal-persistence/index.md b/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/index.md new file mode 100644 index 00000000..1b595d3d --- /dev/null +++ b/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/index.md @@ -0,0 +1,6 @@ +--- +title: "Orthogonal persistence" +sidebar: + order: 6 + label: "Orthogonal persistence" +--- diff --git a/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/overview.md b/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/overview.md index 51b7da82..b3ebb7cf 100644 --- a/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/overview.md +++ b/docs/languages/motoko/fundamentals/actors/orthogonal-persistence/overview.md @@ -1,7 +1,8 @@ --- -sidebar_position: 1 -description: "Motoko language documentation" title: "What is orthogonal persistence?" +description: "Orthogonal persistence is the ability to for a program to automatically preserve its state across transactions and canister upgrades without requiring manual..." +sidebar: + order: 1 --- Orthogonal persistence is the ability to for a program to automatically preserve its state across transactions and canister upgrades without requiring manual intervention. This means that data persists seamlessly, without the need for a database, stable memory APIs, or specialized stable data structures. @@ -12,9 +13,9 @@ In contrast, other canister development languages like Rust require explicit han Motoko features two implementations for orthogonal persistence: -* [Enhanced orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/enhanced) provides very fast upgrades, scaling independently of the heap size. This is realized by retaining the entire Wasm main memory on an upgrade and simply performing a type-driven upgrade safety check. By using 64-bit address space, it is designed to scale beyond 4 GiB and in the future, offer the same capacity like stable memory. +* [Enhanced orthogonal persistence](./enhanced.md) provides very fast upgrades, scaling independently of the heap size. This is realized by retaining the entire Wasm main memory on an upgrade and simply performing a type-driven upgrade safety check. By using 64-bit address space, it is designed to scale beyond 4 GiB and in the future, offer the same capacity like stable memory. -* [Classical orthogonal persistence](/languages/motoko/fundamentals/actors/orthogonal-persistence/classical) is the old implementation of orthogonal persistence that is superseded by enhanced orthogonal persistence. On an upgrade, the runtime system first serializes the persistent data to stable memory and then deserializes it back again to main memory. While this is both inefficient and unscalable, it exhibits problems on shared immutable data (potentially leading to state explosion), deep structures (call stack overflow) and larger heaps (the implementation limits the stable data to at most 2 GiB). +* [Classical orthogonal persistence](./classical.md) is the old implementation of orthogonal persistence that is superseded by enhanced orthogonal persistence. On an upgrade, the runtime system first serializes the persistent data to stable memory and then deserializes it back again to main memory. While this is both inefficient and unscalable, it exhibits problems on shared immutable data (potentially leading to state explosion), deep structures (call stack overflow) and larger heaps (the implementation limits the stable data to at most 2 GiB). :::note diff --git a/docs/languages/motoko/fundamentals/actors/state.md b/docs/languages/motoko/fundamentals/actors/state.md index dbbf59a9..edf112a9 100644 --- a/docs/languages/motoko/fundamentals/actors/state.md +++ b/docs/languages/motoko/fundamentals/actors/state.md @@ -1,8 +1,8 @@ --- -sidebar_position: 2 -description: "Motoko language documentation" title: "Mutable state" -hide_table_of_contents: true +description: "In Motoko, each actor can use internal mutable state but cannot share it directly with other actors." +sidebar: + order: 2 --- In Motoko, each actor can use internal mutable state but cannot share it directly with other actors. Immutable data, however, can be shared among actors and accessed via their external entry points, which act as shareable functions. diff --git a/docs/languages/motoko/fundamentals/basic-syntax/characters-text.md b/docs/languages/motoko/fundamentals/basic-syntax/characters-text.md index 10260012..0810cbfc 100644 --- a/docs/languages/motoko/fundamentals/basic-syntax/characters-text.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/characters-text.md @@ -1,14 +1,15 @@ --- -sidebar_position: 5 -description: "Motoko language documentation" title: "Characters & text" +description: "The Char type in Motoko represents a single Unicode character delimited with a single quotation mark (')." +sidebar: + order: 5 --- ## Characters The `Char` type in Motoko represents a single Unicode character delimited with a single quotation mark (`'`). -```motoko +```motoko no-repl let letter : Char = 'A'; let symbol : Char = '✮'; @@ -20,7 +21,7 @@ let symbol : Char = '✮'; :::note[Iter] An `Iter` is an object that sequentially produces values of specified type `T` until no more values remain. ::: -``` motoko +```motoko no-repl import Char "mo:core/Char"; func reverse(t: Text) : Text { @@ -36,7 +37,7 @@ reverse("Motoko"); The operator `#` concatenates two `Text` values. -```motoko +```motoko no-repl import Text "mo:core/Text"; import Iter "mo:core/Iter"; import Char "mo:core/Char"; @@ -81,13 +82,13 @@ persistent actor Alternator { Strings of characters, familiar from other languages, are called **text** in Motoko, and represented using the [`Text`](https://mops.one/core/docs/Text) type. A text value is an immutable sequence of Unicode characters delimited with a double quotation mark (`"`). -```motoko +```motoko no-repl let greeting : Text = "Hello, world!"; ``` The `#` operator concatenates two `Text` values: -``` motoko +```motoko no-repl // Concatenating text "ICP " # "❤️" # " Motoko" // "ICP ❤️ Motoko" @@ -95,13 +96,13 @@ The `#` operator concatenates two `Text` values: `t.size()` can be used to return the number of characters in the text `t`. -```motoko +```motoko no-repl "abc".size() == 3 ``` `t.chars()` returns an iterator enumerating the characters in `t`. For example: -```motoko +```motoko no-repl import Char "mo:core/Char"; import Debug "mo:core/Debug"; diff --git a/docs/languages/motoko/fundamentals/basic-syntax/comments.md b/docs/languages/motoko/fundamentals/basic-syntax/comments.md index 27332c67..a2aa6f78 100644 --- a/docs/languages/motoko/fundamentals/basic-syntax/comments.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/comments.md @@ -1,7 +1,8 @@ --- -sidebar_position: 10 -description: "Motoko language documentation" title: "Comments" +description: "Motoko supports single-line, multi-line, and nested comments." +sidebar: + order: 10 --- Motoko supports single-line, multi-line, and nested comments. @@ -44,7 +45,7 @@ Multi-line comments can be nested within each other. ## Resources -- [Comment style guide](/languages/motoko/reference/style-guide#comments) +- [Comment style guide](../../style-guide.md#comments) - [Generating Motoko documentation](/developer-tools/#mo-doc) diff --git a/docs/languages/motoko/fundamentals/basic-syntax/defining-an-actor.md b/docs/languages/motoko/fundamentals/basic-syntax/defining-an-actor.md index 5410897d..a8a95001 100644 --- a/docs/languages/motoko/fundamentals/basic-syntax/defining-an-actor.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/defining-an-actor.md @@ -1,13 +1,13 @@ --- -sidebar_position: 1 -description: "Motoko language documentation" title: "Defining an actor" -hide_table_of_contents: true +description: "In Motoko, an actor is a computational process with its own state and behavior." +sidebar: + order: 1 --- -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. +In Motoko, an **actor** is a computational process with its own [state](../actors/state.md) 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/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](../actors/actors-async.md#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. @@ -28,7 +28,7 @@ Each actor maintains separate queues of incoming messages, one per sender. Messa Since actors process messages independently, multiple actors can handle messages in parallel, enabling concurrent execution across actors. -```motoko name=Main +```motoko no-repl // Declares an actor named Main. persistent actor Main { // Define a private variable called 'count' to track the number of greetings. @@ -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/actors/data-persistence). +Learn more about [persistence](../actors/data-persistence.md). ::: 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/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. +A Motoko actor always presents its interface as a suite of named [functions](./functions.md) (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/actors-async) +- [Actors](../actors/actors-async.md) diff --git a/docs/languages/motoko/fundamentals/basic-syntax/functions.md b/docs/languages/motoko/fundamentals/basic-syntax/functions.md index a0bee145..03be2c2d 100644 --- a/docs/languages/motoko/fundamentals/basic-syntax/functions.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/functions.md @@ -1,13 +1,13 @@ --- -sidebar_position: 8 -description: "Motoko language documentation" title: "Functions" -hide_table_of_contents: true +description: "Functions in Motoko can have various attributes, the most fundamental being whether they are public or private." +sidebar: + order: 8 --- 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: +The most basic Motoko [function declaration](../declarations/function-declarations.md) is: ```motoko no-repl func exampleFunction() : () {}; @@ -15,7 +15,7 @@ func exampleFunction() : () {}; In objects, modules, and actors, all functions are private by default unless explicitly declared as `public`. -```motoko +```motoko no-repl object Counter { var value = 0; func reset() { value := 0 }; @@ -48,13 +48,13 @@ Shared functions come in several forms: - `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). +[Learn more about function types](../types/function-types.md). ::: For example, you can rewrite the object above as an actor: -``` motoko +```motoko no-repl persistent actor Digit { var value = 0; func reset() { value := 0 }; @@ -70,7 +70,7 @@ persistent actor Digit { Since the public functions of an actor must be `shared`, you can omit the `shared` keyword: -``` motoko +```motoko no-repl persistent actor Digit { var value = 0; func reset() { value := 0 }; diff --git a/docs/languages/motoko/fundamentals/basic-syntax/identifiers.md b/docs/languages/motoko/fundamentals/basic-syntax/identifiers.md index 739e3cd2..e8b32dd8 100644 --- a/docs/languages/motoko/fundamentals/basic-syntax/identifiers.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/identifiers.md @@ -1,8 +1,8 @@ --- -sidebar_position: 7 -description: "Motoko language documentation" title: "Identifiers" -hide_table_of_contents: true +description: "Identifiers are names used for variables, functions, types, and other entities." +sidebar: + order: 7 --- Identifiers are names used for variables, functions, types, and other entities. They must start with a letter or an underscore and can contain letters, digits, and underscores. @@ -16,4 +16,4 @@ let snake_case_identifier = "for compatibility with other languages"; ## Reserved syntax keywords -Motoko reserves [keywords](/languages/motoko/reference/language-manual#keywords) for its syntax and they cannot be used as identifiers. +Motoko reserves [keywords](../../language-manual.md#keywords) for its syntax and they cannot be used as identifiers. diff --git a/docs/languages/motoko/fundamentals/basic-syntax/imports.md b/docs/languages/motoko/fundamentals/basic-syntax/imports.md index c0cb12a7..5f8a807d 100644 --- a/docs/languages/motoko/fundamentals/basic-syntax/imports.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/imports.md @@ -1,8 +1,8 @@ --- -sidebar_position: 2 -description: "Motoko language documentation" title: "Imports" -hide_table_of_contents: true +description: "In Motoko, related code modules are organized into packages." +sidebar: + order: 2 --- In Motoko, related code modules are organized into packages. Modules can be imported either from named packages or from the local file system using relative paths. The compiler locates packages on the file system based on a command line argument specifying their location. @@ -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/basic-syntax/imports). +Learn more about [modules and imports](./imports.md). diff --git a/docs/languages/motoko/fundamentals/basic-syntax/index.md b/docs/languages/motoko/fundamentals/basic-syntax/index.md new file mode 100644 index 00000000..9ac55043 --- /dev/null +++ b/docs/languages/motoko/fundamentals/basic-syntax/index.md @@ -0,0 +1,6 @@ +--- +title: "Basic syntax" +sidebar: + order: 2 + label: "Basic syntax" +--- diff --git a/docs/languages/motoko/fundamentals/basic-syntax/literals.md b/docs/languages/motoko/fundamentals/basic-syntax/literals.md index eec4035c..94eb047a 100644 --- a/docs/languages/motoko/fundamentals/basic-syntax/literals.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/literals.md @@ -1,8 +1,8 @@ --- -sidebar_position: 6 -description: "Motoko language documentation" title: "Literals" -hide_table_of_contents: true +description: "Literals are constant expressions that require no further evaluation:" +sidebar: + order: 6 --- Literals are constant expressions that require no further evaluation: @@ -19,11 +19,11 @@ Literals are constant expressions that require no further evaluation: You can use literals directly in expressions. -```motoko +```motoko no-repl 100 + 50 ``` ## Resources -- [Literals](/languages/motoko/reference/language-manual#literals) +- [Literals](../../language-manual.md#literals) diff --git a/docs/languages/motoko/fundamentals/basic-syntax/numbers.md b/docs/languages/motoko/fundamentals/basic-syntax/numbers.md index 0e105829..ac63f784 100644 --- a/docs/languages/motoko/fundamentals/basic-syntax/numbers.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/numbers.md @@ -1,7 +1,8 @@ --- -sidebar_position: 4 -description: "Motoko language documentation" title: "Numbers" +description: "The Nat type represents natural numbers, which are all non-negative integers (i.e., 0 and positive numbers)." +sidebar: + order: 4 --- ## Natural numbers @@ -16,7 +17,7 @@ let zero : Nat = 0; Defining a `Nat` with a negative value is a compile time error: -``` motoko +```motoko no-repl let negative : Nat = -1; // Error: Cannot assign a negative value to Nat ``` @@ -47,7 +48,7 @@ let trappingNat8 : Nat8 = 255+1; // trap: arithmetic overflow [`Int`](https://mops.one/core/docs/Int) represents all integers, both positive and negative (e.g., -2, -1, 0, 1, 2). -For scenarios requiring fixed-size integers, Motoko offers bounded variants with specific bit-widths ([`Int8`](https://mops.one/core/docs/Int8), [`Int16`](https://mops.one/core/docs/Int16), [`Int32`](https://mops.one/core/docs/Int32), [`Int64`](https://mops.one/core/docs/Int64)). These types can overflow if their limits are exceeded, resulting in a [runtime error](/languages/motoko/fundamentals/error-handling). +For scenarios requiring fixed-size integers, Motoko offers bounded variants with specific bit-widths ([`Int8`](https://mops.one/core/docs/Int8), [`Int16`](https://mops.one/core/docs/Int16), [`Int32`](https://mops.one/core/docs/Int32), [`Int64`](https://mops.one/core/docs/Int64)). These types can overflow if their limits are exceeded, resulting in a [runtime error](../error-handling.md). ```motoko no-repl let a : Int = -42; @@ -70,7 +71,7 @@ let bigNumber : Int = 999_999_999_999_999; - [`Int32`](https://mops.one/core/docs/Int32) (32-bit signed integer) - [`Int64`](https://mops.one/core/docs/Int64) (64-bit signed integer) -Arithmetic on bounded integers can overflow if their limits are exceeded, resulting in a [runtime error](/languages/motoko/fundamentals/error-handling). +Arithmetic on bounded integers can overflow if their limits are exceeded, resulting in a [runtime error](../error-handling.md). ```motoko no-repl let trappingInt8 : Int8 = 127+1; // trap: arithmetic overflow diff --git a/docs/languages/motoko/fundamentals/basic-syntax/operators.md b/docs/languages/motoko/fundamentals/basic-syntax/operators.md index ac97c665..a422c989 100644 --- a/docs/languages/motoko/fundamentals/basic-syntax/operators.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/operators.md @@ -1,7 +1,8 @@ --- -sidebar_position: 9 -description: "Motoko language documentation" title: "Operators" +description: "Motoko provides various operators for working with numbers, text, and boolean values." +sidebar: + order: 9 --- Motoko provides various operators for working with numbers, text, and boolean values. They can be categorized as follows: @@ -170,13 +171,13 @@ Operators follow precedence rules, meaning that, in the absence of explicit pare For example: -```motoko +```motoko no-repl let result = 10 + 5 * 2; // result = 20 ``` Use parentheses to enforce a different order. -```motoko +```motoko no-repl let result = (10 + 5) * 2; // result = 30 ``` @@ -184,7 +185,7 @@ let result = (10 + 5) * 2; // result = 30 Pipes (`|>`) chain together function calls in a readable way. Instead of nesting function calls, pipes pass the result of one expression as an argument to the next function. The value of the left side of the pipe is referenced on the right side using an underscore (`_`). -```motoko +```motoko no-repl func double(n : Int) : Int { n * 2 }; func increment(n : Int) : Int { n + 1 }; diff --git a/docs/languages/motoko/fundamentals/basic-syntax/printing-values.md b/docs/languages/motoko/fundamentals/basic-syntax/printing-values.md index b59379e7..1d59cd50 100644 --- a/docs/languages/motoko/fundamentals/basic-syntax/printing-values.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/printing-values.md @@ -1,15 +1,15 @@ --- -sidebar_position: 3 -description: "Motoko language documentation" title: "Printing values" -hide_table_of_contents: true +description: "Motoko uses Debug.print to output text to the terminal or a canister's log depending on execution context." +sidebar: + order: 3 --- Motoko uses `Debug.print` to output text to the terminal or a canister's log depending on execution context. It takes a [`Text`](https://mops.one/core/docs/Text) value and returns `()`. `()` is the empty tuple and represents a token or trivial return value. -```motoko +```motoko no-repl import Debug "mo:core/Debug"; Debug.print("Hello, world!"); @@ -17,7 +17,7 @@ Debug.print("Hello, world!"); For debugging purposes, `debug_show` converts most Motoko types into [`Text`](https://mops.one/core/docs/Text). The operator handles most types well, but may not work with cyclic data structures or types containing functions or type parameters. -```motoko +```motoko no-repl import Debug "mo:core/Debug"; Debug.print(debug_show {life = 42} ); // "{life = 42}" @@ -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/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. +In contrast, [**pure functions**](../types/function-types.md#pure-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. ## Resources diff --git a/docs/languages/motoko/fundamentals/basic-syntax/traps.md b/docs/languages/motoko/fundamentals/basic-syntax/traps.md index aa013d68..75b1b11e 100644 --- a/docs/languages/motoko/fundamentals/basic-syntax/traps.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/traps.md @@ -1,21 +1,21 @@ --- -sidebar_position: 12 -description: "Motoko language documentation" title: "Assertions" -hide_table_of_contents: true +description: "An assertion checks a condition at runtime and traps if it fails." +sidebar: + order: 12 --- An assertion checks a condition at runtime and traps if it fails. -```motoko +```motoko no-repl let n = 10; assert n % 2 == 1; // Traps ``` -```motoko +```motoko no-repl let n = 10; assert n % 2 == 0; // Succeeds ``` -Assertions help catch logic errors early, but should not be used for regular [error handling](/languages/motoko/fundamentals/error-handling). +Assertions help catch logic errors early, but should not be used for regular [error handling](../error-handling.md). diff --git a/docs/languages/motoko/fundamentals/basic-syntax/whitespace.md b/docs/languages/motoko/fundamentals/basic-syntax/whitespace.md index 0e0ade53..5cc36c0f 100644 --- a/docs/languages/motoko/fundamentals/basic-syntax/whitespace.md +++ b/docs/languages/motoko/fundamentals/basic-syntax/whitespace.md @@ -1,20 +1,21 @@ --- -sidebar_position: 11 -description: "Motoko language documentation" title: "Whitespace" +description: "Whitespace characters (spaces, tabs, newlines) are generally ignored in Motoko, but are essential for separating syntax components like keywords and identifi..." +sidebar: + order: 11 --- Whitespace characters (spaces, tabs, newlines) are generally ignored in Motoko, but are essential for separating syntax components like keywords and identifiers. Proper use of whitespace enhances code readability. ### Incorrect use of whitespace -```motoko +```motoko no-repl persistent actor Counter{var x : Nat = 0; public func inc(): async Int{x+1; }}; ``` ### Proper whitespace usage -```motoko +```motoko no-repl persistent actor Counter { var x : Nat = 0; public func inc() : async Int { @@ -25,5 +26,5 @@ persistent actor Counter { ## Resources -- [Motoko style guide](/languages/motoko/reference/style-guide) +- [Motoko style guide](../../style-guide.md) diff --git a/docs/languages/motoko/fundamentals/contextual-dot.md b/docs/languages/motoko/fundamentals/contextual-dot.md index fd0b0437..da3bb87e 100644 --- a/docs/languages/motoko/fundamentals/contextual-dot.md +++ b/docs/languages/motoko/fundamentals/contextual-dot.md @@ -1,6 +1,8 @@ --- title: "Contextual dot notation" -description: "Motoko language documentation" +description: "Using contextual dot notation to call module functions with method-like syntax in Motoko." +sidebar: + order: 10 --- Contextual dot notation is a language feature that allows you to call functions from modules using object-oriented style syntax, where a value appears as the receiver of a method call. This feature bridges the gap between Motoko's procedural and object-oriented programming styles. @@ -13,7 +15,7 @@ In Motoko, there are two main approaches to organizing and calling related funct Consider a common operation on data structures. Without contextual dot notation, you would write: -```motoko +```motoko no-repl import Array "mo:core/Array"; let numbers = [1, 2, 3, 4, 5]; @@ -30,7 +32,7 @@ This functional style, while powerful, has some drawbacks: With contextual dot notation, you can rewrite the same code as: -```motoko +```motoko no-repl import Array "mo:core/Array"; let numbers = [1, 2, 3, 4, 5]; @@ -57,7 +59,7 @@ The self parameter is indicated by its position as the first parameter and its t Here's a more comprehensive example using the `Array` module: -```motoko +```motoko no-repl import Array "mo:core/Array"; import Nat "mo:core/Nat"; @@ -121,7 +123,7 @@ While any function can use contextual dot notation based on its first parameter Contextual dot notation works seamlessly with generic types: -```motoko +```motoko no-repl import Array "mo:core/Array"; // These work with any type T @@ -162,4 +164,4 @@ Contextual dot notation has some intentional limitations: ## See also - [Modules and imports](modules-imports) -- [Language reference](/languages/motoko/reference/language-manual#dotted-function-calls) \ No newline at end of file +- [Language reference](../language-manual#dotted-function-calls) \ No newline at end of file diff --git a/docs/languages/motoko/fundamentals/control-flow/basic-control-flow.md b/docs/languages/motoko/fundamentals/control-flow/basic-control-flow.md index e8b852e4..563988f8 100644 --- a/docs/languages/motoko/fundamentals/control-flow/basic-control-flow.md +++ b/docs/languages/motoko/fundamentals/control-flow/basic-control-flow.md @@ -1,7 +1,8 @@ --- -sidebar_position: 1 -description: "Motoko language documentation" title: "Basic control flow" +description: "In Motoko, code normally executes sequentially, evaluating expressions and declarations in order." +sidebar: + order: 1 --- In Motoko, code normally executes sequentially, evaluating expressions and declarations in order. @@ -14,7 +15,7 @@ However, certain constructs can alter the flow of control, such as exiting a blo | `return` | Exits a function and returns a value. | | `if` | Executes a block if the condition is `true`. | | `if/else` | Executes different blocks based on a condition. | -| `switch` | [Pattern matching](/languages/motoko/fundamentals/pattern-matching) for variants, options, results, etc. | +| `switch` | [Pattern matching](../pattern-matching.md) for variants, options, results, etc. | | `let-else` | Destructure a pattern and handle the failure case inline. | | `option block` | Evaluates an expression and wraps the result in an option type, allowing scoped handling of `null` values. | | `label/break` | Allows exiting loops early. | @@ -134,7 +135,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/control-flow/switch). +A more interesting example of option blocks can be found at the end of the section on [switch](./switch.md). ## `label` and `break` @@ -245,7 +246,7 @@ A `continue` expression skips the remainder of the current iteration in a loop a For example, computing the product we can skip a multiplication when the number is `1`: -``` motoko no-repl +```motoko no-repl func product(numbers : [Int]) : Int { var prod : Int = 1; for (number in numbers.vals()) { @@ -258,7 +259,7 @@ func product(numbers : [Int]) : Int { When you have nested loops and need to continue a specific outer loop, you can use a label: -``` motoko no-repl +```motoko no-repl func product(numbers : [Int]) : Int { var prod : Int = 1; label l for (number in numbers.vals()) { @@ -278,7 +279,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](/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. +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](../actors/actors-async.md#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/control-flow/blocks.md b/docs/languages/motoko/fundamentals/control-flow/blocks.md index f83f630f..ff6ac39e 100644 --- a/docs/languages/motoko/fundamentals/control-flow/blocks.md +++ b/docs/languages/motoko/fundamentals/control-flow/blocks.md @@ -1,7 +1,8 @@ --- -sidebar_position: 4 -description: "Motoko language documentation" title: "Block expressions" +description: "A block expression in Motoko is a sequence of declarations enclosed in { ..." +sidebar: + order: 4 --- A block expression in Motoko is a sequence of declarations enclosed in `{ ... }`. diff --git a/docs/languages/motoko/fundamentals/control-flow/conditionals.md b/docs/languages/motoko/fundamentals/control-flow/conditionals.md index 5a5122cf..8c5f50d3 100644 --- a/docs/languages/motoko/fundamentals/control-flow/conditionals.md +++ b/docs/languages/motoko/fundamentals/control-flow/conditionals.md @@ -1,7 +1,8 @@ --- -sidebar_position: 3 -description: "Motoko language documentation" title: "Conditionals" +description: "Conditionals in Motoko come in two forms: if-expressions and if-statements." +sidebar: + order: 3 --- Conditionals in Motoko come in two forms: **if-expressions** and **if-statements**. @@ -34,7 +35,7 @@ let identity : Text = The result of the `if-else` is assigned to `identity`. Here, both branches have the same type ([`Text`](https://mops.one/core/docs/Text) in this case) as does the entire `if-else`. -``` motoko no-repl +```motoko no-repl let n : Nat = 0; let parity = if (n % 2 == 0) #even else #odd; ``` @@ -42,7 +43,7 @@ Here, the first branch has type `{#even}` and the second branch has type `{#odd} Motoko will infer the common supertype for you, choosing the most specific one possible. If the types are inconsistent and only have the useless common supertype `Any`, Motoko will issue a warning: -``` motoko +```motoko no-repl let n : Nat = 0; let oops = if (n % 2 == 0) #even else 0; ``` diff --git a/docs/languages/motoko/fundamentals/control-flow/index.md b/docs/languages/motoko/fundamentals/control-flow/index.md new file mode 100644 index 00000000..84dc120a --- /dev/null +++ b/docs/languages/motoko/fundamentals/control-flow/index.md @@ -0,0 +1,6 @@ +--- +title: "Control flow" +sidebar: + order: 6 + label: "Control flow" +--- diff --git a/docs/languages/motoko/fundamentals/control-flow/loops.md b/docs/languages/motoko/fundamentals/control-flow/loops.md index 5a851a1a..58ed6e91 100644 --- a/docs/languages/motoko/fundamentals/control-flow/loops.md +++ b/docs/languages/motoko/fundamentals/control-flow/loops.md @@ -1,7 +1,8 @@ --- -sidebar_position: 2 -description: "Motoko language documentation" title: "Loops" +description: "In Motoko, loops provide flexible control over repetition, such as iterating over collections, looping while some condition holds, or just looping until an e..." +sidebar: + order: 2 --- @@ -52,7 +53,7 @@ label countLoop loop { A `loop-while` executes the loop body at least once, then repeats as long as the condition remains true. -``` motoko no-repl +```motoko no-repl import Debug "mo:core/Debug"; var count = 0; diff --git a/docs/languages/motoko/fundamentals/control-flow/switch.md b/docs/languages/motoko/fundamentals/control-flow/switch.md index 66c1f54f..34b22ac6 100644 --- a/docs/languages/motoko/fundamentals/control-flow/switch.md +++ b/docs/languages/motoko/fundamentals/control-flow/switch.md @@ -1,13 +1,13 @@ --- -sidebar_position: 5 -description: "Motoko language documentation" title: "Switch" -hide_table_of_contents: true +description: "A switch expression is a control flow construct that, given a value, selects a control flow path based on the pattern or shape of the value." +sidebar: + order: 5 --- A `switch` expression is a control flow construct that, given a value, selects a control flow path based on the pattern or shape of the value. -A switch is constructed from an expression and a sequence of cases. Each case consists of a [pattern](/languages/motoko/fundamentals/pattern-matching) guarding an expression or block that defines a possible branch of execution. +A switch is constructed from an expression and a sequence of cases. Each case consists of a [pattern](../pattern-matching.md) guarding an expression or block that defines a possible branch of execution. Switch evaluates its expression and based on its value, selects the first case whose pattern matches the value. Any identifiers bound by the pattern are available in the selected branch, allowing you to access case-specific data in the branch. @@ -24,7 +24,7 @@ Only the first case of a `switch` expression that matches will execute. The wild The simplest use of switch is to emulate an `if-else` expression: -``` motoko +```motoko no-repl func toText(b : Bool) : Text { switch b { case true "true"; @@ -35,7 +35,7 @@ func toText(b : Bool) : Text { If you add a second case for `true`, Motoko issues a warning that it will never be matched and is unreachable or dead code: -``` motoko +```motoko no-repl func toText(b : Bool) : Text { switch b { case true "true"; @@ -47,7 +47,7 @@ func toText(b : Bool) : Text { If you forget the case for `false`, Motoko will also issue a warning that `false is not covered by any case`: -``` motoko +```motoko no-repl func toText(b : Bool) : Text { switch b { case true "true"; @@ -77,7 +77,7 @@ Above, the example `switch` expressions have only matched against simple constan Here's a simple example of matching against an option: -``` motoko no-repl +```motoko no-repl func value(option : ?T, default : T) : T { switch option { case null default; @@ -92,7 +92,7 @@ If either case is omitted, Motoko will warn that the switch does not cover the ` Here's an example of a nested pattern: -``` motoko no-repl +```motoko no-repl type List = ?(T, List); func size(list : List) : Nat { @@ -111,7 +111,7 @@ In this example, the branches are enclosed in blocks to demonstrate that it is s A more complex example can be found below: -``` motoko no-repl +```motoko no-repl type Exp = {#Lit : Nat; #Div : (Exp, Exp); #If : (Exp, Exp, Exp)}; func eval(e : Exp) : ? Nat { switch e { @@ -146,7 +146,7 @@ eval(expr); Using option blocks this code can be rewritten to reduce the need for nested switches, if that's preferred: -``` motoko no-repl +```motoko no-repl type Exp = {#Lit : Nat; #Div : (Exp, Exp); #If : (Exp, Exp, Exp)}; func eval(e : Exp) : ? Nat { do ? { diff --git a/docs/languages/motoko/fundamentals/declarations/class-declarations.md b/docs/languages/motoko/fundamentals/declarations/class-declarations.md index 72f04a4e..0438118b 100644 --- a/docs/languages/motoko/fundamentals/declarations/class-declarations.md +++ b/docs/languages/motoko/fundamentals/declarations/class-declarations.md @@ -1,10 +1,11 @@ --- -sidebar_position: 4 -description: "Motoko language documentation" title: "Class declarations" +description: "A class in Motoko serves as a blueprint for creating objects that encapsulate both state and behavior." +sidebar: + order: 4 --- -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. +A class in Motoko serves as a blueprint for creating [objects](./object-declaration.md) that encapsulate both [state](../actors/state.md) 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 +166,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](/languages/motoko/reference/language-manual#actor-class-management). +[Learn more about actor class management](../../language-manual.md#actor-class-management). diff --git a/docs/languages/motoko/fundamentals/declarations/expression-declarations.md b/docs/languages/motoko/fundamentals/declarations/expression-declarations.md index 7e82f078..38bcd4db 100644 --- a/docs/languages/motoko/fundamentals/declarations/expression-declarations.md +++ b/docs/languages/motoko/fundamentals/declarations/expression-declarations.md @@ -1,7 +1,8 @@ --- -sidebar_position: 6 -description: "Motoko language documentation" title: "Expression declarations" +description: "An expression declaration is a declaration that consists of a single expression." +sidebar: + order: 6 --- An expression declaration is a declaration that consists of a single expression. The expression is evaluated solely for its value and side effects. Unlike other declarations, it does not declare any new names. @@ -31,7 +32,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/actors/state). +Expression declarations are commonly used for functions or operations that produce side effects, such as printing or modifying [state](../actors/state.md). ```motoko no-repl Debug.print("Hello, Motoko!"); @@ -65,7 +66,7 @@ The expression `x * 2;` returns a value of type `Nat`, but since it is not assig Motoko supports anonymous functions as a type of expression. -``` motoko no-repl +```motoko no-repl func applyFunction(f : Int -> Int, value : Int) : Int { f(value) }; applyFunction( func (x : Int) : Int { x * 2 } , 2); ``` @@ -75,6 +76,6 @@ This is just an anonymous version of the function named `double` above. The compiler can infer the argument and result types of anonymous functions, when the types are determined from the context, so you can even just write: -``` motoko no-repl +```motoko no-repl applyFunction( func x { x * 2 } , 2); ``` diff --git a/docs/languages/motoko/fundamentals/declarations/function-declarations.md b/docs/languages/motoko/fundamentals/declarations/function-declarations.md index 0255de7e..85e45d1f 100644 --- a/docs/languages/motoko/fundamentals/declarations/function-declarations.md +++ b/docs/languages/motoko/fundamentals/declarations/function-declarations.md @@ -1,7 +1,8 @@ --- -sidebar_position: 2 -description: "Motoko language documentation" title: "Function declarations" +description: "A function in Motoko is a reusable block of code that accepts inputs, performs computations or actions, and optionally returns a result." +sidebar: + order: 2 --- A function in Motoko is a reusable block of code that accepts inputs, performs computations or actions, and optionally returns a result. Functions can be either named or anonymous and may explicitly define the types of their parameters and return values for clarity and type safety. @@ -98,7 +99,7 @@ assert echoTwice("Hello") == "Hello!!"; ## Shared functions in actors -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. +In actors, functions can be marked as `shared` to allow [asynchronous](../actors/actors-async.md#async--await) [inter-canister](/references/message-execution-properties) communication. ```motoko no-repl actor Counter { @@ -120,7 +121,7 @@ await Counter.getCount(); One key advantage of shared functions in Motoko is that they have access to the caller's Principal, which uniquely identifies the entity (user or another canister) that made the request. This capability allows actors to implement access control by verifying the caller’s identity before performing sensitive operations. -```motoko +```motoko no-repl actor Example { // msg.caller retrieves the Principal of the caller. public shared(msg) func whoAmI() : async Principal { diff --git a/docs/languages/motoko/fundamentals/declarations/index.md b/docs/languages/motoko/fundamentals/declarations/index.md new file mode 100644 index 00000000..079b0bec --- /dev/null +++ b/docs/languages/motoko/fundamentals/declarations/index.md @@ -0,0 +1,6 @@ +--- +title: "Declarations" +sidebar: + order: 5 + label: "Declarations" +--- diff --git a/docs/languages/motoko/fundamentals/declarations/module-declarations.md b/docs/languages/motoko/fundamentals/declarations/module-declarations.md index 09070099..4f246aaa 100644 --- a/docs/languages/motoko/fundamentals/declarations/module-declarations.md +++ b/docs/languages/motoko/fundamentals/declarations/module-declarations.md @@ -1,12 +1,13 @@ --- -sidebar_position: 7 -description: "Motoko language documentation" title: "Module declarations" +description: "In Motoko, a module is a collection of related types, values, and functions grouped under a single namespace." +sidebar: + order: 7 --- In Motoko, a **module** is a collection of related types, values, and functions grouped under a single namespace. Unlike actors and objects, modules cannot declare mutable state or have side effects during their construction. This restriction makes them ideal for defining code libraries, since you don’t need to worry about the side effects or state implications of importing the same library multiple times or removing an unused one. -Modules are mainly used to build libraries, such as those in the [core package](https://mops.one/core) or packages available through [Mops, the Motoko package manager](https://mops.one). +Modules are mainly used to build libraries, such as those in the [core package](https://mops.one/core/docs/index) or packages available through [Mops, the Motoko package manager](https://mops.one). A module in Motoko can define: @@ -90,7 +91,7 @@ A module can declare classes that use state, provided it doesn't instantiate tho For example, a module can define a class of stateful `Counters` : -``` motoko no-repl +```motoko no-repl module Counters { public class Counter() { var count : Nat = 0; @@ -133,7 +134,7 @@ If you'd prefer to avoid dot notation, you can also import individual values dir This allows you to bind specific names from the module into your local scope, making the code more concise and readable when those values are used frequently. -``` motoko no-repl +```motoko no-repl import {init; identity} "Matrix"; let zero = init(3, 3, 0); diff --git a/docs/languages/motoko/fundamentals/declarations/object-declaration.md b/docs/languages/motoko/fundamentals/declarations/object-declaration.md index ac82e228..71879e0f 100644 --- a/docs/languages/motoko/fundamentals/declarations/object-declaration.md +++ b/docs/languages/motoko/fundamentals/declarations/object-declaration.md @@ -1,20 +1,22 @@ --- -sidebar_position: 3 -description: "Motoko language documentation" title: "Object declarations" +description: "In Motoko, records and objects are both used to group related values using named fields." +sidebar: + order: 3 --- In Motoko, records and objects are both used to group related values using named fields. Record and objects have the same types, but differ in the way they are created and used. The types of record and objects are both described using object types, which are unordered sequences of named fields describing the content and mutability of each public field. Both record and object fields can be accessed by either dot notation or by pattern matching on the names of the fields. 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/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 and object both use the `var` keyword to define [mutable](./variable-declarations.md) 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. Record values can only be declared using `let`: -```motoko name=record no-repl +```motoko no-repl + let Motoko = { name : Text = "Motoko"; var age : Nat = 25; @@ -60,7 +62,8 @@ This defines an object with three public members, the field `name` and the metho Motoko also supports object declarations, which stress the definition of an object by using the `object` keyword in place of `let`: -```motoko name=Object no-repl +```motoko no-repl + object Motoko = { public let name = "Motoko"; var age = 6; diff --git a/docs/languages/motoko/fundamentals/declarations/type-declarations.md b/docs/languages/motoko/fundamentals/declarations/type-declarations.md index 528e11a8..85634a61 100644 --- a/docs/languages/motoko/fundamentals/declarations/type-declarations.md +++ b/docs/languages/motoko/fundamentals/declarations/type-declarations.md @@ -1,7 +1,8 @@ --- -sidebar_position: 5 -description: "Motoko language documentation" title: "Type declarations" +description: "Type declarations are used for defining custom types that improve readability, reusability, and structure of the code." +sidebar: + order: 5 --- Type declarations are used for defining custom types that improve readability, reusability, and structure of the code. They can represent records, variants, objects, or parameterized (generic) types. Motoko enforces productivity and non-expansiveness in type declarations to ensure well-formed, valid types. @@ -34,7 +35,7 @@ type Person = { username : Username; age : Age}; Given a similar type `User`: -``` motoko no-repl +```motoko no-repl type User = { age : Nat; username : Text }; ``` @@ -42,7 +43,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/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. +In Motoko, a type can define a structured [record](../types/records.md) 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 +146,8 @@ type Seq = ?(T, Seq<[T]>); ## Resources -- [`Record`](/languages/motoko/fundamentals/types/records) -- [`Variant`](/languages/motoko/fundamentals/types/variants) +- [`Record`](../types/records.md) +- [`Variant`](../types/variants.md) diff --git a/docs/languages/motoko/fundamentals/declarations/variable-declarations.md b/docs/languages/motoko/fundamentals/declarations/variable-declarations.md index c852e20d..b40186c0 100644 --- a/docs/languages/motoko/fundamentals/declarations/variable-declarations.md +++ b/docs/languages/motoko/fundamentals/declarations/variable-declarations.md @@ -1,7 +1,8 @@ --- -sidebar_position: 1 -description: "Motoko language documentation" title: "Variable declarations" +description: "In Motoko, variables are declared using:" +sidebar: + order: 1 --- In Motoko, variables are declared using: @@ -25,7 +26,7 @@ The left hand side of a `let` can be also be a more general pattern, naming the For example, the declaration: -``` motoko +```motoko no-repl let (fst, snd) = (1, 2); ``` @@ -56,7 +57,7 @@ Motoko provides special assignment operators that combine assignment with a bina For example, numbers permit a combination of assignment and addition: -``` motoko +```motoko no-repl var count = 2; count += 40; ``` @@ -65,7 +66,7 @@ After the second line, the variable `count` holds `42`. Motoko includes other compound assignments as well, such as `#=`: -``` motoko +```motoko no-repl var text = "Motoko"; text #= " Ghost" ``` diff --git a/docs/languages/motoko/fundamentals/error-handling.md b/docs/languages/motoko/fundamentals/error-handling.md index 43bd0625..e6f34ad3 100644 --- a/docs/languages/motoko/fundamentals/error-handling.md +++ b/docs/languages/motoko/fundamentals/error-handling.md @@ -1,7 +1,8 @@ --- -sidebar_position: 9 -description: "Motoko language documentation" title: "Error handling" +description: "Using Option or Result is the preferred way of signaling errors in Motoko." +sidebar: + order: 9 --- Using `Option` or `Result` is the preferred way of signaling errors in Motoko. They work in both synchronous and asynchronous contexts and make your APIs safer to use by encouraging clients to consider the error cases as well as the success cases. Exceptions should only be used to signal unexpected error states. @@ -33,7 +34,7 @@ For this reason, option types should only be used for errors when there's just o While options are a built-in type, the `Result` is defined as a variant type like so: -``` motoko no-repl +```motoko no-repl type Result = { #ok : Ok; #err : Err } ``` @@ -70,7 +71,7 @@ With a `Result` type, you can use pattern matching to handle both success and er Sometimes you need to convert between `Option` and `Result` types. For example, a HashMap lookup returns `null` on failure (an `Option`), but if the caller has more context, they can turn that failure into a meaningful `Result` with an error message. On the other hand, sometimes you don’t need the extra detail from a `Result` and just want to convert any error (`#err`) into `null`. -The [core](https://github.com/dfinity/motoko-core) package provides `fromOption` and `toOption` functions in the `Result` module that make converting between these two types easy. +The [core](https://github.com/caffeinelabs/motoko-core) package provides `fromOption` and `toOption` functions in the `Result` module that make converting between these two types easy. ## Error reporting with `Error` (asynchronous errors) @@ -94,7 +95,7 @@ Function callsite: ## Traps -Traps immediately stop execution and roll back [state](/languages/motoko/fundamentals/actors/state). They are used for fatal errors that cannot be recovered. +Traps immediately stop execution and roll back [state](./actors/state.md). 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 2576ae72..d910eea2 100644 --- a/docs/languages/motoko/fundamentals/hello-world.md +++ b/docs/languages/motoko/fundamentals/hello-world.md @@ -1,15 +1,15 @@ --- -sidebar_position: 1 -description: "Motoko language documentation" title: "Hello, world!" -hide_table_of_contents: true +description: "\"Hello, world!\" is a common starting point used to showcase a programming language's basic syntax." +sidebar: + order: 1 --- "Hello, world!" is a common starting point used to showcase a programming language's basic syntax. Below is an example of "Hello, world!" written in Motoko: -```motoko +```motoko no-repl // If an actor is declared with the persistent keyword, all private declarations are considered stable by default persistent actor HelloWorld { // We store the greeting in a stable variable such that it gets persisted over canister upgrades. @@ -29,12 +29,12 @@ persistent actor HelloWorld { In this example: -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. +1. The code begins by defining an [actor](./actors/actors-async.md) 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/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) +2. It then declares the variable `greeting`. This is a [stable variable](./types/stable-types.md) 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#upgrade-a-canister) -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`. +3. An [update method](/concepts/canisters#update-calls) named `setGreeting` is used to modify the canister’s state. This method specifically updates the value stored in `greeting`. -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. +4. Finally, a [query method](/concepts/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. -[Learn more about actors and basic syntax](/languages/motoko/fundamentals/basic-syntax/defining-an-actor). \ No newline at end of file +[Learn more about actors and basic syntax](./basic-syntax/defining-an-actor.md). \ 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 1339f1a8..c3935854 100644 --- a/docs/languages/motoko/fundamentals/implicit-parameters.md +++ b/docs/languages/motoko/fundamentals/implicit-parameters.md @@ -1,6 +1,8 @@ --- title: "Implicit parameters" -description: "Motoko language documentation" +description: "Using implicit parameters to pass values to functions without explicit arguments in Motoko." +sidebar: + order: 11 --- ## Overview @@ -27,7 +29,7 @@ The `implicit` marker on the type of parameter `compare` indicates the call-site A function can declare more than one implicit parameter, even of the same name. -```motoko +```motoko no-repl func show( self: (T, U), toTextT : (implicit : (toText : T -> Text)), @@ -44,7 +46,7 @@ The inner name (under `implicit`) overrides the local name of the parameter in t When calling a function with implicit parameters, you can omit the implicit arguments if the compiler can infer them: -```motoko +```motoko no-repl import Map "mo:core/Map"; import Nat "mo:core/Nat"; @@ -69,13 +71,13 @@ An ambiguous call can always be disambiguated by supplying the explicit argument ### Contextual dot notation -Implicit parameters dovetail nicely with [contextual dot notation](/languages/motoko/fundamentals/contextual-dot). +Implicit parameters dovetail nicely with [contextual dot notation](contextual-dot.md). The dot notation and implicit arguments can be used in conjunction to shorten code. For example, since the first parameter of `Map.add` is called `self`, we can both use `map` as the receiver of `add` "method" calls and omit the tedious `compare` argument: -```motoko +```motoko no-repl import Map "mo:core/Map"; import Nat "mo:core/Nat"; @@ -95,7 +97,7 @@ The primary use case for implicit arguments is simplifying code that uses maps a ### Map Example -```motoko +```motoko no-repl import Map "mo:core/Map"; import Nat "mo:core/Nat"; @@ -120,7 +122,7 @@ let item2 = inventory.get(102); ### Set example The core `Set` type also takes advantage of implicit `compare` parameters. -```motoko +```motoko no-repl import Set "mo:core/Set"; import Text "mo:core/Text"; @@ -141,7 +143,7 @@ let hasTag2 = tags.contains("urgent"); Implicit arguments make imperative collection operations much cleaner: -```motoko +```motoko no-repl import Map "mo:core/Map"; import Text "mo:core/Text"; @@ -215,7 +217,7 @@ module MyArray { With derivation, the compiler handles this automatically. It recognizes that `Array.compare`, after removing its implicit `compare` parameter and instantiating `T := Nat`, has the right type. It then recursively resolves the inner implicit (`Nat.compare`) and synthesizes the wrapper for you. -This works transitively: a `compare` for `[[Nat]]` is derived via `Array.compare<[Nat]>`, which needs `[Nat]` compare, which is derived via `Array.compare`, which needs `Nat.compare`: all resolved automatically. +This works transitively: a `compare` for `[[Nat]]` is derived via `Array.compare<[Nat]>`, which needs `[Nat]` compare, which is derived via `Array.compare`, which needs `Nat.compare`, all resolved automatically. The resolution depth is bounded to guarantee termination. If you encounter a depth limit, you can increase it with `--implicit-derivation-depth` or provide the argument explicitly. @@ -239,7 +241,7 @@ Other implicit parameters declared by the core library are `equals : (implicit : You can always provide implicit arguments explicitly when needed: -```motoko +```motoko no-repl import Map "mo:core/Map"; import Nat "mo:core/Nat"; import {type Order} "mo:core/Order"; @@ -264,7 +266,7 @@ This is useful when: To use implicit arguments with your own custom types, define a comparison function: -```motoko +```motoko no-repl import Map "mo:core/Map"; import Text "mo:core/Text"; import {type Order} "mo:core/Order"; @@ -306,7 +308,7 @@ let email = directory.get({ name = "Alice"; age = 30 }); Existing code with explicit comparison functions will continue to work. You can adopt implicit arguments gradually: -```motoko +```motoko no-repl import Map "mo:core/Map"; import Nat "mo:core/Nat"; @@ -328,4 +330,4 @@ Implicit arguments are resolved at compile time. ## See also -- [Language reference](/languages/motoko/reference/language-manual#function-calls) +- [Language reference](../language-manual#function-calls) diff --git a/docs/languages/motoko/fundamentals/modules-imports.md b/docs/languages/motoko/fundamentals/modules-imports.md index 33fb18b9..d2adaccb 100644 --- a/docs/languages/motoko/fundamentals/modules-imports.md +++ b/docs/languages/motoko/fundamentals/modules-imports.md @@ -1,7 +1,8 @@ --- -sidebar_position: 7 -description: "Motoko language documentation" title: "Modules and imports" +description: "Motoko minimizes built-in types and operations, relying on a core package of modules to provide essential functionality." +sidebar: + order: 7 --- Motoko minimizes built-in types and operations, relying on a core package of modules to provide essential functionality. This modular approach keeps the language simple. @@ -28,7 +29,7 @@ The `mo:` prefix identifies a Motoko module. The declaration does not include th You can also selectively import and rename a subset of named values and types from a module by using the object pattern syntax: -``` motoko +```motoko no-repl import { type List; get; foldLeft = fold } "mo:core/List"; ``` @@ -48,7 +49,7 @@ In this scenario, you might place all three files in the same directory and use For example, the `main.mo` contains the following lines to reference the modules in the same directory: -``` motoko no-repl +```motoko no-repl import Types "types"; import Utils "utils"; ``` @@ -61,7 +62,7 @@ You can also import modules from other packages or from directories other than t For example, the following lines import modules from a `redraw` package that is defined as a dependency: -``` motoko no-repl +```motoko no-repl import Render "mo:redraw/Render"; import Mono5x5 "mo:redraw/glyph/Mono5x5"; ``` @@ -146,7 +147,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/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](./actors/actors-async.md) 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 +184,7 @@ persistent actor CountToTen { }; ``` -`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. +`Counters.Counter(1)` installs a new counter on the network. Installation is [asynchronous](./actors/actors-async.md#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/pattern-matching.md b/docs/languages/motoko/fundamentals/pattern-matching.md index d8d5bf67..891e004a 100644 --- a/docs/languages/motoko/fundamentals/pattern-matching.md +++ b/docs/languages/motoko/fundamentals/pattern-matching.md @@ -1,7 +1,8 @@ --- -sidebar_position: 8 -description: "Motoko language documentation" title: "Pattern matching" +description: "Pattern matching in Motoko is a language feature that makes it easy to test and break down complex data structures." +sidebar: + order: 8 --- Pattern matching in Motoko is a language feature that makes it easy to test and break down complex data structures. It is commonly used in `switch` expressions to extract and work with parts of a value. @@ -44,7 +45,7 @@ To prevent runtime errors when no `switch` case matches, the Motoko compiler per Consider the following function call: -```motoko +```motoko no-repl let name : Text = fullName({ first = "Motoko"; mid = "X"; last = "Ghost" }); ``` @@ -52,7 +53,7 @@ This creates a record with three fields and passes it to the `fullName` function Now, look at the function itself: -```motoko +```motoko no-repl func fullName({ first : Text; mid : Text; last : Text }) : Text { first # " " # mid # " " # last }; @@ -60,7 +61,7 @@ func fullName({ first : Text; mid : Text; last : Text }) : Text { Here, the input record is*destructured. Its fields are matched and their values are assigned to the variables `first`, `mid`, and `last`, which are then used in the function body. This example uses name punning, where the field name (e.g., `first`) is reused as the variable name. A more flexible pattern lets you give the value a different name, like this: -```motoko +```motoko no-repl mid = m : Text ``` diff --git a/docs/languages/motoko/fundamentals/types/advanced-types.md b/docs/languages/motoko/fundamentals/types/advanced-types.md index 47aa3982..eed45d7a 100644 --- a/docs/languages/motoko/fundamentals/types/advanced-types.md +++ b/docs/languages/motoko/fundamentals/types/advanced-types.md @@ -1,16 +1,17 @@ --- -sidebar_position: 12 -description: "Motoko language documentation" title: "Advanced types" +description: "Advanced type features enable more flexible and expressive type definitions, including structural equality, generic types, subtyping, recursive types, and ty..." +sidebar: + order: 12 --- Advanced type features enable more flexible and expressive type definitions, including structural equality, generic types, subtyping, recursive types, and type bounds. ## 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/types/records) and [variants](/languages/motoko/fundamentals/types/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](./records.md) and [variants](./variants.md), but does not apply to mutable structures for safety reasons. -```motoko +```motoko no-repl type Point = { x : Int; y : Int }; let p1 : Point = { x = 1; y = 2 }; @@ -23,7 +24,7 @@ Even though `p1` and `p2` are distinct objects, they are considered equal becaus This remains true even if different fields are added to the point values, since the `==` on `Point` values only considers the `x` and `y` fields and ignores other fields. -```motoko +```motoko no-repl type Point = { x : Int; y : Int }; let p1 : Point = { x = 1; y = 2; z = 3 }; @@ -34,9 +35,9 @@ 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/types/function-types), [classes](/languages/motoko/fundamentals/types/objects-classes), and data structures. +Generic types are used to define type parameters that work with multiple data types, commonly used in [functions](./function-types.md), [classes](./objects-classes.md), and data structures. -```motoko +```motoko no-repl // Generic function func identity(x : T) : T { return x; @@ -47,7 +48,7 @@ identity(42); // num is Nat A generic class can store any type while maintaining type safety: -```motoko +```motoko no-repl class Box(value : T) { public func open() : T { value }; }; @@ -70,7 +71,7 @@ This defines a recursive type for representing a linked list of natural number. - `?(head, tail)`, where `head` is a `Nat` and `tail` is another `List`. -```motoko +```motoko no-repl ?(1, ?(2, ?(3, null))) // A list: 1 → 2 → 3 ``` @@ -88,7 +89,7 @@ Reversing a linked list involves iterating through the list and prepending each Non-parameterized type: -```motoko name=List +```motoko no-repl // Lists of naturals type List = ?(Nat, List); @@ -111,14 +112,14 @@ func reverseNat(l : List) : List { }; ``` -```motoko _include=List no-repl +```motoko no-repl let numbers : List = ?(1, ?(2, ?(3, null))); reverseNat(numbers); // ?(3, ?(2, ?(1, null))) ``` Parameterized: -```motoko name=GenList +```motoko no-repl // Lists of naturals type List = ?(T, List); @@ -144,13 +145,13 @@ These type and function definitions generalize the previous code to work not jus You can reverse a list of numbers. -``` motoko _include=GenList no-repl +```motoko no-repl let numbers : List = ?(1, ?(2, ?(3, null))); reverse(numbers); // ?(3, ?(2, ?(1, null))) ``` But you can also reverse a list of characters: -```motoko _include=GenList no-repl +```motoko no-repl let chars : List = ?('a', ?('b', ?('c', null))); reverse(numbers); // ?('c', ?('b', ?('a', null))) @@ -171,7 +172,7 @@ This approach balances the flexibility of generic programming with the safety of The following examples illustrate this behavior: -```motoko +```motoko no-repl func printName(x : T): Text { debug_show(x.name); }; @@ -180,13 +181,13 @@ 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/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. +In the example above, `T <: { name : Text }` requires that any type used for `T` must be a subtype of the [record](./records.md) `{ 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`. For example, it is possible to constrain a generic type to be a subtype of a primitive type. -```motoko name=max +```motoko no-repl func max(x : T, y : T) : T { if (x <= y) y else x }; @@ -197,7 +198,7 @@ Here, `T <: Int` constrains `T` to be a subtype of [`Int`](https://mops.one/core But the function can also be used to return the maximum of two `Nat`s and still produce a `Nat` (not an `Int`). -```motoko _include=max no-repl +```motoko no-repl max(5, 10); // returns 10 : Nat ``` @@ -208,7 +209,7 @@ The *actor reference* expression `actor ` compute a reference to an actor f A simple example of using actor references is to access the management canister with textual address `"aaaaa-aa"`. Amongst other things, it has a method `raw_rand` for generating cryptographically random bytes as a `Blob`. -```motoko +```motoko no-repl persistent actor Coin { public func flip() : async Bool { let managementCanister = actor "aaaaa-aa" : actor { raw_rand : () -> async Blob }; @@ -220,7 +221,7 @@ persistent actor Coin { A variation computes the textual canister identifier from a given principal. A call to `flipWith(p)` will succeed is called with `Principal.fromBlob("aaaaa-aa")`, but may fail with another argument, if the canister does not exist or does not have a `raw_rand` function: -```motoko +```motoko no-repl import Principal "mo:core/Principal"; persistent actor Coin { diff --git a/docs/languages/motoko/fundamentals/types/function-types.md b/docs/languages/motoko/fundamentals/types/function-types.md index 2d2fdb0d..3c73ab2e 100644 --- a/docs/languages/motoko/fundamentals/types/function-types.md +++ b/docs/languages/motoko/fundamentals/types/function-types.md @@ -1,7 +1,8 @@ --- -sidebar_position: 3 -description: "Motoko language documentation" title: "Function types" +description: "Functions are reusable chunks of code that perform a specific task." +sidebar: + order: 3 --- Functions are reusable chunks of code that perform a specific task. A function is defined with a name and optional parameters, then returns a defined result. A function can also specify a return type for the value it produces. @@ -29,12 +30,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/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). | +| `async` | Runs the function [asynchronously](../actors/actors-async.md#async--await) and returns its result in a future. | +| `query` | Optimized for reading data but cannot modify [state](../actors/state.md). | ## Function comparison -| Function type | Mutates [state](/languages/motoko/fundamentals/actors/state) | Calls updates | Calls queries | Asynchronous | External calls | +| Function type | Mutates [state](../actors/state.md) | Calls updates | Calls queries | Asynchronous | External calls | |------------------------------|---------------|------------------|------------------|---------------|---------------| | Local (synchronous) | Yes | No | No | No | No | | Local (asynchronous) | Yes | Yes | Yes | Yes | No | @@ -42,11 +43,11 @@ Motoko provides different types of functions based on where in the program they | Shared query | No | No | No | Yes | Yes | | Shared composite query | No | No | Yes | Yes | Yes | -## Local functions +## Local functions {#pure-functions} -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. +Local functions run within the canister's [actor](../actors/actors-async.md). They cannot call other [canisters](/concepts/canisters). Local functions are cheap to call and execute synchronously. -```motoko +```motoko no-repl persistent actor CommonDivisor{ func gcd(a : Nat, b : Nat) : Nat { var x = a; @@ -72,7 +73,7 @@ The type of `gcd` is `(Nat, Nat) -> Nat` indicating that it expects a pair of na Generic functions allow the use of type parameters, making them more flexible for using different data types. -```motoko name=swap +```motoko no-repl func swap(t : T, u : U) : (U, T) { (u, t) }; @@ -163,7 +164,7 @@ persistent actor Account { The deposit function has type `: shared Nat -> async Nat`. Consider this code: -``` motoko +```motoko no-repl let b1 = await Account.deposit(50); let b2 = await Account.deposit(50); (b1,b2) @@ -173,7 +174,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/actors/state) updates, or anything that modifies persistent data. +**Example use case**: Transactions, user [state](../actors/state.md) updates, or anything that modifies persistent data. ### One-way functions @@ -193,7 +194,7 @@ persistent actor Account { Calling `Account.credit(100)` updates the balance by `100`; -``` motoko +```motoko no-repl Account.credit(100); ``` @@ -204,7 +205,7 @@ Again, the shared keyword is optional. Note that `Account.credit(100` just retur ## Query functions -[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. +[Query](/concepts/canisters#query-calls) functions are designed for retrieving data. They cannot permanently update [state](../actors/state.md) and execute faster than [update](/concepts/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](/concepts/canisters#update-calls) function. ```motoko no-repl public query func greet(name : Text) : async Text { @@ -236,7 +237,7 @@ 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/actors/state). +**Example use case:** Fetching data quickly without modifying the canister [state](../actors/state.md). ### Composite queries @@ -305,7 +306,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/types/records) type. +Multiple values can be passed as a single argument by encapsulating them within a [record](./records.md) type. ```motoko no-repl func userName(user: { name : Text; age : Nat }) : Text { diff --git a/docs/languages/motoko/fundamentals/types/immutable-arrays.md b/docs/languages/motoko/fundamentals/types/immutable-arrays.md index 7366bdc4..92a58371 100644 --- a/docs/languages/motoko/fundamentals/types/immutable-arrays.md +++ b/docs/languages/motoko/fundamentals/types/immutable-arrays.md @@ -1,10 +1,11 @@ --- -sidebar_position: 8 -description: "Motoko language documentation" title: "Immutable arrays" +description: "Immutable arrays are fixed-size, read-only data structures that allow efficiently storing elements of the same type." +sidebar: + order: 8 --- -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. +Immutable arrays are fixed-size, read-only data structures that allow efficiently storing elements of the same type. Unlike [mutable arrays](./mutable-arrays.md), they cannot be modified after creation, ensuring data integrity and predictable behavior. ## When to use immutable arrays @@ -20,7 +21,7 @@ If the number of elements may change, collections like `List` is a better choice Immutable arrays are declared using square brackets `[T]`. The type of the array is specified within the square brackets, e.g., `[Nat]` declares an immutable array of natural numbers. -```motoko +```motoko no-repl let arr : [Nat] = [1, 2, 3, 4, 5]; ``` @@ -30,9 +31,9 @@ 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/basic-syntax/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](../basic-syntax/traps.md). Attempting to modify an immutable array will result in an error `expected mutable assignment target(M0073)`. -```motoko +```motoko no-repl import Debug "mo:core/Debug"; let numbers : [Nat] = [10, 20, 30]; @@ -64,7 +65,7 @@ The `array.keys()` function returns an iterator that is used to iterate over the A `for` loop can also be used to iterate over an array by accessing elements via their index. -```motoko +```motoko no-repl import Debug "mo:core/Debug"; let arr : [Nat] = [1, 2, 3, 4, 5]; @@ -89,7 +90,7 @@ mutableCopy[0] := 10; Motoko supports passing collections to a function, ensuring that all arguments are handled as a collection rather than individual parameters. -```motoko +```motoko no-repl import Debug "mo:core/Debug" func printAllStrings(strings : [Text]) { @@ -134,7 +135,7 @@ Unlike some languages, Motoko does not compare arrays by reference; instead, it The [`Array`](https://mops.one/core/docs/Array) module in Motoko's core package contains built-in functions for mapping over elements, filtering values, and summing numerical arrays. -```motoko +```motoko no-repl import Array "mo:core/Array"; func transformArray() : [Nat] { @@ -148,7 +149,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/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). +A chessboard is a fixed `8×8` grid. Using immutable arrays to represent the initial [state](../actors/state.md) 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](../actors/state.md). ```motoko no-repl import Array "mo:core/Array"; diff --git a/docs/languages/motoko/fundamentals/types/index.md b/docs/languages/motoko/fundamentals/types/index.md new file mode 100644 index 00000000..fd3d6a1f --- /dev/null +++ b/docs/languages/motoko/fundamentals/types/index.md @@ -0,0 +1,6 @@ +--- +title: "Types" +sidebar: + order: 4 + label: "Types" +--- diff --git a/docs/languages/motoko/fundamentals/types/mutable-arrays.md b/docs/languages/motoko/fundamentals/types/mutable-arrays.md index c4580146..45dbd793 100644 --- a/docs/languages/motoko/fundamentals/types/mutable-arrays.md +++ b/docs/languages/motoko/fundamentals/types/mutable-arrays.md @@ -1,10 +1,11 @@ --- -sidebar_position: 9 -description: "Motoko language documentation" title: "Mutable arrays" +description: "Mutable arrays allow direct modification of elements, making them suitable for scenarios where data needs to be updated frequently." +sidebar: + order: 9 --- -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. +Mutable arrays allow direct modification of elements, making them suitable for scenarios where data needs to be updated frequently. Unlike [immutable arrays](./immutable-arrays.md), which require creating a new array to reflect changes, mutable arrays support in place modifications, improving performance in some cases. ## Creating a mutable array @@ -12,7 +13,7 @@ Mutable array types are written with square brackets `[var T]`. The `var` keywor A mutable array is created using a mutable array expression: - ``` motoko + ```motoko no-repl [var 1, 2, 3, 4, 5]; ``` @@ -22,13 +23,13 @@ Its type is inferred to be `[var Nat]`. If you want to update the array with negative elements, use a type annotation: - ```motoko + ```motoko no-repl [var 1, 2, 3, 4, 5] : [var Int] ``` A named array can be declared using either `let` or `var`: -```motoko +```motoko no-repl let digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]; ``` @@ -36,7 +37,7 @@ The function `Array.tabulateVar(size, f)` creates a mutable array of `size` elem Example: -```motoko +```motoko no-repl import Nat "mo:core/Nat"; import Array "mo:core/Array"; @@ -53,7 +54,7 @@ Each element is mutable and can be updated later. To initialize a large array where every element starts with the same value, use `Array.init(size, value)`: -```motoko +```motoko no-repl import Array "mo:core/Array"; let optArr = Array.repeat(null, 10); @@ -86,7 +87,7 @@ Mutable arrays are beneficial when: | Conversion | Can be converted to mutable with `Array.thaw`. | Can be converted to immutable with `Array.freeze`. | | Use case | Tabular fixed, data | Iterative algorithms | -:::warning +:::caution Unlike some other programming languages that support resizable arrays, Motoko's arrays (both mutable and immutable) are fixed-size. Motoko arrays cannot shrink or grow in length, and operations like `Array.concat` always construct new arrays. For dynamically-sized, array-like data structures, consider using modules in `core` (e.g. `List`) or other `mops` packages (e.g. [`vector`](https://mops.one/vector)). @@ -97,7 +98,7 @@ For dynamically-sized, array-like data structures, consider using modules in `co Mutable arrays use the `var` keyword inside the square brackets `[var T]`. The type of the array is also specified within the square brackets, e.g., `[var Nat]` declares a mutable array of natural numbers. In place element modification is supported in mutable arrays. -```motoko +```motoko no-repl let mutableArray : [var Nat] = [var 1, 2, 3, 4, 5]; mutableArray[0] := 10; // Updates the first element to 10 @@ -107,9 +108,9 @@ 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/basic-syntax/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](../basic-syntax/traps.md). -```motoko +```motoko no-repl let numbers : [var Nat] = [var 10, 20, 30]; numbers[0] := 100; // updating first element @@ -119,7 +120,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/basic-syntax/traps). +Attempting to access an array's index that does not exist will cause a [trap](../basic-syntax/traps.md). ```motoko no-repl let numbers : [var Nat] = [var 10, 20, 30]; @@ -157,7 +158,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/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. +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](./shared-types.md), freezing them is useful when passing data across [functions](./function-types.md) or [actors](../actors/actors-async.md) to ensure immutability. ```motoko no-repl import Array "mo:core/Array"; @@ -175,7 +176,7 @@ A Tic-tac-toe board is a `3x3` grid that requires updates as players take turns. `VarArray.tabulate` is used to create a mutable board initialized with `"_"` (empty space). -```motoko +```motoko no-repl import VarArray "mo:core/VarArray"; import Debug "mo:core/Debug"; @@ -237,7 +238,7 @@ To see why, suppose the following was allowed: `[var Nat] <: [var Int]` (since ` Then, consider the following code: -```motoko +```motoko no-repl let ns : [var Nat] = [var 0]; let is : [var Int] = ns; // only allowed if [var Nat] <: [var Int] is[0] := -1; // [var Nat] is not a subtype of [var Int] — even though Nat <: Int. diff --git a/docs/languages/motoko/fundamentals/types/objects-classes.md b/docs/languages/motoko/fundamentals/types/objects-classes.md index 6cc9c6f9..d76d35d3 100644 --- a/docs/languages/motoko/fundamentals/types/objects-classes.md +++ b/docs/languages/motoko/fundamentals/types/objects-classes.md @@ -1,7 +1,8 @@ --- -sidebar_position: 6 -description: "Motoko language documentation" title: "Objects & classes" +description: "In Motoko, an object is a collection of named fields that hold values." +sidebar: + order: 6 --- ## Objects @@ -9,14 +10,14 @@ 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/types/records) syntax makes it easy to construct such objects. +Motoko's light-weight [record](./records.md) 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. In addition to the record syntax, Motoko let's you define an object from a block of declarations. The declarations in the block can be `public` or `private`, with `private` the default. Public declarations become accessible fields of the object, while private declarations remain hidden and inaccessible from outside the object. -```motoko +```motoko no-repl object Account { var balance : Nat = 1000; @@ -34,9 +35,9 @@ 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/actors/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](../actors/state.md). -```motoko +```motoko no-repl class Account(initialBalance : Nat) { var balance = initialBalance; @@ -60,7 +61,7 @@ let account2 = Account(1000); An object class defines a blueprint for multiple objects. The above is just short-hand for an `object` class. Motoko also support module and actor classes. -```motoko +```motoko no-repl object class Account(initialBalance : Nat) { var balance = initialBalance; @@ -91,7 +92,7 @@ Objects with fewer fields are more general, while objects with additional fields Below are example objects for each account type, demonstrating subtyping in practice: -```motoko name=accounts +```motoko no-repl type BasicAccount = { getBalance : () -> Nat; }; @@ -189,5 +190,5 @@ withdrawFromAccount(_premiumAccount); // withdrawFromAccount(_basicAccount); // type error: (missing withdraw) ``` -[Learn more about subtyping](/languages/motoko/fundamentals/types/subtyping). +[Learn more about subtyping](./subtyping.md). diff --git a/docs/languages/motoko/fundamentals/types/options.md b/docs/languages/motoko/fundamentals/types/options.md index 844c1ac9..1e16ff86 100644 --- a/docs/languages/motoko/fundamentals/types/options.md +++ b/docs/languages/motoko/fundamentals/types/options.md @@ -1,7 +1,8 @@ --- -sidebar_position: 10 -description: "Motoko language documentation" title: "Options" +description: "Options provide a structured way to represent values that may or may not be present." +sidebar: + order: 10 --- | Type | Syntax | Purpose | Application | @@ -12,7 +13,7 @@ Options provide a structured way to represent values that may or may not be pres An option is defined using `?` followed by the type of the value it can hold. -```motoko name=user +```motoko no-repl var username : ?Text = null; username; ``` @@ -27,7 +28,7 @@ The constant `null` is the sole value of Motoko’s trivial `Null` type. It also When a Motoko value has type `?T`, it is either `null` or contains a value, written as `?value` (note the leading `?`). The fundamental way to access this value is by using a `switch` expression, which explicitly handles both cases: -``` motoko no-repl +```motoko no-repl func displayName(option : ?Text) : Text { switch option { case (?user) { user }; @@ -43,7 +44,7 @@ Sometimes, the verbosity of a `switch` expression can make code harder to read. To determine if an option contains a value, function `Option.isSome` returns `true` if its argument is not `null`. -```motoko +```motoko no-repl import Option "mo:core/Option"; import Debug "mo:core/Debug"; @@ -53,11 +54,11 @@ 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/control-flow/switch) statements. +By leveraging the `Option` module, handling optional values becomes more concise and expressive, reducing the need for explicit [`switch`](../control-flow/switch.md) statements. ### Providing default values -Instead of manually handling `null` cases with [pattern matching](/languages/motoko/fundamentals/pattern-matching), `Option.get` allows for cleaner fallback logic to ensure that missing values are safely replaced with a default. +Instead of manually handling `null` cases with [pattern matching](../pattern-matching.md), `Option.get` allows for cleaner fallback logic to ensure that missing values are safely replaced with a default. ```motoko no-repl import Option "mo:core/Option"; @@ -67,9 +68,9 @@ 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/basic-syntax/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`](../basic-syntax/traps.md), making a function return `null` when it encounters an invalid input. -```motoko +```motoko no-repl func safeDivide(a : Int, b : Int) : ?Int { if (b == 0) null else ?(a / b); }; @@ -96,7 +97,7 @@ The `let` statement matches the option against the pattern `?value`, extracting The same logic can be expressed using a `switch`, though the result is more verbose and introduces an additional level of nesting: -``` motoko no-repl +```motoko no-repl func get(option : ?T, defaultValue : T) : T { switch option { case null defaultValue; @@ -111,7 +112,7 @@ Although convenient for option patterns, `let-else` also works with other types The `Option.map` function applies a transformation only if the value is present. -```motoko +```motoko no-repl import Option "mo:core/Option"; let number : ?Nat = ?10; @@ -124,7 +125,7 @@ In this example, if `number` is `null`, `map` ensures the result remains `null` Sometimes, both the function and value are optional. `Option.apply` calls a function only if both are present. This is useful when chaining optional operations that may return `null`. -```motoko +```motoko no-repl import Option "mo:core/Option"; let maybeIncrement : ?(Nat -> Nat) = ?(func x: Nat = x + 1); @@ -139,7 +140,7 @@ If either `maybeFunction` or `maybeValue` is `null`, the result remains `null`. When working with multiple optional values, using `Option.chain` processes them safely without unnecessary `switch` statements. -```motoko +```motoko no-repl import Option "mo:core/Option"; let firstName : ?Text = ?"Motoko"; @@ -164,7 +165,7 @@ Within a `do ? `, the `!` operator is used to unwrap values of unrelated The `do ? ` construct is similar to the `?` operator in Rust, providing a concise and expressive way to propagate `null` values. -```motoko +```motoko no-repl // Returns the sum of optional values `n` and `m` or `null`, if either is `null` func addOpt(n : ?Nat, m : ?Nat) : ?Nat { do ? { @@ -175,7 +176,7 @@ func addOpt(n : ?Nat, m : ?Nat) : ?Nat { The following example defines a simple function that evaluates expressions built from natural numbers, division, and a zero test, encoded as a variant type: -```motoko +```motoko no-repl type Exp = {#Lit : Nat; #Div : (Exp, Exp); #If : (Exp, Exp, Exp)}; func eval(e : Exp) : ? Nat { do ? { diff --git a/docs/languages/motoko/fundamentals/types/primitive-types.md b/docs/languages/motoko/fundamentals/types/primitive-types.md index fad81793..f84b81cf 100644 --- a/docs/languages/motoko/fundamentals/types/primitive-types.md +++ b/docs/languages/motoko/fundamentals/types/primitive-types.md @@ -1,7 +1,8 @@ --- -sidebar_position: 1 -description: "Motoko language documentation" title: "Primitive types" +description: "Motoko provides several primitive types that form the foundation of all computations." +sidebar: + order: 1 --- Motoko provides several primitive types that form the foundation of all computations. These include numeric types, characters and text, booleans, and floating-point numbers. @@ -12,7 +13,7 @@ More esoteric functions, not supported by dedicated operators, can be found in t For example, the library function `Int.toText: Int -> Text`, declared in core package `Int`, returns the textual representation of its argument. -```motoko name=int +```motoko no-repl import Int "mo:core/Int"; Int.toText(0); // returns "0" ``` @@ -32,7 +33,7 @@ This means that every expression of type [`Nat`](https://mops.one/core/docs/Nat) An [`Int`](https://mops.one/core/docs/Int) cannot be directly assigned to a [`Nat`](https://mops.one/core/docs/Nat) since it may be a negative number and the [`Nat`](https://mops.one/core/docs/Nat) type only contains non-negative numbers. -```motoko +```motoko no-repl let x : Int = -5; let y : Nat = x; // Error ``` @@ -46,7 +47,7 @@ let y : Nat = Int.abs(x); // Allowed, y = 5 Fixed-size numeric types ([`Int8`](https://mops.one/core/docs/Int8), [`Nat32`](https://mops.one/core/docs/Nat32), etc.) support additional operations, including bitwise shifts. -```motoko +```motoko no-repl let x : Nat32 = 0xA; // 10 in hexadecimal let y = x << 2; // 0x28 (40 in decimal) ``` @@ -55,7 +56,7 @@ let y = x << 2; // 0x28 (40 in decimal) `Char` represents a single Unicode scalar value, while [`Text`](https://mops.one/core/docs/Text) represents a sequence of characters. -```motoko +```motoko no-repl import Char "mo:core/Char"; import Text "mo:core/Text"; @@ -76,7 +77,7 @@ The [`Bool`](https://mops.one/core/docs/Bool) type represents boolean values, `t The logical operators `and` and `or` will only evaluate their second operand if necessary. -```motoko +```motoko no-repl let flag : Bool = true or false; // true let opposite = not flag; // false @@ -87,7 +88,7 @@ let isEqual = true == false ; // false [`Float`](https://mops.one/core/docs/Float) is a 64-bit floating-point type that provides mathematical operations. -```motoko +```motoko no-repl import Float "mo:core/Float"; let pi = Float.pi; let radius : Float = 2.5; @@ -107,7 +108,7 @@ single-precision values. Values are written as float literals with a `Float32` type ascription, or produced by arithmetic on `Float32` operands, or by explicit conversion from `Float`: -```motoko +```motoko no-repl let a : Float32 = 3.14; // literal rounded to single precision at compile time let b : Float32 = a * 2.0; // arithmetic stays in Float32 let c : Float32 = floatToFloat32 3.14; // explicit conversion from Float diff --git a/docs/languages/motoko/fundamentals/types/records.md b/docs/languages/motoko/fundamentals/types/records.md index fbd7d65f..d9b81557 100644 --- a/docs/languages/motoko/fundamentals/types/records.md +++ b/docs/languages/motoko/fundamentals/types/records.md @@ -1,18 +1,19 @@ --- -sidebar_position: 5 -description: "Motoko language documentation" title: "Records" +description: "Records allow you to group related values using named fields, with each field potentially having a different type." +sidebar: + order: 5 --- Records allow you to group related values using named fields, with each field potentially having a different type. -Unlike [tuples](/languages/motoko/fundamentals/types/tuples), which use positional access, records provide field-based access, improving readability and maintainability. +Unlike [tuples](./tuples.md), 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**. ## Defining a record -```motoko +```motoko no-repl let person = { name : Text = "Motoko"; age : Nat = 25; @@ -26,7 +27,7 @@ Without an explicit annotation, the compiler might infer a more specific type th Example: -```motoko +```motoko no-repl let account = { name = "Motoko"; var balance = 0 }; // Inferred as { name : Text; var balance : Nat } account.balance := -100; // Rejected, -100 is an Int not a Nat @@ -53,7 +54,7 @@ Unlike tuples, the order of record fields is immaterial and all record types wit Fields in a record can be accessed using the dot (`.`) notation. -```motoko +```motoko no-repl let person = { name : Text = "Motoko"; age : Nat = 25; @@ -71,7 +72,7 @@ Attempting to access a field that isn't available in the type of the record is a By default, record fields are immutable. To create a mutable field, use `var`. -```motoko +```motoko no-repl let person = { var name : Text = "Motoko"; var age : Nat = 25; @@ -82,7 +83,7 @@ This `person` has type `{var age : Nat; var name : Text}`. `var name` and `var age` allow the values to be updated later. -```motoko +```motoko no-repl let person = { var name : Text = "Motoko"; var age : Nat = 25; @@ -100,7 +101,7 @@ Attempting to update an immutable field is a compile-time type error. Records can contain other records, allowing for hierarchical data structures that maintain organization while ensuring type safety and clarity. -```motoko +```motoko no-repl type Address = { city : Text; street : Text; @@ -120,9 +121,9 @@ let individual : Individual = { ## Pattern matching on records -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. +Records can be destructured using [`switch`](../control-flow/switch.md), allowing selective extraction of fields. This approach makes accessing deeply nested fields more explicit and readable. -```motoko +```motoko no-repl type Address = { city : Text; street : Text; @@ -149,7 +150,7 @@ The field pattern `name` is just shorthand for `name = name`: it binds the conte Records are commonly used in arrays and other collections for structured data storage, allowing efficient data organization and retrieval. -```motoko +```motoko no-repl type Product = { name : Text; price : Float; @@ -187,7 +188,7 @@ debug_show(profile); The `with` keyword modifies, overrides, or adds fields when combining records. -```motoko +```motoko no-repl let person = { name : Text = "Motoko"; age : Nat = 25; }; // age = 26; updates the existing age field. // city = "New York" adds a new field to the record. @@ -205,7 +206,7 @@ If `person` contained a mutable (`var`) field, `with` must redefine it, preventi ### Combining `and` and `with` -```motoko +```motoko no-repl let person = {name : Text = "Motoko"; age : Nat = 25}; let contact = {email : Text = "motoko@example.com"}; diff --git a/docs/languages/motoko/fundamentals/types/results.md b/docs/languages/motoko/fundamentals/types/results.md index 3504ced2..b8df6e4b 100644 --- a/docs/languages/motoko/fundamentals/types/results.md +++ b/docs/languages/motoko/fundamentals/types/results.md @@ -1,7 +1,8 @@ --- -sidebar_position: 11 -description: "Motoko language documentation" title: "Results" +description: "While options are a built-in type, the Result is defined as a variant type:" +sidebar: + order: 11 --- | Type | Syntax | Purpose | Application | @@ -10,7 +11,7 @@ title: "Results" While options are a built-in type, the `Result` is defined as a variant type: -``` motoko no-repl +```motoko no-repl type Result = { #ok : Ok; #err : Err } ``` @@ -18,7 +19,7 @@ Because of the second type parameter `Err`, the `Result` type lets you select th Here’s a simple function that validates a username. If it's non-empty, it will return a greeting of type `Text`. If not, it will return an error of type `Text`. -```motoko +```motoko no-repl import Result "mo:core/Result"; func greet(name : Text) : Result.Result { @@ -32,7 +33,7 @@ When a Motoko value has type `Result`, it is either a success, written `#o ### `switch` -```motoko +```motoko no-repl import Result "mo:core/Result"; func greet(name : Text) : Result.Result { @@ -56,7 +57,7 @@ The verbosity of `switch` expressions can make code harder to read, so Motoko al Values can be extracted from `Result` using the `let ... else` pattern. This can be preferable to a `switch` expression when only the success `case` is needed, and the else branch can cleanly handle or exit on failure. It allows concise early returns or alternative flows when the result is `#err`. -```motoko +```motoko no-repl import Result "mo:core/Result"; func greet(name : Text) : Result.Result { diff --git a/docs/languages/motoko/fundamentals/types/shared-types.md b/docs/languages/motoko/fundamentals/types/shared-types.md index 52252024..fdcd54a8 100644 --- a/docs/languages/motoko/fundamentals/types/shared-types.md +++ b/docs/languages/motoko/fundamentals/types/shared-types.md @@ -1,10 +1,11 @@ --- -sidebar_position: 2 -description: "Motoko language documentation" title: "Shared types" +description: "All Motoko types are divided into sets." +sidebar: + order: 2 --- -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). +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](./stable-types.md). 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. @@ -29,7 +30,7 @@ Shareability is essential for several reasons: ### Primitive types -Most [primitive types](/languages/motoko/fundamentals/types/primitive-types) are shared by default. +Most [primitive types](./primitive-types.md) are shared by default. ```motoko no-repl // Numbers, text, and booleans are shared @@ -40,7 +41,7 @@ let flag : Bool = true; ### Immutable collections -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). +Collections that cannot be modified after creation are shared, including [immutable arrays](./immutable-arrays.md) and [tuples](./tuples.md). ```motoko no-repl // Immutable arrays are shared @@ -52,7 +53,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/types/records). +Objects with immutable fields containing shared types are shared, including [records](./records.md). ```motoko no-repl // Records with immutable fields are shared @@ -65,7 +66,7 @@ let user = { ### Variants with shared type tags -[Variant types](/languages/motoko/fundamentals/types/variants) are shared when their tags contain shared types. +[Variant types](./variants.md) are shared when their tags contain shared types. ```motoko no-repl // Variant types with shared tags are shared @@ -80,7 +81,7 @@ let failure : Result = #error("Operation failed"); ### Option types -[Option types](/languages/motoko/fundamentals/types/options) are shared when they contain shared types. +[Option types](./options.md) are shared when they contain shared types. ```motoko no-repl // Option types with shared inner types are shared @@ -90,7 +91,7 @@ let nothing : ?Nat = null; ### Actor references -References to [actors](/languages/motoko/fundamentals/actors/actors-async) are shared, allowing [canisters](/concepts/canisters) to call each other. +References to [actors](../actors/actors-async.md) are shared, allowing [canisters](/concepts/canisters) to call each other. ```motoko no-repl // Actor types are shared @@ -102,7 +103,7 @@ type CounterActor = actor { ### Shared functions -[Function types](/languages/motoko/fundamentals/types/function-types) marked as `shared` are sharable. +[Function types](./function-types.md) marked as `shared` are sharable. ```motoko no-repl // Shared function types are shared diff --git a/docs/languages/motoko/fundamentals/types/stable-types.md b/docs/languages/motoko/fundamentals/types/stable-types.md index 96e71762..ef35c579 100644 --- a/docs/languages/motoko/fundamentals/types/stable-types.md +++ b/docs/languages/motoko/fundamentals/types/stable-types.md @@ -1,10 +1,11 @@ --- -sidebar_position: 13 -description: "Motoko language documentation" title: "Stable types" +description: "Stable types include all shared types and represent the kinds of values that can be stored in the stable declarations of a Motoko actor." +sidebar: + order: 13 --- -**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. +**Stable types** include all [shared types](./shared-types.md) 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. @@ -55,7 +56,7 @@ Non-shared functions and futures (`async T`) and computations (`async* T`) depen ### Primitive types -Most [primitive types](/languages/motoko/fundamentals/types/primitive-types) in Motoko are stable. +Most [primitive types](./primitive-types.md) in Motoko are stable. ```motoko no-repl persistent actor { @@ -83,7 +84,7 @@ persistent actor { ### Records with mutable or immutable fields -[Records](/languages/motoko/fundamentals/types/records) that contain only stable types remain stable, regardless of whether their fields are mutable or immutable. +[Records](./records.md) that contain only stable types remain stable, regardless of whether their fields are mutable or immutable. ```motoko no-repl persistent actor { @@ -104,7 +105,7 @@ persistent actor { ### Variants with stable type tags -[Variants](/languages/motoko/fundamentals/types/variants) are stable when their tags contain only stable types. +[Variants](./variants.md) are stable when their tags contain only stable types. ```motoko no-repl persistent actor { @@ -122,7 +123,7 @@ persistent actor { ### Option types -[Option](/languages/motoko/fundamentals/types/options) types are stable when they contain stable types. +[Option](./options.md) types are stable when they contain stable types. ```motoko no-repl persistent actor { @@ -145,7 +146,7 @@ persistent actor { ### Actor references -References to [actors](/languages/motoko/fundamentals/actors/actors-async) are stable, allowing stable canister-to-canister interactions. +References to [actors](../actors/actors-async.md) are stable, allowing stable canister-to-canister interactions. ```motoko no-repl persistent actor { diff --git a/docs/languages/motoko/fundamentals/types/subtyping.md b/docs/languages/motoko/fundamentals/types/subtyping.md index d7586feb..f4a02947 100644 --- a/docs/languages/motoko/fundamentals/types/subtyping.md +++ b/docs/languages/motoko/fundamentals/types/subtyping.md @@ -1,7 +1,8 @@ --- -sidebar_position: 14 -description: "Motoko language documentation" title: "Subtyping" +description: "Subtyping is a fundamental concept in type systems that allows values of one type to be used wherever values of another type are expected, p" +sidebar: + order: 14 --- Subtyping is a fundamental concept in type systems that allows values of one type to be used wherever values of another type are expected, provided @@ -73,12 +74,12 @@ In this table: [`Nat`](https://mops.one/core/docs/Nat) is a subtype of [`Int`](https://mops.one/core/docs/Int) (`Nat <: Int`), meaning a [`Nat`](https://mops.one/core/docs/Nat) value can be used where an `Int` is expected. This works because every [`Nat`](https://mops.one/core/docs/Nat) is an `Int`, but not every `Int` is a [`Nat`](https://mops.one/core/docs/Nat) (as negative numbers exist in `Int`). -```motoko +```motoko no-repl let n : Nat = 5; let i : Int = n; // Allowed, since `Int <: Nat` ``` -```motoko +```motoko no-repl let i : Int = -5; let n : Nat = i; // Not allowed, since `Int = ok; // Allowed, since `{#ok : Nat} <: {#ok : Int; ## Immutable arrays -[Immutable arrays (`[T]`)](/languages/motoko/fundamentals/types/immutable-arrays) support covariant subtyping, meaning if `T <: U`, then `[T] <: [U]`. +[Immutable arrays (`[T]`)](./immutable-arrays.md) 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 +239,7 @@ let ints : [Int] = nats; // Allowed, since `Nat <: Int` we also have `[Nat] <: ## Mutable arrays -[Mutable arrays](/languages/motoko/fundamentals/types/mutable-arrays) of the form `[var T]` do not support interesting subtyping. +[Mutable arrays](./mutable-arrays.md) 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 +253,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` ). @@ -266,7 +267,7 @@ This ensures safety because the function will never be passed arguments it can As a simple example, consider the `magnitude` function that returns the absolute value, or magnitude, of an integer. -```motoko no-repl name=magnitude +```motoko no-repl import Int "mo:core/Int" func magnitude(i : Int) : Nat { Int.abs(i) }; ``` @@ -274,7 +275,7 @@ func magnitude(i : Int) : Nat { Int.abs(i) }; Its most precise type is `Int -> Nat`, but, due to subtyping, it also has types `Nat -> Nat` (making the argument more specific), `Int -> Int` (making the result more general) and `Int -> Int` (doing both). -``` motoko no-repl _include=magnitude +```motoko no-repl let i2n : Int -> Nat = magnitude; let n2n : Nat -> Nat = magnitude; let i2i : Int-> Int = magnitude; @@ -298,11 +299,11 @@ 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/types/advanced-types) can be subtypes of each other when their definitions allow it. +[Recursive and generic types](./advanced-types.md) 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: -```motoko no-repl name=Point +```motoko no-repl type Point = { x : Int; move: Int -> Point @@ -317,7 +318,7 @@ type ColorPoint = { `ColorPoint` is a subtype of `Point`: -``` motoko no-repl _include=Point +```motoko no-repl let cp : ColorPoint = { color = #red; x = 0; diff --git a/docs/languages/motoko/fundamentals/types/tuples.md b/docs/languages/motoko/fundamentals/types/tuples.md index b9ecddc2..7a417995 100644 --- a/docs/languages/motoko/fundamentals/types/tuples.md +++ b/docs/languages/motoko/fundamentals/types/tuples.md @@ -1,7 +1,8 @@ --- -sidebar_position: 4 -description: "Motoko language documentation" title: "Tuples" +description: "A tuple is a fixed-size, ordered collection of values, where each element can have a different type." +sidebar: + order: 4 --- A tuple is a fixed-size, ordered collection of values, where each element can have a different type. Tuples provide a way to group values by position, without the overhead of defining a record of named fields. @@ -14,13 +15,13 @@ Unit values are typically used as placeholder arguments or return values for fun ## Defining a tuple -```motoko +```motoko no-repl let ghost = ("Motoko", 25); ``` The tuple's type is automatically inferred as `(Text, Nat)`, since `"Motoko"` is of type [`Text`](https://mops.one/core/docs/Text) and `25` is of type [`Nat`](https://mops.one/core/docs/Nat). -```motoko +```motoko no-repl let ghost : (Text, Nat) = ("Motoko", 25); ``` @@ -32,7 +33,7 @@ Motoko **does not** support length-one tuples. This is in contrast to languages Elements are accessed using `.n` where `n` is the index (0-based indexing). -```motoko +```motoko no-repl // Ghost is a tuple of length 2 let ghost : (firstName : Text, age : Nat) = ("Motoko", 25); let first = ghost.0; // "Motoko" @@ -43,7 +44,7 @@ let second = ghost.1; // 25 Tuples are useful for returning multiple values from a function without requiring a separate data structure. -```motoko +```motoko no-repl func getUserInfo() : (Text, Nat) { ("Ghost", 30); }; @@ -55,17 +56,17 @@ getUserInfo(); Tuples can be stored in arrays or other data structures. Tuples can be constructed with named types, improving readability. By naming the types in the tuple in the collection, the intent of each component is clarified, reducing ambiguity. -```motoko +```motoko no-repl 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/types/records) type. +This structure efficiently represents a collection of key-value pairs without requiring a dedicated [record](./records.md) type. ## Pattern matching on tuples In addition to dot notation, tuples can be decomposed using tuple patterns. When combined with `let` or `switch`, this allows you to access the components of a tuple through simple pattern matching. -```motoko +```motoko no-repl let users : [(Text, Nat)] = [("Motoko", 25), ("Ghost", 30)]; let (firstUserName, _) = users[0] // "Motoko" @@ -85,7 +86,7 @@ $$ Using nested tuples, this can be implemented in Motoko as follows: -```motoko +```motoko no-repl // Point is a tuple of coordinate floats type Point = (Float, Float); // Line is a tuple of points, that is, a nested tuple diff --git a/docs/languages/motoko/fundamentals/types/type-conversions.md b/docs/languages/motoko/fundamentals/types/type-conversions.md index 5626f5f6..de5b9220 100644 --- a/docs/languages/motoko/fundamentals/types/type-conversions.md +++ b/docs/languages/motoko/fundamentals/types/type-conversions.md @@ -1,7 +1,8 @@ --- -sidebar_position: 15 -description: "Motoko language documentation" title: "Type conversions" +description: "Conversions are used to transform values between different types to ensure compatibility and ease of manipulation." +sidebar: + order: 15 --- Conversions are used to transform values between different types to ensure compatibility and ease of manipulation. Common conversions include numeric transformation, such as converting [`Float`](https://mops.one/core/docs/Float) or [`Int`](https://mops.one/core/docs/Int) to [`Nat`](https://mops.one/core/docs/Nat), and text manipulation, like converting [`Text`](https://mops.one/core/docs/Text) to [`Float`](https://mops.one/core/docs/Float) or encoding [`Text`](https://mops.one/core/docs/Text) as a [`Blob`](https://mops.one/core/docs/Blob). Arrays and tuples can be converted into structured types, such as records or hashmaps, for better organization. Additionally, time conversions enable transforming `Time.now()` (nanoseconds since 1970) into human-readable date formats, with optional timezone adjustments. These conversions provide flexibility when working with different data types. @@ -14,7 +15,7 @@ Motoko provides methods for converting both [`Float`](https://mops.one/core/docs A [`Float`](https://mops.one/core/docs/Float) can be converted to [`Nat`](https://mops.one/core/docs/Nat) using `Float.toInt`, followed by `Int.abs` to ensure a non-negative value. -```motoko +```motoko no-repl import Float "mo:core/Float"; import Int "mo:core/Int"; @@ -30,7 +31,7 @@ let result2 = floatToNat(-15.6); // 15 (absolute value is taken) [`Int`](https://mops.one/core/docs/Int) can be directly converted to [`Nat`](https://mops.one/core/docs/Nat) using `Int.abs`, which removes any negative sign. -```motoko +```motoko no-repl import Int "mo:core/Int"; func intToNat(i : Int) : Nat { @@ -162,7 +163,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/types/records) or a structured representation. +Motoko lacks support for dynamic objects, so an array of tuples is converted into a [record](./records.md) or a structured representation. ```motoko no-repl import HashMap "mo:core/HashMap"; @@ -181,7 +182,7 @@ persistent actor MapConverter { arrayToMap([("Motoko", 4), ("Ghost", 21)]); ``` -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). +To convert an array of tuples `[(Text, Nat)]` into a custom [record](./records.md) type, such as `User`, `Array.map` is used to transform each tuple into a structured [record](./records.md). ```motoko no-repl import Array "mo:core/Array"; diff --git a/docs/languages/motoko/fundamentals/types/variants.md b/docs/languages/motoko/fundamentals/types/variants.md index 175378a1..75eda882 100644 --- a/docs/languages/motoko/fundamentals/types/variants.md +++ b/docs/languages/motoko/fundamentals/types/variants.md @@ -1,14 +1,15 @@ --- -sidebar_position: 7 -description: "Motoko language documentation" title: "Variants" +description: "Variant type describe values that take on one of several forms, each labeled with a distinct tag." +sidebar: + order: 7 --- -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. +Variant type describe values that take on one of several forms, each labeled with a distinct tag. Unlike [records](./records.md), 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 -```motoko no-repl name=status +```motoko no-repl type Status = { #Active; #Inactive; @@ -22,14 +23,14 @@ type Status = { To assign a variant value, use one of the defined tags. -```motoko +```motoko no-repl let activeUser = #Active; let bannedUser = #Banned("Violation of rules"); ``` ## Accessing a variant's value -To work with a variant, use a [`switch`](/languages/motoko/fundamentals/control-flow/switch) expression to match each possible case. +To work with a variant, use a [`switch`](../control-flow/switch.md) expression to match each possible case. ```motoko no-repl import Debug "mo:core/Debug"; @@ -59,11 +60,11 @@ 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/actors/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](../actors/state.md), as every possible value is explicitly defined. The transitions are controlled and predictable. ### Defining the traffic light state -```motoko no-repl name=lights +```motoko no-repl type TrafficLight = { #red; #yellow; @@ -73,7 +74,7 @@ type TrafficLight = { ### Transitioning between states -A function can define how the traffic light cycles from one [state](/languages/motoko/fundamentals/actors/state) to the next. +A function can define how the traffic light cycles from one [state](../actors/state.md) to the next. ```motoko no-repl func nextState(light : TrafficLight) : TrafficLight { @@ -113,7 +114,7 @@ for (_ in Iter.range(0, 5)) { A binary tree is a data structure where each node has up to two child nodes. A variant can be used to represent this structure since a node can either contain a value with left and right children or be an empty leaf. This tree type is recursive as it refers to itself in its definition. -```motoko no-repl name=tree +```motoko no-repl type Tree = { #node : { value : Nat; @@ -183,7 +184,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/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. +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](./advanced-types.md#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/caller-identification.md b/docs/languages/motoko/icp-features/caller-identification.md index 10391907..5e929988 100644 --- a/docs/languages/motoko/icp-features/caller-identification.md +++ b/docs/languages/motoko/icp-features/caller-identification.md @@ -1,8 +1,8 @@ --- +title: "Caller identification" +description: "On ICP, every user and canister has a unique principal identifier." sidebar: order: 3 -description: "Motoko language documentation" -title: "Caller identification" --- On ICP, every user and canister has a unique **principal** identifier. When a canister receives a message, such as a function call, the principal identifying the caller of the function is included in the message. @@ -13,7 +13,7 @@ Motoko’s `shared` keyword is used to declare a shared function. Shared functio For example, when a shared function is called by a user or another canister, the caller's principal can be captured with `msg.caller`: -``` motoko no-repl +```motoko no-repl shared(msg) func inc() : async () { // ... msg.caller ... } @@ -23,7 +23,7 @@ In this example, the shared function `inc()` specifies a `msg` parameter, a reco To access the caller of an actor class constructor, you use the same syntax on the actor class declaration: -``` motoko +```motoko no-repl shared(msg) persistent actor class Counter(init : Nat) { // ... msg.caller ... } diff --git a/docs/languages/motoko/icp-features/candid-serialization.md b/docs/languages/motoko/icp-features/candid-serialization.md index 64f7f700..287d64df 100644 --- a/docs/languages/motoko/icp-features/candid-serialization.md +++ b/docs/languages/motoko/icp-features/candid-serialization.md @@ -1,8 +1,8 @@ --- +title: "Candid serialization" +description: "Candid is an interface description language and serialization format designed specifically for the Internet Computer Protocol." sidebar: order: 4 -description: "Motoko language documentation" -title: "Candid serialization" --- Candid is an interface description language and serialization format designed specifically for the Internet Computer Protocol. Candid serves as the standard communication protocol between canisters. When one canister calls another, the arguments are serialized to Candid, transmitted, and then deserialized by the receiving canister. This standardization enables developers to create frontends in languages like JavaScript that can easily interact with backend canisters written in Motoko or Rust. Candid uses strong typing to guarantee accurate data interpretation and an efficient binary format for encoding data, making it ideal for network transmission. Importantly, Candid's design allows for backwards-compatible upgrades of canister interfaces. @@ -102,7 +102,7 @@ Dynamic calls are particularly useful when working with canisters or services th In this example, use the imported `call` function to make a dynamic call on the actor: -``` motoko no-repl +```motoko no-repl import Principal "mo:core/Principal"; import { call } "mo:core/InternetComputer"; diff --git a/docs/languages/motoko/icp-features/randomness.md b/docs/languages/motoko/icp-features/randomness.md index aaedd55d..92a8cbbe 100644 --- a/docs/languages/motoko/icp-features/randomness.md +++ b/docs/languages/motoko/icp-features/randomness.md @@ -1,8 +1,8 @@ --- +title: "Randomness" +description: "Randomness is used for generating unique identifiers, ensuring fairness in games, cryptographic protocols, and much more." sidebar: order: 1 -description: "Motoko language documentation" -title: "Randomness" --- [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. diff --git a/docs/languages/motoko/icp-features/stable-memory.md b/docs/languages/motoko/icp-features/stable-memory.md index 2b1363df..5c414f44 100644 --- a/docs/languages/motoko/icp-features/stable-memory.md +++ b/docs/languages/motoko/icp-features/stable-memory.md @@ -1,8 +1,8 @@ --- +title: "Stable memory and regions" +description: "Canisters have two types of storage: Wasm memory and stable memory." sidebar: order: 5 -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](/concepts/orthogonal-persistence#heap-wasm-linear-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. @@ -12,7 +12,7 @@ Stable memory has a maximum size of 500 GiB and is preserved across canister upg 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/actors/orthogonal-persistence/enhanced) does not fit your use case. +The `Regions` library should only be used if [enhanced orthogonal persistence](../fundamentals/actors/orthogonal-persistence/enhanced.md) does not fit your use case. ::: ## What is a `Region`? diff --git a/docs/languages/motoko/icp-features/system-functions.md b/docs/languages/motoko/icp-features/system-functions.md index a1beb372..78e5da31 100644 --- a/docs/languages/motoko/icp-features/system-functions.md +++ b/docs/languages/motoko/icp-features/system-functions.md @@ -1,25 +1,25 @@ --- +title: "System functions" +description: "ICP supports five system functions that canisters can call to interact with the ICP runtime environment:" sidebar: order: 6 -description: "Motoko language documentation" -title: "System functions" --- ICP supports five system functions that canisters can call to interact with the ICP runtime environment: -- [`timer`](/references/ic-interface-spec/canister-interface#global-timer) +- [`timer`](#timer) - [`preupgrade`](#preupgrade) - [`postupgrade`](#postupgrade) - [`lowmemory`](#lowmemory) -- [`inspect`](/references/ic-interface-spec/canister-interface#system-api-inspect-message) -- [`heartbeat`](/references/ic-interface-spec/canister-interface#heartbeat) +- [`inspect`](#inspect) +- [`heartbeat`](#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](/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 ()`. +The [`timer()` system function](/guides/backends/timers#recurring-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. diff --git a/docs/languages/motoko/icp-features/timers.md b/docs/languages/motoko/icp-features/timers.md index 1b7a6d4b..e6a447cd 100644 --- a/docs/languages/motoko/icp-features/timers.md +++ b/docs/languages/motoko/icp-features/timers.md @@ -1,8 +1,8 @@ --- +title: "Timers" +description: "Canisters can set recurring timers that execute a piece of code after a specified period of time or regular interval." sidebar: order: 2 -description: "Motoko language documentation" -title: "Timers" --- Canisters can set recurring timers that execute a piece of code after a specified period of time or regular interval. Timers in Motoko are implemented using the [`Timer.mo`](https://mops.one/core/docs/Timer) module and return a `TimerId`. `TimerId`s are unique for each timer instance. A canister can contain multiple active timers. @@ -26,7 +26,7 @@ If the `timer` system method is declared, the [`Timer.mo`](https://mops.one/core The following example of a global timer expiration callback gets called immediately after the canister starts, i.e. after install, and periodically every twenty seconds thereafter: -``` motoko no-repl +```motoko no-repl system func timer(setGlobalTimer : Nat64 -> ()) : async () { let next = Nat64.fromIntWrap(Time.now()) + 20_000_000_000; setGlobalTimer(next); // absolute time in nanoseconds diff --git a/docs/languages/motoko/icp-features/view-queries.md b/docs/languages/motoko/icp-features/view-queries.md index 6053659b..e51c4efe 100644 --- a/docs/languages/motoko/icp-features/view-queries.md +++ b/docs/languages/motoko/icp-features/view-queries.md @@ -1,6 +1,8 @@ --- -title: "Stable Variable Inspection with `--generate-view-queries`" -description: "Motoko language documentation" +title: "Stable variable inspection" +description: "Using --generate-view-queries to auto-generate query methods that expose stable variable contents in Motoko." +sidebar: + order: 7 --- The `--generate-view-queries` compiler flag instructs `moc` to auto-generate **query methods** that expose the contents of an actor's stable variables for inspection at runtime. This enables tooling, dashboards, and generic front-end UIs to browse canister state without writing boilerplate accessor code. @@ -26,7 +28,7 @@ When generation proceeds, the compiler chooses one of two strategies: If the expression `id.view()` resolves to a function with shared argument types `(T1, ..., TN)` and shared result type `R`, the compiler generates: -```motoko +```motoko no-repl public shared ({ caller }) query func __id(arg1 : T1, ..., argN : TN) : async R { ; id.view()(arg1, ..., argN) @@ -39,7 +41,7 @@ The `.view()` call may rely on implicit arguments (such as `compare`) provided t If no `.view()` method is available but `` is a shared type, the compiler generates a simple accessor: -```motoko +```motoko no-repl public shared ({ caller }) query func __id() : async { ; id @@ -72,7 +74,7 @@ A `.view()` method is a function resolved via contextual dot syntax on a stable ### Signature pattern -```motoko +```motoko no-repl module MyView { public func view<...>(self : , ...) : (arg1 : T1, ..., argN : TN) -> R = ... } @@ -82,7 +84,7 @@ Implicit arguments (like `compare` for ordered collections) are supported and re ### Example: paginated map view -```motoko +```motoko no-repl module MapView { public func view( self : Map.Map, @@ -103,13 +105,13 @@ module MapView { Given a stable variable: -```motoko +```motoko no-repl let customers : Map.Map = Map.empty(); ``` The compiler generates a query with the Motoko signature: -```motoko +```motoko no-repl public shared query func __customers(ko : ?Text, count : ?Nat) : async [(Text, Customer)] ``` @@ -123,7 +125,7 @@ __customers : (ko : opt text, count : opt nat) -> (vec record { text; Customer } View modules for common core data structures (`Map`, `Set`, arrays, `List`, `Stack`, `Queue`, and their pure counterparts) can be collected into a **mixin** and included in any actor: -```motoko +```motoko no-repl import Views "views"; persistent actor { @@ -136,7 +138,7 @@ persistent actor { ## Example: full actor -```motoko +```motoko no-repl //MOC-FLAG --generate-view-queries import Array "mo:core/Array"; diff --git a/docs/languages/motoko/index.md b/docs/languages/motoko/index.md index 704705c3..2b9c3347 100644 --- a/docs/languages/motoko/index.md +++ b/docs/languages/motoko/index.md @@ -1,17 +1,17 @@ --- title: "Motoko" -description: "A language designed for the Internet Computer with built-in actor model and orthogonal persistence" +description: "A programming language designed for the Internet Computer with built-in actor model, orthogonal persistence, and native WebAssembly compilation." sidebar: order: 1 --- -Motoko is a next-generation, high-level programming language designed to empower AI agents building backends for apps and services on the Internet Computer cloud network. While it channels several popular modern languages, it introduces groundbreaking new features such as actor-based concurrency, orthogonal persistence, and seamless WebAssembly integration. +Motoko is a high-level programming language designed for AI agents building backends for apps and services on the Internet Computer. It combines a familiar syntax with platform-native features: actor-based concurrency, orthogonal persistence, and direct WebAssembly compilation. ## Key features -**Actor model.** Every Motoko canister is an actor — an isolated unit of state and behavior that communicates with other actors through asynchronous messages. This maps directly to how canisters work on ICP: each canister has private state and a public interface. +**Actor model.** Every Motoko canister is an actor: an isolated unit of state and behavior that communicates with other actors through asynchronous messages. This maps directly to how canisters work on ICP: each canister has private state and a public interface. -**Orthogonal persistence.** Variables declared in a `persistent actor` survive canister upgrades automatically. There is no database layer, no serialization code, and no pre/post-upgrade hooks needed for most use cases. See [Orthogonal persistence](../../concepts/orthogonal-persistence.md) for how this works at the platform level. +**Orthogonal persistence.** Variables declared in a `persistent actor` survive canister upgrades automatically. There is no database layer, no serialization code, and no pre/post-upgrade hooks needed for most use cases. See [Orthogonal persistence](/concepts/orthogonal-persistence) for how this works at the platform level. **Async/await messaging.** Inter-canister calls use `async`/`await`, making sequential message flows read like synchronous code. The compiler and runtime handle the underlying callback mechanics. @@ -37,37 +37,6 @@ persistent actor Counter { }; ``` -The `persistent actor` declaration means `count` survives canister upgrades. The `query` keyword marks `get` as a fast, read-only call. The `increment` function is an update call that modifies state and goes through consensus. - -## Getting started - -Create a new Motoko project with icp-cli: - -```bash -icp new my-project --subfolder motoko -``` - -This generates a Motoko canister project with an `icp.yaml` build configuration and a source file. The build configuration uses the Motoko recipe: - -```yaml -canisters: - - name: backend - recipe: - type: "@dfinity/motoko@" - configuration: - main: src/main.mo - shrink: true -``` - -Start a local network and deploy: - -```bash -icp network start -d -icp deploy -``` - -For a guided walkthrough, see the [Quickstart](../../getting-started/quickstart.md). - ## Standard library: `core` The **`core`** package ([mops.one/core](https://mops.one/core)) is the standard library for Motoko. It supersedes the older `base` library with a cleaner API, consistent naming conventions, and data structures that work directly with stable memory. @@ -76,10 +45,10 @@ Add it to your project's `mops.toml`: ```toml [dependencies] -core = "2.2.0" # Check the latest version at https://mops.one/core +core = "2.5.0" # Check the latest version at https://mops.one/core [toolchain] -moc = "1.3.0" # Check the latest version at https://github.com/caffeinelabs/motoko/releases +moc = "1.8.0" # Check the latest version at https://github.com/caffeinelabs/motoko/releases ``` Then import modules: @@ -103,9 +72,7 @@ If you have an existing project using `base`, you can migrate incrementally; bot ## Further reading -- [Quickstart](../../getting-started/quickstart.md): create and deploy your first canister +- [Quickstart](/getting-started/quickstart): create and deploy your first canister - [core library API docs](https://mops.one/core/docs): standard library reference -- [Orthogonal persistence](../../concepts/orthogonal-persistence.md): how persistent memory works at the platform level +- [Orthogonal persistence](/concepts/orthogonal-persistence): how persistent memory works at the platform level - [Motoko GitHub](https://github.com/caffeinelabs/motoko): compiler source and issue tracker - - diff --git a/docs/languages/motoko/reference/changelog.md b/docs/languages/motoko/reference/changelog.md index 7a1269d7..5066d8bd 100644 --- a/docs/languages/motoko/reference/changelog.md +++ b/docs/languages/motoko/reference/changelog.md @@ -1,2508 +1,9 @@ --- -sidebar_position: 3 -description: "Motoko language documentation" -title: "Motoko changelog" +title: "Changelog" +description: "Motoko compiler changelog." +sidebar: + order: 6 --- -This section reproduces the changelog of Motoko up until this release. - -More recent `moc` releases may be available on the [release page](https://github.com/dfinity/motoko/releases/). - -:::tip -You can determine the version of your `moc` installation using -```bash -moc --version -``` - -If using `moc` via `dfx`, you can determine the version of moc bundled with `dfx` using: -```bash -$(dfx cache show)/moc --version +```md file=/Changelog.md ``` -::: - -# Motoko compiler changelog - -## 1.8.0 (2026-05-15) - -* motoko (`moc`) - - * feat: Implicit argument derivation: the compiler can derive implicit arguments from functions that themselves have implicit parameters (e.g., `compare` for `[Nat]` from `Array.compare` + `Nat.compare`). Works transitively and is depth-limited via `--implicit-derivation-depth` (#5966). - - * feat: `and`-patterns: `p1 and p2` matches when both legs match, binding from both (#6049). - - * bugfix: M0236 dot-notation auto-fix on unparenthesized single-argument calls (e.g. `List.reverse b`) no longer rewrites them into a bare function reference (`b.reverse`), which silently turned a call into a no-op; the suggestion now produces `b.reverse()` (#6096). - -## 1.7.0 (2026-04-29) - -* motoko (`moc`) - - * feat: Add null-coalescing operator `??` (#5722). - `e1 ?? e2` evaluates to the unwrapped contents of `e1` when `e1` is `?v`, - otherwise to `e2`. The right-hand side is evaluated lazily (short-circuit). - For example, `opt ?? defaultValue` replaces the verbose - `switch opt { case (?v) v; case null defaultValue }`. - The right-hand side may be a block (e.g. `opt ?? { let x = 1; x }`), - a `do`-block, or a `Prim.trap` for fail-fast unwrapping. Because `{ ... }` - on the right is parsed as a block, a bare record literal must be wrapped - in extra braces or parentheses, e.g. `opt ?? ({ x = 0 })` or - `opt ?? {{ x = 0 }}`. - - * perf: Compile enhanced multi-migration chains as per-step functions instead of one deeply-nested inlined expression, avoiding the wasm-function complexity limit hit by long chains (#6065). - - * bugfix: Preserve GC-only roots (blob deduplication table, migration functions list) across graph-copy upgrades, and defer actor type compatibility checks to `ICStableRead` so enhanced multi-migration chains with multiple pending steps are accepted (#5993). - - * bugfix: Clearer error when installing a Motoko canister over a non-Motoko or otherwise incompatible canister (#6044). - -## 1.6.0 (2026-04-21) - -* motoko (`moc`) - - * feat: expose caller attributes feature through primitives (#5970). - - * bugfix: Fix `moc.js` resolution of relative flag paths (e.g. `--enhanced-migration`, `--actor-idl`): resolve against the project root (via new `setProjectRoot` API) instead of the source file's directory, matching native `moc` behavior. The language server should call `setProjectRoot(path)` before processing files (#6015). - -## 1.5.1 (2026-04-13) - -* motoko (`moc`) - - * bugfix: Resolve relative paths in `moc.js` flags (e.g. `--enhanced-migration`, `--actor-idl`) against the source file's directory, fixing "not a directory" errors when these flags are passed with relative paths via the language server (#6002). - -## 1.5.0 (2026-04-10) - -* motoko (`moc`) - - * feat: Add `--generate-view-queries` flag to auto-generate query methods for stable variables (#5796). - When enabled, `moc` produces one `__` query method per stable variable ``, using the variable's `.view()` method if available, or returning the value directly for shared types. - Generated queries are restricted to controllers and self. - View queries appear in the local `.did` file (for tooling) but are excluded from the canister's public Candid interface, so they never affect upgrade compatibility. - See [Stable variable inspection](doc/md/icp-features/7-view-queries.md) for details. - - * feat: Enhanced multi-migration support via `--enhanced-migration ` (#5840). - Actor upgrades are managed through a chain of migration modules, each in its own file under a migrations directory (``). - Each migration module must export a function called `migrate`, consuming old and introducing new stable variables, in a similar fashion to the already supported single migration functions. - The (lexicographic) sort order of module filenames determines the order of application of migration functions, with lowest applied first. - The compiler verifies that the chain of migration functions composes correctly. - The runtime only applies previously unapplied migrations on upgrade. - Stable variables within an actor's body must be declared with types but without initializers; - their values are determined entirely by the output of the migration chain. - The main body of actor must not have any immediate side effects, beyond invoking - local `` functions (e.g. to register timers). - General side-effects are allowed in migration functions, to enable data initialization - and transformation. - See [Enhanced multi-migration](doc/md/fundamentals/2-actors/8-enhanced-multi-migration.md) for details. - - * perf: type-based optimization of option creation and consumption, reducing cycle cost (#5947). - - * bugfix: Fix type inference for `return` expressions inside unannotated lambdas passed to generic functions. Previously, the generic type parameter could resolve to `Non` instead of the actual return type, causing an IR type error (#5962). - - * bugfix: Fix crash when reporting errors with no source region (#5976). - -* documentation (`mo-doc`) - - * feat: doc comments on individual record fields and variant tags inside a `type` declaration are now extracted and rendered (#5983). - -## 1.4.1 (2026-03-30) - -* motoko (`moc`) - - * feat: Preserve named types in variable pattern bindings, so error messages show e.g. `Map.Map` instead of expanding the full structural type (#5940). - * bugfix: implement `Float32` `ModOp` (`%`): Wasm has no `f32.rem` instruction; the fix promotes operands to `f64`, applies `fmod`, then demotes the result back to `f32` (#5950). - -## 1.4.0 (2026-03-27) - -* motoko (`moc`) - - * feat: added `--actor-env-alias` to facilitate (installation-time) late binding of canister aliases via environment variables (#5890). - * feat: added `--actor-id-alias` as a variant of `--actor-alias` that accepts an explicit IDL file path as a third argument, bypassing the `--actor-idl` search path (#5890). - * feat: provide a polymorphic `actorOfPrincipal` primitive (#5882). - * feat: add `Float32` primitive type with conversions to/from `Float`, Candid serialisation, and literal ascription (e.g. `(3.14 : Float32)`). This is experimental and subject to change (#5906). - * feat: prettier unknown identifier suggestions and pattern type mismatch errors (#5875, #5881). - * bugfix: Show the "Hint: Add explicit type instantiation" hint for calls with implicit arguments whose type parameters are invariant and underconstrained. Previously, implicit arguments caused unnecessary deferral of type variable solving, which suppressed the hint (#5886). - -## 1.3.0 (2026-02-24) - -* motoko (`moc`) - - * Allow destructuring `type` imports from `actor`-valued URIs (#5824). - * perf: Optimise a few arithmetic/logic operations involving neutral elements (#5706). - * Warn when a `var` binding is never reassigned, suggesting `let` instead (#5833). - * Adds `--error-format human` option to print pretty errors with code snippets and labels (#5816), with improved formatting for unused (#5864) and duplicate name (#5865) errors. - * Emit machine-applicable code fixes in `--error-format json` diagnostics for warnings M0223 (redundant type instantiation), M0236 (use dot notation), and M0237 (omit explicit implicit argument). The JSON span format now includes `is_primary`, `label`, `suggested_replacement`, and `suggestion_applicability` fields, enabling IDEs and tooling to offer automatic fixes (#5831). - * Add `--all-libs` flag to load all library files from all packages, enabling better diagnostics, e.g. hinting at non-imported items (increases compilation time) (#5861). - -## 1.2.0 (2026-02-12) - -* motoko (`moc`) - - * Report multiple type errors for compound types at once (#5790). - - This means code like ``` type T = (Na, In)``` will fail with errors for both the misspelled `Na` and `In` types at once, so they can be fixed in one go, rather than having to re-run the compiler after fixing the first one. - - * Allow `break` and `continue` in loops without labels (#5702). - * Report a better error for labeled `continue` targeting a non-loop (#5800). - * Deprecate older garbage collectors: generational, copying and compating GCs (#5806). - * Fix contextual dot type note, this should fix the hover hint in the vscode extension, showing the correct function type instead of `()` (#5809). - * bugfix: Avoid `moc.js` crashing when passing invalid flags (#5811). - * bugfix: Sometimes `import { type X } = "mo:./X"` didn't work, with a confusing error message (#5826). - * Improved type recovery for `let` and `var` declarations (enabled only with a type recovery flag for the IDE) (#5819). - * Add `checkWithScopeCache` function to `moc.js` -- a cached version of `check` (#5820). - * Add `--error-format json` flag to `moc` for machine-readable diagnostic output on stdout in JSON Lines format (#5829). - * Expose contextual dot resolution in `moc.js` via two new functions: `contextualDotSuggestions` returns matching context-dot functions for a receiver type, and `contextualDotModule` returns the module reference for a resolved context-dot expression. AST expression nodes now carry non-enumerable `rawExp` references, and the root AST node exposes the accumulated `scope` (including all transitive imports) to support these APIs (#5797). - -## 1.1.0 (2026-01-16) - -* motoko (`moc`) - - * Warn on unreachable let-else (#5789). - - * bugfix: The source region for `do { ... }` blocks now includes the `do` keyword too (#5785). - - * Omit `blob:*` imports from `moc --print-deps` (#5781). - - * Split unused identifier warnings into separate warnings for shared and non-shared contexts: `M0194` for general declarations, `M0240` for identifiers in shared pattern contexts (e.g. `c` in `shared({caller = c})`), `M0198` for unused fields in object patterns, and `M0241` for unused fields in shared patterns (e.g. `caller` in `shared({caller})`) (#5779). - - * Print type constructors using available type paths (#5698). - - * Warn on implicit oneway declarations (#5787). - - * Make the type checker more lenient and continue accumulating typing errors, and try to produce the typed AST even with errors. Enabled only with a type recovery flag for the IDE (Serokell Grant 2 Milestone 3) (#5776). - - * Explain subtype failures (#5643). - - * Removes the Viper support (#5751). - - * Allows resolving local definitions for context-dot (#5731). - - Extends contextual-dot resolution to consider local definitions first, to make the following snippet type check. Local definitions take precedence over definitions that are in scope via modules. - - ```motoko - func first(self : [A]) : A { - return self[0] - }; - assert [1, 2, 3].first() == 1 - ``` - - * Add privileged primitive for setting Candid type table cutoff (#5642). - -## 1.0.0 (2025-12-11) - -* motoko (`moc`) - - * Shorter, simpler error messages for generic functions (#5650). - The compiler now tries to point to the first problematic expression in the function call, rather than the entire function call with type inference details. - Simple errors only mention closed types; verbose errors with unsolved type variables are only shown when necessary. - - * Improved error messages for context dot: only the receiver type variables are solved, remaining type variables stay unsolved, not solved to `Any` or `Non` (#5634). - - * Fixed the type instantiation hint to have the correct arity (#5634). - - * Fix for #5618 (compiling dotted `await`s) (#5622). - - * Improved type inference of the record update syntax (#5625). - - * New flag `--error-recovery` to enable reporting of multiple syntax errors (#5632). - - * Improved solving and error messages for invariant type parameters (#5464). - Error messages now include suggested type instantiations when there is no principal solution. - - Invariant type parameters with bounds like `Int <: U <: Any` (when the upper bound is `Any`) can now be solved by choosing the lower bound (`Int` here) when it has no proper supertypes other than `Any`. - This means that when choosing between **exactly two** solutions: the lower bound and `Any` as the upper bound, the lower bound is chosen as the solution for the invariant type parameter (`U` here). - Symmetrically, with bounds like `Non <: U <: Nat` (when the lower bound is `Non`), the upper bound (`Nat` here) is chosen when it has no proper subtypes other than `Non`. - - For example, the following code now compiles without explicit type arguments: - - ```motoko - import VarArray "mo:core/VarArray"; - let varAr = [var 1, 2, 3]; - let result = VarArray.map(varAr, func x = x : Int); - ``` - - This compiles because the body of `func x = x : Int` has type `Int`, which implies that `Int <: U <: Any`. - Since `Int` has no proper supertypes other than `Any`, it can be chosen as the solution for the invariant type parameter `U`, resulting in the output type `[var Int]`. - - However, note that if the function body was of type `Nat`, it would not compile, because `Nat` is a proper subtype of `Int` (`Nat <: Int`). - In this case, there would be no principal solution with `Nat <: U <: Any`, and the error message would suggest: - - ``` - Hint: Add explicit type instantiation, e.g. - ``` - - The suggested type instantiation can be used to fix the code: - - ```motoko - let result = VarArray.map(varAr, func x = x); - ``` - - Note that the error message suggests only one possible solution, but there may be alternatives. In the example above, `` would also be a valid instantiation. - - * Fixes type inference of deferred funcs that use `return` in their body (#5615). - Avoids confusing errors like `Bool does not have expected type T` on `return` expressions. Should type check successfully now. - - * Add warning `M0239` that warns when binding a unit `()` value by `let` or `var` (#5599). - - * Use `self` parameter, not `Self` type, to enable contextual dot notation (#5574). - - * Add (caffeine) warning `M0237` (#5588). - Warns if explicit argument could have been inferred and omitted, - e.g. `a.sort(Nat.compare)` vs `a.sort()`. - (allowed by default, warn with `-W 0237`). - - * Add (caffeine) warning `M0236` (#5584). - Warns if contextual dot notation could have been used, - e.g. `Map.filter(map, ...)` vs `map.filter(...)`. - Does not warn for binary `M.equals(e1, e2)` or `M.compareXXX(e1, e2)`. - (allowed by default, warn with `-W 0236`). - - * Add (caffeine) deprecation code `M0235` (#5583). - Deprecates any public types and values with special doc comment - `/// @deprecated M0235`. - (allowed by default, warn with `-W 0235`). - - * Experimental support for `implicit` argument declarations (#5517). - - * Experimental support for Mixins (#5459). - - * bugfix: importing of `blob:file:` URLs in subdirectories should work now (#5507, #5569). - - * bugfix: escape `composite_query` fields on the Candid side, as it is a keyword (#5617). - - * bugfix: implement Candid spec improvements (#5504, #5543, #5505). - May now cause rejection of certain type-incorrect Candid messages that were accepted before. - -## 0.16.3 (2025-09-29) - -* motoko (`moc`) - - * Added `Prim.getSelfPrincipal() : Principal` to get the principal of the current actor (#5518). - - * Contextual dot notation (#5458): - - Writing `e0.f()(e1,...,en)` is short-hand for `M.f()(e0, e1, ..., en)`, provided: - - * `f` is not already a field or special member of `e0`. - * There is a unique module `M` with member `f` in the context that declares: - * a public type `Self` that can be instantiated to the type of `e0`; - * a public field `f` that accepts `(e0, e2, ..., en)` as arguments. - - * Added an optional warning for **redundant type instantiations** in generic function calls (#5468). - Note that this warning is off by default. - It can be enabled with the `-W M0223` flag. - - * Added `-A` and `-W` flags to disable and enable warnings given their message codes (#5496). - - For example, to disable the warning for redundant `stable` keyword, use `-A M0217`. - To enable the warning for redundant type instantiations, use `-W M0223`. - Multiple warnings can be disabled or enabled by comma-separating the message codes, e.g. `-A M0217,M0218`. - Both flags can be used multiple times. - - * Added `-E` flag to treat specified warnings as errors given their message codes (#5502). - - * Added `--warn-help` flag to show available warning codes, current lint level (**A**llowed, **W**arn or **E**rror), and descriptions (#5502). - - * `moc.js` : Added `setExtraFlags` method for passing some of the `moc` flags (#5506). - -## 0.16.2 (2025-09-12) - -* motoko (`moc`) - - * Added primitives to access canister environment variables (#5443): - - ```motoko - Prim.envVarNames : () -> [Text] - Prim.envVar : (name : Text) -> ?Text - ``` - - These require `system` capability to prevent supply-chain attacks. - - * Added ability to import `Blob`s from the local file system by means of the `blob:file:` URI scheme (#4935). - -## 0.16.1 (2025-08-25) - -* motoko (`moc`) - - * bugfix: fix compile-time exception showing `???` type when using 'improved type inference' (#5423). - - * Allow inference of invariant type parameters, but only when the bound/solution is an 'isolated' type (meaning it has no proper subtypes nor supertypes other than `Any`/`None`) (#5359). - This addresses the limitation mentioned in #5180. - Examples of isolated types include all primitive types except `Nat` and `Int`, such as `Bool`, `Text`, `Blob`, `Float`, `Char`, `Int32`, etc. - `Nat` and `Int` are not isolated because `Nat` is a subtype of `Int` (`Nat <: Int`). - - For example, the following code now works without explicit type arguments: - - ```motoko - import VarArray "mo:core/VarArray"; - let varAr = [var 1, 2, 3]; - let result = VarArray.map(varAr, func x = debug_show (x) # "!"); // [var Text] - ``` - - * `ignore` now warns when its argument has type `async*`, as it will have no effect (#5419). - - * bugfix: fix rare compiler crash when using a label and identifier of the same name in the same scope (#5283, #5412). - - * bugfix: `moc` now warns about parentheticals on `async*` calls, and makes sure that they get discarded (#5415). - -## 0.16.0 (2025-08-19) - -* motoko (`moc`) - - * Breaking change: add new type constructor `weak T` for constructing weak references. - - ```motoko - Prim.allocWeakRef: (value : T) -> weak T - Prim.weakGet: weak T -> ?(value : T) - Prim.isLive: weak Any -> Bool - ``` - - A weak reference can only be allocated from a value whose type representation is always a heap reference; `allowWeakRef` will trap on values of other types. - A weak reference does not count as a reference to its value and allows the collector to collect the value once no other references to it remain. - `weakGet` will return `null`, and `isLive` will return false once the value of the reference has been collected by the garbage collector. - The type constructor `weak T` is covariant. - - Weak reference operations are only supported with --enhanced-orthogonal-persistence and cannot be used with the classic compiler. - - * bugfix: the EOP dynamic stable compatibility check incorrectly rejected upgrades from `Null` to `?T` (#5404). - - * More explanatory upgrade error messages with detailing of cause (#5391). - - * Improved type inference for calling generic functions (#5180). - This means that type arguments can be omitted when calling generic functions in _most common cases_. - For example: - - ```motoko - let ar = [1, 2, 3]; - Array.map(ar, func x = x * 2); // Needs no explicit type arguments anymore! - ``` - - Previously, type arguments were usually required when there was an anonymous not annotated function in arguments. - The reason being that the type inference algorithm cannot infer the type of `func`s in general, - e.g. `func x = x * 2` cannot be inferred without knowing the type of `x`. - - Now, the improved type inference can handle such `func`s when there is enough type information from other arguments. - It works by splitting the type inference into two phases: - 1. In the first phase, it infers part of the instantiation from the non-`func` arguments. - The goal is to infer all parameters of the `func` arguments, e.g. `x` in the example above. - The `ar` argument in the example above is used to infer the partial instantiation `Array.map`, leaving the second type argument `O` to be inferred in the second phase. - With this partial instantiation, it knows that `x : Nat`. - 2. In the second phase, it completes the instantiation by inferring the bodies of the `func` arguments; assuming that all parameters were inferred in the first phase. - In the example above, it knows that `x : Nat`, so inferring the body `x * 2` will infer the type `O` to be `Nat`. - With this, the full instantiation `Array.map` is inferred, and the type arguments can be omitted. - - Limitations: - - Invariant type parameters must be explicitly provided in most cases. - e.g. `VarArray.map` must have the return type annotation: - ```motoko - let result = VarArray.map(varAr, func x = x * 2); - ``` - Or the type of the result must be explicitly provided: - ```motoko - let result : [var Nat] = VarArray.map(varAr, func x = x * 2); - ``` - - - When there is not enough type information from the non-`func` arguments, the type inference will not be able to infer the `func` arguments. - However this is not a problem in most cases. - -## 0.15.1 (2025-07-30) - -* motoko (`moc`) - - * bugfix: `persistent` imported actor classes incorrectly rejected as non-`persistent` (#5667). - - * Allow matching type fields of modules and objects in patterns (#5056) - This allows importing a type from a module without requiring an indirection or extra binding. - - ``` - // What previously required indirection, ... - import Result "mo:core/Result"; - type MyResult = Result.Result; - - // or rebinding, ... - import Result "mo:core/Result"; - type Result = Result.Result; - type MyResult = Result; - - // can now be written more concisely as: - import { type Result } "mo:core/Result"; - type MyResult = Result; - ``` - -## 0.15.0 (2025-07-25) - -* motoko (`moc`) - - * Breaking change: the `persistent` keyword is now required on actors and actor classes (#5320, #5298). - This is a transitional restriction to force users to declare transient declarations as `transient` and actor/actor classes as `persistent`. - New error messages and warnings will iteratively guide you to insert `transient` and `persistent` as required, after which any `stable` keywords can be removed. Use the force. - - In the near future, the `persistent` keyword will be made optional again, and `let` and `var` declarations within actor and actor classes will be `stable` (by default) unless declared `transient`, inverting the previous default for non-`persistent` actors. - The goal of this song and dance is to *always* default actor declarations to stable unless declared `transient` and make the `persistent` keyword redundant. - - * Breaking change: enhanced orthogonal persistence is now the default compilation mode for `moc` (#5305). - Flag `--enhanced-orthogonal-persistence` is on by default. - Users not willing or able to migrate their code can opt in to the behavior of moc prior to this release with the new flag `--legacy-persistence`. - Flag `--legacy-persistence` is required to select the legacy `--copying-gc` (the previous default), `--compacting-gc`, or `generational-gc`. - - As a safeguard, to protect users from unwittingly, and irreversibly, upgrading from legacy to enhanced orthogonal persistence, such upgrades will fail unless the new code is compiled with flag `--enhanced-orthogonal-persistence` explicitly set. - New projects should not require the flag at all (#5308) and will simply adopt enhanced mode. - - To recap, enhanced orthogonal persistence implements scalable and efficient orthogonal persistence (stable variables) for Motoko: - * The Wasm main memory (heap) is retained on upgrade with new program versions directly picking up this state. - * The Wasm main memory has been extended to 64-bit to scale as large as stable memory in the future. - * The runtime system checks that data changes of new program versions are compatible with the old state. - - Implications: - * Upgrades become extremely fast, only depending on the number of types, not on the number of heap objects. - * Upgrades will no longer hit the IC instruction limit, even for maximum heap usage. - * The change to 64-bit increases the memory demand on the heap, in worst case by a factor of two. - * For step-wise release handling, the IC initially only offers a limited capacity of the 64-bit space (e.g. 4GB or 6GB), that will be gradually increased in future to the capacity of stable memory. - * There is moderate performance regression of around 10% for normal execution due to combined related features (precise tagging, change to incremental GC, and handling of compile-time-known data). - * The garbage collector is fixed to incremental GC and cannot be chosen. - * `Float.format(#hex prec, x)` is no longer supported (expected to be very rarely used in practice). - * The debug print format of `NaN` changes (originally `nan`). - - * Fixed file indices in the DWARF encoding of the `debug_line` section. This change is only relevant when using the `-g` flag (#5281). - - * Improved large array behavior under the incremental GC (#5314) - -## 0.14.14 (2025-06-30) - -* motoko (`moc`) - - * Lazy WASM imports: avoids unnecessary function imports from the runtime, improving compatibility with more runtime versions (#5276). - - * Improved stable compatibility error messages to be more concise and clear during canister upgrades (#5271). - -## 0.14.13 (2025-06-17) - -* motoko (`moc`) - - * Introduce `await?` to synchronize `async` futures, avoiding the commit point when already fulfilled (#5215). - - * Adds a `Prim.Array_tabulateVar` function, that allows faster initialization of mutable arrays (#5256). - - * optimization: accelerate IR type checking with caching of sub, lub and check_typ tests (#5260). - Reduces need for `-no-check-ir` flag. - -## 0.14.12 (2025-06-12) - - * Added the `rootKey` primitive (#4994). - - * optimization: for `--enhanced-orthogonal-persistence`, reduce code-size and compile-time by sharing more static allocations (#5233, #5242). - - * bugfix: fix `-fshared-code` bug (#5230). - - * bugfix: avoid stack overflow and reduce code complexity for large EOP canisters (#5218). - -## 0.14.11 (2025-05-16) - -* motoko (`moc`) - - * Enhance syntax error messages with examples and support _find-references_ and _go-to-definition_ - functionality for fields in the language server (Serokell, Milestone-3) (#5076). - - * bugfix: `mo-doc` now correctly extracts record-patterned function arguments (#5128). - -## 0.14.10 (2025-05-12) - -* motoko (`moc`) - - * Added new primitives for cost calculation: - `costCall`, `costCreateCanister`, `costHttpRequest`, `costSignWithEcdsa`, `costSignWithSchnorr` (#5001). - -## 0.14.9 (2025-04-25) - -* motoko (`moc`) - - * Added new primitives for exploding fixed-width numbers to bytes: - `explodeNat16`, `explodeInt16`, `explodeNat32`, `explodeInt32`, `explodeNat64`, `explodeInt64` (#5057). - -## 0.14.8 (2025-04-17) - -* motoko (`moc`) - - * Add random-access indexing to `Blob`, support special methods `get` and `keys` (#5018). - - * Officializing **enhanced orthogonal persistence** (EOP) after a successful beta testing phase (#5035). - - EOP needs to be explicitly enabled by the `--enhanced-orthogonal-persistence` compiler flag or via `args` in `dfx.json`: - ``` - "type" : "motoko" - ... - "args" : "--enhanced-orthogonal-persistence" - ``` - - * Add support for parser error recovery to improve LSP (Serokell, Milestone-2) (#4959). - - * We now provide a proper `motoko-mode` for `emacs` (#5043). - - * bugfix: Avoid generating new Candid `type`s arising from equal homonymous Motoko `type` (if possible) - in service definitions (#4309, #5013). - - * bugfix: Provide a more consistent framework for dealing with internally generated type indentifiers, - fixing caching bugs, e.g. in the VSCode plugin (#5055). - -## 0.14.7 (2025-04-04) - -* motoko (`moc`) - - * Preserve and infer named types both to improve displayed types in error messages, and to preserve function signatures when deriving Candid types (#4943). - The names remain semantically insignificant and are ignored when comparing types for subtyping and equality. - - For example, - ``` motoko - func add(x : Int, y : Int) : (res : Int) = x + y; - ``` - now has inferred type: - ``` motoko - (x : Int, y: Int) -> (res : Int) - ``` - Previously, the type would be inferred as: - ``` motoko - (Int, Int) -> Int - ``` - - * Refine the `*.most` stable signature file format to distinguish stable variables that are strictly required by the migration function rather than propagated from the actor body (#4991). - This enables the stable compatibility check to verify that a migration function will not fail due to missing required fields. - Required fields are declared `in`, not `stable`, in the actor's pre-signature. - - * Added improved LSP cache for typechecking (thanks to Serokell) (#4931). - - * Reduce enhanced-orthogonal-persistence memory requirements using incremental allocation within partitions (#4979). - -* motoko-base - - * Deprecated `ExperimentalCycles.add`, use a parenthetical `(with cycles = ) ` instead (dfinity/motoko-base#703). - -## 0.14.6 (2025-04-01) - -* motoko (`moc`) - - * To prevent implicit data loss due to upgrades, stable fields may no longer be dropped or promoted to lossy supertypes (#4970). - Removing a stable variable, or promoting its type to a lossy supertype by, for example, dropping nested record fields, - now requires an explicit migration expression. - Promotion to non-lossy supertypes, such as `Nat` to `Int` or `{#version1}` to `{#version1; #version2}`, is still supported. - - * Now we detect (and warn for) fields in literal objects and record extensions, - (as well as `public` fields or types in `object` and `class`) that are inaccessible - due to a user-specified type constraint (#4978, #4981). - - * We now provide release artefacts for `Darwin-arm64` and `Linux-aarch64` platforms (#4952). - -## 0.14.5 (2025-03-25) - -* motoko (`moc`) - - * Performance improvements to the default timer mechanism (#3872, #4967). - -* documentation (`mo-doc`) - - * Changed extracted `let` bindings with manifest function type to appear as `func`s (#4963). - -## 0.14.4 (2025-03-18) - -* motoko (`moc`) - - * Added `canisterSubnet` primitive (#4857). - -* motoko-base - - * Added `burn : Nat -> Nat` to `ExperimentalCycles` (dfinity/motoko-base#699). - - * Added `ExperimentalInternetComputer.subnet` (dfinity/motoko-base#700). - -## 0.14.3 (2025-03-04) - -* motoko (`moc`) - - * Added primitive predicate `isReplicatedExecution` (#4929). - -* motoko-base - - * Added `isRetryPossible : Error -> Bool` to `Error` (dfinity/motoko-base⁠#692). - - * Made `ExperimentalInternetComputer.replyDeadline` to return - an optional return type (dfinity/motoko-base⁠#693). - _Caveat_: Breaking change (minor). - - * Added `isReplicated : () -> Bool` to `ExperimentalInternetComputer` (dfinity/motoko-base#694). - -## 0.14.2 (2025-02-26) - -* motoko (`moc`) - - * Added support for sending `cycles` and setting a `timeout` in parentheticals. - This is an **experimental feature**, with new syntax, and now also allowing best-effort - message sends. The legacy call `Cycles.add` is still supported (#4608). - - For example, if one wants to attach cycles to a message send, one can prefix it with a parenthetical - ``` motoko - (with cycles = 5_000) Coins.mine(forMe); - ``` - Similarly a timeout for _best-effort_ execution (also called _bounded-wait_) can be specified like - ``` motoko - let worker = (with timeout = 15) async { /* worker loop */ }; - ``` - A common base for fields optionally goes before the `with` and can be customised with both fields - after it. Please consult the documentation for more usage information. - - * bugfix: `mo-doc` will now generate documentation for `actor`s and `actor class`es (#4905). - - * bugfix: Error messages now won't suggest privileged/internal names (#4916). - -## 0.14.1 (2025-02-13) - -* motoko (`moc`) - - * bugfix: Be more precise when reporting type errors in `migration` fields (#4888). - -## 0.14.0 (2025-02-05) - -* motoko (`moc`) - - * Add `.values()` as an alias to `.vals()` for arrays and `Blob`s (#4876). - - * Support explicit, safe migration of persistent data allowing arbitrary - transformations on a selected subset of stable variables. - Additional static checks warn against possible data loss (#4812). - - As a very simple example: - ``` motoko - import Nat32 "mo:base/Nat32"; - - (with migration = - func (old : { var size : Nat32 }) : { var length : Nat } = - { var length = Nat32.toNat(old.size) } - ) - persistent actor { - var length : Nat = 0; - } - ``` - may be used during an upgrade to rename the stable field `size` to `length`, - and change its type from `Nat32` to `Nat`. - - See the documentation for full details. - -## 0.13.7 (2025-02-03) - -* motoko (`moc`) - - * Support passing cycles in primitive `call_raw` (resp. `ExperimentalInternetComputer.call`) (#4868). - -## 0.13.6 (2025-01-21) - -* motoko (`moc`) - - * Support the low Wasm memory hook: `system func lowmemory() : async* () { ... }` (#4849). - - * Breaking change (minor) (#4854): - - * For enhanced orthogonal persistence: The Wasm persistence modes used internally for canister upgrades have been changed to lower case names, - `keep` and `replace` and instead of `Keep` and `Replace`: - - If using actor class instances with enhanced orthogonal persistence, you would need to recompile the program and upgrade with latest `moc` and `dfx`. - Otherwise, no action is needed. - - * bugfix: Checks and mitigations that timer servicing works (#4846). - - * bugfix: Some valid upgrades deleting a stable variable could fail the `--enhanced-orthogonal-persistence` stable compatibility check due to a bug (#4855). - -## 0.13.5 (2024-12-06) - -* motoko (`moc`) - - * Breaking change (minor) (#4786): - - * Add new keyword `transient` with exactly the same meaning as the old keyword `flexible` (but a more familiar reading). - - * Add keyword `persistent`. - - When used to modify the `actor` keyword in an actor or actor class definition, the keyword declares that the default stability of a - `let` or `var` declaration is `stable` (not `flexible` or `transient`). - - For example, a stateful counter can now be declared as: - ``` motoko - persistent actor { - // counts increments since last upgrade - transient var invocations = 0; - - // counts increments since first installation - var value = 0; // implicitly `stable` - - public func inc() : async () { - value += 1; - invocations += 1; - } - } - ``` - On upgrade, the transient variable `invocations` will be reset to `0` and `value`, now implicitly `stable`, will retain its current value. - - Legacy actors and classes declared without the `persistent` keyword have the same semantics as before. - - * Added new primitive `replyDeadline : () -> Nat64` to obtain when a response for a best-effort message is due (#4795). - - * bugfix: fail-fast by limiting subtyping depth to avoid reliance on unpredictable stack overflow (#3057, #4798). - -* motoko-base - - * Added `Text.fromList` and `Text.toList` functions (dfinity/motoko-base#676). - - * Added `Text.fromArray/fromVarArray` functions (dfinity/motoko-base#674). - - * Added `replyDeadline` to `ExperimentalInternetComputer` (dfinity/motoko-base⁠#677). - -## 0.13.4 (2024-11-29) - -* motoko (`moc`) - - * refactoring: Updating and simplifying the runtime system dependencies (#4677). - -* motoko-base - - * Breaking change (minor): `Float.format(#hex)` is no longer supported. - This is because newer versions of Motoko (such as with enhanced orthogonal persistence) - rely on the Rust-native formatter that does not offer this functionality. - It is expected that this formatter is very rarely used in practice (dfinity/motoko-base⁠#589). - - * Formatter change (minor): The text formatting of `NaN`, positive or negative, - will be `NaN` in newer Motoko versions, while it was `nan` or `-nan` in older versions (dfinity/motoko-base⁠#589). - -## 0.13.3 (2024-11-13) - -* motoko (`moc`) - - * typing: suggest conversions between primitive types from imported libraries - and, with `--ai-errors`, all available package libraries (#4747). - -* motoko-base - - * Add modules `OrderedMap` and `OrderedSet` to replace `RBTree` with improved functionality, performance - and ergonomics avoiding the need for preupgrade hooks (thanks to Serokell) (dfinity/motoko-base⁠#662). - -## 0.13.2 (2024-10-18) - -* motoko (`moc`) - - * Made the `actor`'s _self_ identifier available in the toplevel block. This also allows using - functions that refer to _self_ from the initialiser (e.g. calls to `setTimer`) (#4719). - - * bugfix: `actor ` now correctly performs definedness tracking (#4731). - -## 0.13.1 (2024-10-07) - -* motoko (`moc`) - - * Improved error messages for unbound identifiers and fields that avoid reporting large types and use an edit-distance based metric to suggest alternatives (#4720). - - * Flag `--ai-errors` to tailor error messages to AI clients (#4720). - - * Compilation units containing leading type definitions are now rejected with an improved error message (#4714). - - * bugfix: `floatToInt64` now behaves correctly in the interpreter too (#4712). - -## 0.13.0 (2024-09-17) - -* motoko (`moc`) - - * Added a new primitive `cyclesBurn : Nat -> Nat` for burning the canister's cycles - programmatically (#4690). - - * **For beta testing:** Support __enhanced orthogonal persistence__, enabled with new `moc` flag `--enhanced-orthogonal-persistence` (#4193). - - This implements scalable and efficient orthogonal persistence (stable variables) for Motoko: - * The Wasm main memory (heap) is retained on upgrade with new program versions directly picking up this state. - * The Wasm main memory has been extended to 64-bit to scale as large as stable memory in the future. - * The runtime system checks that data changes of new program versions are compatible with the old state. - - Implications: - * Upgrades become extremely fast, only depending on the number of types, not on the number of heap objects. - * Upgrades will no longer hit the IC instruction limit, even for maximum heap usage. - * The change to 64-bit increases the memory demand on the heap, in worst case by a factor of two. - * For step-wise release handling, the IC initially only offers a limited capacity of the 64-bit space (e.g. 4GB or 6GB), that will be gradually increased in future to the capacity of stable memory. - * There is moderate performance regression of around 10% for normal execution due to combined related features (precise tagging, change to incremental GC, and handling of compile-time-known data). - * The garbage collector is fixed to incremental GC and cannot be chosen. - * `Float.format(#hex prec, x)` is no longer supported (expected to be very rarely used in practice). - * The debug print format of `NaN` changes (originally `nan`). - - To activate enhanced orthogonal persistence under `dfx`, the following command-line argument needs to be specified in `dfx.json`: - - ``` - ... - "type" : "motoko" - ... - "args" : "--enhanced-orthogonal-persistence" - ... - ``` - BREAKING CHANGE (Minor): changes some aspects of `Float` formatting. - - For more information, see: - * The Motoko design documentation `design/OrthogonalPersistence.md` - * The Motoko user documentation `doc/md/canister-maintenance/upgrades.md`. - - * Candid decoding: impose an upper limit on the number of values decoded or skipped in a single candid payload, - as a linear function, `max_values`, of binary payload size. - - ``` - max_values(blob) = (blob.size() * numerator)/denominator + bias - ``` - - The current default settings are `{numerator = 1; denominator = 1; bias = 1024 }`, allowing a maximum - of 1024 values plus one additional value per byte in the payload. - - While hopefully not required, the constant factors can be read/modified using system functions: - * Prim.setCandidLimits: `{numerator : Nat32; denominator : Nat32; bias : Nat32 } -> ()` - * Prim.getCandidLimits: `() -> {numerator : Nat32; denominator : Nat32; bias : Nat32 }` - -## 0.12.1 (2024-08-08) - -* motoko (`moc`) - - * Added a new command-line flag `--print-source-on-error` to print source code context on error (#4650). - - * debugging: `__motoko_runtime_information()` as privileged query for runtime statistics (#4635). - - Exposing a privileged system-level query function `__motoko_runtime_information()` - that reports the current runtime statistics of the canister, such as the heap size, - the total number of allocated objects, the total amount of reclaimed memory and more. - This is useful because several statistics of the reported information cannot be - inspected on the IC replica dashboard as they are internal to the Motoko runtime system. - This query is only authorized to the canister controllers and self-calls of the canister. - - ``` Motoko - __motoko_runtime_information : () -> { - compilerVersion : Text; - rtsVersion : Text; - garbageCollector : Text; - sanityChecks : Nat; - memorySize : Nat; - heapSize : Nat; - totalAllocation : Nat; - reclaimed : Nat; - maxLiveSize : Nat; - stableMemorySize : Nat; - logicalStableMemorySize : Nat; - maxStackSize : Nat; - callbackTableCount : Nat; - callbackTableSize : Nat; - } - ``` - -* motoko-base - - * Added `Iter.concat` function (thanks to AndyGura) (dfinity/motoko-base⁠#650). - -## 0.12.0 (2024-07-26) - -* motoko (`moc`) - - * feat: `finally` clauses for `try` expressions (#4507). - - A trailing `finally` clause to `try`/`catch` expressions facilitates structured - resource deallocation (e.g. acquired locks, etc.) and similar cleanups in the - presence of control-flow expressions (`return`, `break`, `continue`, `throw`). - Additionally, in presence of `finally` the `catch` clause becomes optional and - and any uncaught error from the `try` block will be propagated, after executing the `finally` block. - - _Note_: `finally`-expressions that are in scope will be executed even if an execution - path _following_ an `await`-expression traps. This feature, formerly not available in Motoko, - allows programmers to implement cleanups even in the presence of traps. For trapping - execution paths prior to any `await`, the replica-provided state roll-back mechanism - ensures that no cleanup is required. - - The relevant security best practices are accessible at - /guides/security/inter-canister-calls#recommendation - - BREAKING CHANGE (Minor): `finally` is now a reserved keyword, - programs using this identifier will break. - - * bugfix: `mo-doc` will now generate correct entries for `public` variables (#4626). - -## 0.11.3 (2024-07-16) - -* motoko (`moc`) - - * feat: `motoko-san` contributions by Serokell. Now able to verify some simple but non-trivial actors - (thanks to the entire Serokell team) (#4500). - - * bugfix: Corrects the interpreter (and compiler) to recognise certain type parameters as callable function types (#4617). - -## 0.11.2 (2024-07-06) - -* motoko (`moc`) - - * deprecation: Deprecate the use of base library's `ExperimentalStableMemory` (ESM) (#4573). - New `moc` flag `--experimental-stable-memory ` controls the level of deprecation: - * n < 0: error on use of stable memory primitives. - * n = 0: warn on use of stable memory primitives. - * n > 1: warning-less use of stable memory primitives (for legacy applications). - Users of ESM should consider migrating their code to use isolated regions (library `Region.mo`) instead. - - * bugfix: Fix the detection of unused declarations in `switch` and `catch` alternatives (#4560). - - * improvement: Only warn on unused identifiers if type checking is error-free (#4561). - -## 0.11.1 (2024-03-15) - -* motoko (`moc`) - - * feat: Custom error message for unused, punned field bindings (#4454). - - * feat: Don't report top-level identifiers as unused (#4452). - - * bugfix: Declaring `` capability on a class enables system capabilities in its body (#4449). - - * bugfix: Fix crash compiling actor reference containing an `await` (#4418, #4450). - - * bugfix: Fix crash when compiling with flag `--experimental-rtti` (#4434). - -## 0.11.0 (2024-03-05) - -* motoko (`moc`) - - * Warn on detection of unused identifiers (code `M0194`) (#4377). - - - By design, warnings are not emitted for code imported from a package. - - A warning can be suppressed by replacing the identifier entirely by a wildcard `_`, - or by prefixing it with an `_`, e.g. replace `x` by `_x`. - - **Limitations**: recursive and mutually recursive definitions are considered used, - even if never referenced outside the recursive definition. - - * Remove `__get_candid_interface_tmp_hack` endpoint. Candid interface is already stored as canister metadata, this temporary endpoint is redundant, thus removed. (#4386) - - * Improved capability system, introducing a synchronous (`system`) capability (#4406). - - `actor` initialisation body, `pre`/`postupgrade` hooks, `async` function bodies (and - blocks) possess this capability. Functions (and classes) can demand it by prepending `system` - to the type argument list. The capability can be forwarded in calls by mentioning `` - in the instantiation parameter list. - - BREAKING CHANGE (Minor): A few built-in functions have been marked with demand - for the `system` capability. In order to call these, the full call hierarchy needs to be - adapted to pass the `system` capability. - - * Introduced the feature for precise tagging of scalar values (#4369). - - Controlled by flag `--experimental-rtti` (off by default). Minor performance changes for - arithmetic expected. We advise to only turn on the feature for testing, as currently no - productive upsides exist (though future improvements will depend on it), and performance - of arithmetic will degrade somewhat. See the PR for the whole picture. - -* motoko-base - - * Added `Option.equal` function (thanks to ByronBecker) (dfinity/motoko-base⁠#615). - -## 0.10.4 (2024-01-10) - -* motoko (`moc`) - - * Officializing the new **incremental garbage collector** after a successful beta testing phase. - The incremental GC can be enabled by the `moc` flag `--incremental-gc` (#3837) and is designed to scale for large program heap sizes. - - **Note**: While resolving scalability issues with regard to the instruction limit of the GC work, it is now possible to hit other scalability limits: - - _Out of memory_: A program can run out of memory if it fills the entire memory space with live objects. - - _Upgrade limits_: When using stable variables, the current mechanism of serialization and deserialization to and from stable memory can exceed the instruction limit or run out of memory. - - **Recommendations**: - - _Test the upgrade_: Thoroughly test the upgrade mechanism for different data volumes and heap sizes and conservatively determine the amount of stable data that is supported when upgrading the program. - - _Monitor the heap size_: Monitor the memory and heap size (`Prim.rts_memory_size()` and `Prim.rts_heap_size()`) of the application in production. - - _Limit the heap size_: Implement a custom limit in the application to keep the heap size and data volume below the scalability limit that has been determined during testing, in particular for the upgrade mechanism. - - _Avoid large allocations per message_: Avoid large allocations of 100 MB or more per message, but rather distribute larger allocations across multiple messages. Large allocations per message extend the duration of the GC increment. Moreover, memory pressure may occur because the GC has a higher reclamation latency than a classical stop-the-world collector. - - _Consider a backup query function_: Depending on the application case, it can be beneficial to offer an privileged _query_ function to extract the critical canister state in several chunks. The runtime system maintains an extra memory reserve for query functions. Of course, such a function has to be implemented with a check that restricts it to authorized callers only. It is also important to test this function well. - - _Last resort if memory would be full_: Assuming the memory is full with objects that have shortly become garbage before the memory space has been exhausted, the canister owner or controllers can call the system-level function `__motoko_gc_trigger()` multiple times to run extra GC increments and complete a GC run, for collecting the latest garbage in a full heap. Up to 100 calls of this function may be needed to complete a GC run in a 4GB memory space. The GC keeps an specific memory reserve to be able to perform its work even if the application has exhausted the memory. Usually, this functionality is not needed in practice but is only useful in such exceptional cases. - - * Allow type annotations on free-standing `object`/`module`/`actor` blocks, in order to perform a conformity check with an interface type (#4324). - -## 0.10.3 (2023-12-20) - -* motoko (`moc`) - - * Include doc comments to Candid interfaces generated via the `--idl` flag (#4334). - - * bugfix: fix broken implementations of `Region.loadNat32`, `Region.storeNat32`, `Region.loadInt32`, `Region.storeInt32` (#4335). - Values previously stored with the broken 32-bit operations must be loaded with care. - If bit 0 is clear, the original value can be obtained by an arithmetic shift right by 1 bit. - If bit 0 is set, the value cannot be trusted and should be ignored - (it encodes some transient address of a boxed value). - -* motoko-base - - * Added `ExperimentalInternetComputer.performanceCounter` function to get the raw performance - counters (dfinity/motoko-base⁠#600). - - * Added `Array.take` function to get some prefix of an array (dfinity/motoko-base⁠#587). - - * Deprecated `TrieSet.mem` in favor of `TrieSet.has` (dfinity/motoko-base⁠#576). - - * bugfix: `Array.chain(as, f)` was incorrectly trapping when `f(a)` was an empty array - (dfinity/motoko-base⁠#599). - -## 0.10.2 (2023-11-12) - -* motoko (`moc`) - - * bugfix: separate tag from underscore in coverage warnings (#4274). - - * Code compiled for targets WASI (`-wasi-system-api`) and pure Wasm (`-no-system-api`) can now - use up to 4GB of (efficiently emulated) stable memory, enabling more offline testing of, for example, - stable data structures built using libraries `Regions.mo` and `ExperimentalStableMemory.mo`. - Note that any Wasm engine (such as `wasmtime`), used to execute such binaries, must support and enable - Wasm features `multi-memory` and `bulk-memory` (as well as the standard NaN canonicalization) (#4256). - - * bugfix: fully implement `Region.loadXXX/storeXXX` for `Int8`, `Int16` and `Float` (#4270). - - * BREAKING CHANGE (Minor): values of type [`Principal`](doc/md/base/Principal.md) are now constrained to contain - at most 29 bytes, matching the IC's notion of principal (#4268). - - In particular: - - * An actor `import` will be statically rejected if the binary representation of the (aliased) textually encoded - principal contains strictly more than 29 bytes. - - * `Principal.fromBlob(b)` will trap if `b` contains strictly more than 29 bytes. - - * The actor literal, `actor `, will trap if the binary representation of - of the textually encoded principal `` contains strictly more than 29 bytes. - -* motoko-base - - * bugfix: fix `Array.tabulateVar` to avoid repeated side-effects (dfinity/motoko-base⁠#596) - -## 0.10.1 (2023-10-16) - -* motoko (`moc`) - - * bugfix: fix assertion failure renaming `or`-patterns (#4236, #4224). - - * bugfix: unsuccessful Candid decoding of an optional array now defaults to null instead of crashing (#4240). - - * bugfix: Candid decoding of an optional, unknown variant with a payload now succeeds instead of crashing (#4238). - - * Implement Prim.textLowercase and Prim.textUppercase (via Rust) (#4216). - - * perf: inline sharable low-level functions in generated coded, - trading code size for reduced cycle count (#4212). - Controlled by flags: - * `-fno-shared-code` (default) - * `-fshared-code` (legacy) - (Helps mitigate the effect of the IC's new cost model, that increases - the cost of function calls). - -* motoko-base - - * Added `Principal.toLedgerAccount` (dfinity/motoko-base⁠#582). - - * Added `Text.toLowercase` and `Text.toUppercase` (dfinity/motoko-base⁠#590). - -## 0.10.0 (2023-09-11) - -* motoko (`moc`) - - * Added a new stable `Region` type of dynamically allocated, independently growable and - isolated regions of IC stable memory (#3768). See documentation. - BREAKING CHANGE: stable memory changes may occur that can prevent returning - to previous `moc` versions. - - * Added doc comments in generated Candid files (#4178). - -* motoko-base - - * Exposed conversions between adjacent fixed-width types (dfinity/motoko-base⁠#585). - - * Added library `Region.mo` offering isolated regions of IC stable memory (dfinity/motoko-base⁠#580). - -## 0.9.8 (2023-08-11) - -* motoko (`moc`) - - * Added numerical type conversions between adjacent fixed-width types (#4139). - - * Administrative: legacy-named release artefacts are no longer created (#4111). - -## 0.9.7 (2023-07-18) - -* motoko (`moc`) - - * Performance improvement: lower the default allocation for bignums (#4102). - - * Performance improvement: generate better code for pattern matches on some small variants (#4093). - - * bugfix: don't crash on import of Candid composite queries (#4128). - -## 0.9.6 (2023-07-07) - -* motoko (`moc`) - - * Allow canister controllers to call the `__motoko_stable_var_info` query endpoint (#4103). - (Previously only self-queries were permitted.) - - * Performance improvement: reduced cycle consumption for allocating objects (#4095). - - * bugfix: reduced memory consumption in the Motoko Playground (#4106). - -## 0.9.5 (2023-07-05) - -* motoko (`moc`) - - * Allow identifiers in `or`-patterns (#3807). - Bindings in alternatives must mention the same identifiers and have compatible types: - ``` Motoko - let verbose = switch result { - case (#ok) "All is good!"; - case (#warning why or #error why) "There is some problem: " # why; - } - ``` - - * Performance improvement: improved cycle consumption allocating fixed-size objects (#4064). - Benchmarks indicate up to 10% less cycles burned for allocation-heavy code, - and 2.5% savings in realistic applications. - - * Administrative: binary build artefacts are now available according to standard naming - conventions (thanks to EnzoPlayer0ne) (#3997). - Please consider transitioning to downloading binaries following the new scheme, - as legacy naming will be discontinued at some point in the future. - -## 0.9.4 (2023-07-01) - -* motoko (`moc`) - - * Allow multiline text literals (#3995). - For example, - ``` - "A horse walks into a bar. - The barman says: `Why the long face?`" - ``` - - parses as: - ``` - "A horse walks into a bar.\nThe barman says: `Why the long face?`" - ``` - - * Added pipe operator ` |> ` and placeholder expression `_` (#3987). - For example: - ``` motoko - Iter.range(0, 10) |> - Iter.toList _ |> - List.filter(_, func n { n % 3 == 0 }) |> - { multiples = _ }; - ``` - - may, according to taste, be a more readable rendition of: - ``` motoko - { multiples = - List.filter( - Iter.toList(Iter.range(0, 10)), - func n { n % 3 == 0 }) }; - ``` - - However, beware the change of evaluation order for code with side-effects. - - * BREAKING CHANGE (Minor): - - New keyword `composite` allows one to declare Internet Computer *composite queries* (#4003). - - For example, - ``` motoko - public shared composite query func sum(counters : [Counter]) : async Nat { - var sum = 0; - for (counter in counters.vals()) { - sum += await counter.peek(); - }; - sum - } - ``` - - has type: - ``` motoko - shared composite query [Counter] -> async Nat - ``` - - and can call both `query` and other `composite query` functions. - - See the documentation for full details. - - * Allow canister imports of Candid service constructors, ignoring the service arguments to - import the instantiated service instead (with a warning) (#4041). - - * Allow optional terminal semicolons in Candid imports (#4042). - - * bugfix: allow signed float literals as static expressions in modules (#4063). - - * bugfix: improved reporting of patterns with record types in error messages (#4002). - -* motoko-base - - * Added more `Array` (and `Text`) utility functions (thanks to roman-kashitsyn) (dfinity/motoko-base⁠#564). - -## 0.9.3 (2023-06-19) - -* motoko (`moc`) - - * Added fields `sender_canister_version` for actor class version tracking (#4036). - -## 0.9.2 (2023-06-10) - -* motoko (`moc`) - - * BREAKING CHANGE (Minor): - - `or`-patterns in function definitions cannot be inferred any more. The new error - message suggests to add a type annotation instead. This became necessary in order - to avoid potentially unsound types (#4012). - - * Added implementation for `ic0.canister_version` as a primitive (#4027). - - * Added a more efficient `Prim.blobCompare` (thanks to nomeata) (#4009). - - * bugfix: minor error in grammar for `async*` expressions (#4005). - -* motoko-base - - * Add `Principal.isController` function (dfinity/motoko-base#558). - -## 0.9.1 (2023-05-15) - -* motoko (`moc`) - - * Added implementation for `ic0.is_controller` as a primitive (#3935). - - * Added ability to enable the new incremental GC in the Motoko Playground (#3976). - -## 0.9.0 (2023-05-12) - -* motoko (`moc`) - - * **For beta testing:** Add a new _incremental_ GC, enabled with new moc flag `--incremental-gc` (#3837). - The incremental garbage collector is designed to scale for large program heap sizes. - - The GC distributes its workload across multiple steps, called increments, that each pause the mutator - (user's program) for only a limited amount of time. As a result, the GC work can fit within the instruction-limited - IC messages, regardless of the heap size and the object structures. - - According to GC benchmark measurements, the incremental GC is more efficient than the existing copying, compacting, - and generational GC in the following regards: - * Scalability: Able to use the full heap space, 3x more object allocations on average. - * Shorter interruptions: The GC pause has a maximum limit that is up to 10x shorter. - * Lower runtimes: The number of executed instructions is reduced by 10% on average (compared to the copying GC). - * Less GC overhead: The amount of GC work in proportion to the user's program work drops by 10-16%. - - The GC incurs a moderate memory overhead: The allocated WASM memory has been measured to be 9% higher - on average compared to the copying GC, which is the current default GC. - - To activate the incremental GC under `dfx`, the following command-line argument needs to be specified in `dfx.json`: - - ``` - ... - "type" : "motoko" - ... - "args" : "--incremental-gc" - ... - ``` - - * bugfix: `array.vals()` now returns a working iterator for mutable arrays (#3497, #3967). - -## 0.8.8 (2023-05-02) - -* motoko (`moc`) - - * Performance improvement: optimised code generation for pattern matching that cannot fail (#3957). - -## 0.8.7 (2023-04-06) - -* motoko (`moc`) - - * Added ability to `mo-doc` for rendering documentation of nested modules (#3918). - - * bugfix: when re-adding recurrent timers, skip over past expirations (#3871). - - * bugfix: eliminated crash compiling local `async` functions that pattern match on arguments (#3910, #3916). - -## 0.8.6 (2023-04-01) - -* motoko (`moc`) - - * bugfix: avoid compiler crash (regression) when `let`-matching on constant variants (#3901, #3903). - - * Performance improvement: improved cycle usage when receiving messages (#3893). - -## 0.8.5 (2023-03-20) - -* motoko (`moc`) - - * Performance improvement: Values of variant type that are compile-time known - are relegated to the static heap now and don't get allocated each time (#3878). - - * bugfix: the global timer expiration callback was called unnecessarily in the - default mechanism (#3883). - -## 0.8.4 (2023-03-11) - -* motoko (`moc`) - - * Performance improvement: UTF-8 coding and validation is now properly tail recursive (#3842). - - * Performance improvement: eliminated bounds checking for certain array accesses (thanks to nomeata) (#3853). - - * Performance improvement: optimized `{array, blob, text}.size()` operations (thanks to nomeata) (#3863). - - * Performance improvement: efficient tuple results in `switch` statements (thanks to nomeata) (#3865). - - * Performance improvement: more efficient untagging operation (#3873). - - * bugfix: restored a grammar regression caused by `let-else` (#3869). - -* motoko-base - - * Add `Array.subArray` function (dfinity/motoko-base#445). - - * BREAKING CHANGE (Minor) - - Optimized `AssocList.{replace, find}` to avoid unnecessary allocation (dfinity/motoko-base#535, dfinity/motoko-base#539). - Note: this subtly changes the order in which the key-value pairs occur after replacement. May affect other containers that use `AssocList`. - - * Performance improvement: Optimized deletion for `Trie`/`TrieMap` (dfinity/motoko-base#525). - -## 0.8.3 (2023-02-24) - -* motoko (`moc`) - - * new 'let-else' construct for handling pattern-match failure (#3836). - This is a frequently asked-for feature that allows to change the control-flow - of programs when pattern-match failure occurs, thus providing a means against - the famous "pyramid of doom" issue. A common example is look-ups: - ``` Motoko - shared func getUser(user : Text) : async Id { - let ?id = Map.get(users, user) else { throw Error.reject("no such user") }; - id - } - ``` - Similarly, an expression like - ``` Motoko - (label v : Bool { let = else break v false; true }) - ``` - evaluates to a `Bool`, signifying whether `` matches ``. - - * Improve recursive deserialization capacity to match recursive serialization capacity by reducing - Wasm stack consumption (#3809). - Because of the bounds on recursion depth imposed by fixed-size stack, the - advice remains the same: avoid deeply nested recursive data structures. - Think "shallow trees good, very long lists bad". - - * bugfix: stack overflow in UTF-8 encode/decode for `moc.js` (#3825). - -* motoko-base - - * add missing `unshare : Tree -> ()` method to class `RBTree` - to restore objects from saved state (dfinity/motoko-base#532). - -## 0.8.2 (2023-02-17) - -* motoko (`moc`) - - * Add compiler flag `--rts-stack-pages ` to override default number of - pages dedicated to fixed runtime system stack. Now defaults to 32 pages - (2MiB) (up from previous 2 pages/128KiB) (#3782). - In emergencies, increasing this setting may improve your ability to deserialize - deeply nested Candid or stable variable data. - - * Add stack overflow detection utilising reserved page (#3793). - - * Performance improvement: heap allocator speedup (#3090, #3790). - - * bugfix: avoid more heap-out-bounds errors during deserialization of stable variables - by increasing default runtime system stack from 128KiB to 2MiB (#3782). - _Note_: this is a partial fix, as issues with stack growth remain. - -* motoko-base - - * bugfix: non-leaky deletion for `RBTree` (dfinity/motoko-base#524). - -## 0.8.1 (2023-02-03) - -* motoko (`moc`) - - * Performance improvement: faster heap allocation (#3765). - - * bugfix: `async` returns involving abbreviated tuple types no longer crash the compiler (#3740, #3741). - - * bugfix: avoid quadratic code expansion due to imported, but unused, actor classes (#3758). - -## 0.8.0 (2023-01-27) - -* motoko (`moc`) - - * BREAKING CHANGE - - Motoko now implements Candid 1.4 (dfinity/candid#311). - - In particular, when deserializing an actor or function reference, - Motoko will now first check that the type of the deserialized reference - is a subtype of the expected type and act accordingly. - - Very few users should be affected by this change in behaviour. - - * BREAKING CHANGE - - Failure to send a message no longer traps but, instead, throws a catchable `Error` with new error code `#call_error` (#3630). - - On the IC, the act of making 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 now reported by throwing an `Error` with new `ErrorCode` `#call_error { err_code = n }`, - where `n` is the non-zero `err_code` value returned by the IC. - Like other errors, call errors can be caught and handled using `try ... catch ...` expressions, if desired. - - The constructs that now throw call errors, instead of trapping as with previous version of Motoko are: - * calls to `shared` functions (including oneway functions that return `()`). - These involve sending a message to another canister, and can fail when the queue for the destination canister is full. - * calls to local functions with return type `async`. These involve sending a message to self, and can fail when the local queue for sends to self is full. - * `async` expressions. These involve sending a message to self, and can fail when the local queue for sends to self is full. - * `await` expressions. These can fail on awaiting an already completed future, which requires sending a message to self to suspend and commit state. - - (On the other hand, `async*` (being delayed) cannot throw, and evaluating `await*` will at most propagate an error from its argument but not, in itself, throw.) - - Note that exiting a function call via an uncaught throw, rather than a trap, will commit any state changes and currently queued messages. - The previous behaviour of trapping would, instead, discard, such changes. - - To appreciate the change in semantics, consider the following example: - - ``` motoko - actor { - var count = 0; - public func inc() : async () { - count += 1; - }; - public func repeat() : async () { - loop { - ignore inc(); - } - }; - public func repeatUntil() : async () { - try { - loop { - ignore inc(); - } - } catch (e) { - } - }; - } - ``` - - In previous releases of Motoko, calling `repeat()` and `repeatUntil()` would trap, leaving `count` at `0`, because - each infinite loop would eventually exhaust the message queue and issue a trap, rolling back the effects of each call. - With this release of Motoko, calling `repeat()` will enqueue several `inc()` messages (around 500), then `throw` an `Error` - and exit with the error result, incrementing the `count` several times (asynchronously). - Calling `repeatUntil()` will also enqueue several `inc()` messages (around 500) but the error is caught so the call returns, - still incrementing `count` several times (asynchronously). - - The previous semantics of trapping on call errors can be enabled with compiler option `--trap-on-call-error`, if desired, - or selectively emulated by forcing a trap (e.g. `assert false`) when an error is caught. - - For example, - - ``` motoko - public func allOrNothing() : async () { - try { - loop { - ignore inc(); - } - } catch (e) { - assert false; // trap! - } - }; - ``` - - Calling `allOrNothing()` will not send any messages: the loop exits with an error on queue full, - the error is caught, but `assert false` traps so all queued `inc()` messages are aborted. - - * bugfix: system method `inspect` involving message with single tuple argument no longer crashes the compiler (#3732, #3733). - -## 0.7.6 (2023-01-20) - -* motoko (`moc`) - - * Added support for `ManagementCanister.raw_rand` in interpreters (#3693). - - * Added preliminary Viper support for `old` expressions in specifications and calls to private methods (#3675). - - * bugfix: in the default timer mechanism `cancelTimer` sometimes wouldn't actually stop a recurring timer (#3695). - - * bugfix: zero negation for floating point numbers in compiled code (#3676). - -* motoko-base - - * Add user-facing timer functionality (dfinity/motoko-base#474). - - * Add `Array.size` (dfinity/motoko-base#486, dfinity/motoko-base#494). - - * Add `TrieSet` methods `isEmpty`, `isSubset` (dfinity/motoko-base#503). - - * BREAKING CHANGES (Minor): - - renamed `Float.neq` to `Float.neg` (this was a misspelling) - - renamed `Nat.neq` to `Nat.neg` (this was a misspelling) - - removed second argument from `bitnot` (this was an oversight) - - * bugfix: `Random.Finite.coin` didn't use entropy correctly (dfinity/motoko-base#500). - - * bugfix: `Trie.mergeDisjoint` (dfinity/motoko-base#505). - - * bugfix: `TrieSet.equals` (dfinity/motoko-base#503). - - * Various documentation fixes and API usage examples. - -## 0.7.5 (2022-12-23) - -* motoko (`moc`) - - * Add new primitives for a default timer mechanism (#3542). These are - ``` Motoko - setTimer : (delayNanos : Nat64, recurring : Bool, job : () -> async ()) -> (id : Nat) - cancelTimer : (id : Nat) -> () - ``` - By defining a `system func timer` the default mechanism can now be overridden by a custom - implementation. Additionally by supplying the command-line flag `-no-timer` all aspects - of timers can be suppressed, e.g. for space- or security-sensitive purposes, thus effectively - reverting canisters to the pre-timers era. - - * bugfix: silence bogus cascading errors in stable compatibility check (#3645). - -## 0.7.4 (2022-12-07) - -* motoko (`moc`) - - * Add new keywords `async*` and `await*` (note the `*`) for efficient abstraction of asynchronous code (#3609). - ``` - ::= ... - async* delayed, asynchronous computation - ::= ... - async* delay an asynchronous computation - await* execute a delayed computation (only in async, async*) - ``` - This avoids the resource consumption and latency of `async`/`await` by only committing state and suspending execution - when necessary in the `await*`-ed computation, not necessarily at the `await*` itself. - - WARNING: Unlike `async`/`await`: - * an `async*` value has no effect unless `await*`-ed; - * each `await*` of the same `async*` value repeats its effects. - - This feature is experimental and may evolve in future. Use with discretion. - See the [manual](doc/md/reference/language-manual.md) for details. - - * Suppress GC during IC `canister_heartbeat`, deferring any GC to the scheduled Motoko `heartbeat` `system` method (#3623). - This is a temporary workaround, to be removed once DTS is supported for `canister_heartbeat` itself (#3622). - - * Add a new _generational_ GC, enabled with new moc flag `--generational-gc` (#3495). - The generational garbage collector optimizes for fast reclamation of short-lived objects. - New objects are allocated in a young generation that is more frequently collected than the older objects - that have already survived a GC run. - - For many cases, the generational GC is more efficient than the existing compacting GC and copying GCs: - * Lower runtimes: Less number of executed instructions on average. - * Shorter interruptions: Young generation collection entails shorter program interruptions. - - To activate the generational GC under `dfx`, the following command-line argument needs to be specified in `dfx.json`: - - ``` - ... - "type" : "motoko" - ... - "args" : "--generational-gc" - ... - ``` - - * `moc.js` : add trampoline and step limiter to interpreter, avoiding (some) stackoverflows and - hangs (#3618, #3541). - Enables execution of larger examples on web pages. - - * BREAKING CHANGE (Minor): - - Consider records with mutable fields as non-static (#3586). - Consequently, an imported library declaring a mutable record is now - rejected, not accepted, to be consistent with the declarations of - mutable fields and mutable objects. - - * Experimental Viper integration by compiling a very narrow subset of - Motoko to the verification intermediate language. See `src/viper/README.md` - and the PR for details. (#3477). - -* motoko-base - - * Unit tests for Trie and fix for `disj` (dfinity/motoko-base#438). - - * Respect Trie structure in `filter` (dfinity/motoko-base#431, dfinity/motoko-base#438). - - * Array module reimplementation, tests and documentation (dfinity/motoko-base#425,dfinity/motoko-base#432). - -## 0.7.3 (2022-11-01) - -* motoko (`moc`) - - * Statically reject shared functions and function types with type parameters (#3519, #3522). - - * Performance improvement: `Array.init` and `Array.tabulate` (#3526). - -* motoko-base - - * Add some examples to `Buffer` library documentation (dfinity/motoko-base#420). - - * Fix another bug in `Buffer` library affecting `filterEntries` (dfinity/motoko-base#422). - -## 0.7.2 (2022-10-25) - -* motoko-base - - * Fix bugs in `Buffer` library affecting `remove` and `filterEntries` (dfinity/motoko-base#419). - -## 0.7.1 (2022-10-24) - -* motoko (`moc`) - - * Halve (default ir-checking) compilation times by optimizing type comparison and hashing (#3463) - - * Add support for type components in object type syntax (#3457, also fixes #3449) - ``` motoko - type Record = { type T = Nat; x : Nat}; - ``` - is now legal. - Note the definition of `T` is neither recursive, nor bound in `x : Nat`, - but can refer to an existing recursive type declared in an outer scope. - -* motoko-base - - * Optimized and extended `Buffer` library (dfinity/motoko-base#417). - -## 0.7.0 (2022-08-25) - -* motoko (`moc`) - - * BREAKING CHANGE (Minor): - Adds new syntax for merging records (objects) and - adding/overwriting fields. The expression - ``` motoko - { baseA and baseB with field1 = val1; field2 = val2 } - ``` - creates a new record by joining all (statically known) fields from - `baseA/B` and the explicitly specified `field1/2`. - This is a _breaking change_, as a new keyword `with` has been added. - Restrictions for ambiguous and `var` fields from bases apply. (#3084) - - * Add new support for installing actor class instances on the IC, - enabling specification of canister settings, install, upgrade and - reinstall. (#3386) - - A new expression - - ``` bnf - (system . ) - ``` - where `` is an imported library and `` is the name of - an actor class, accesses a secondary constructor of the class - that takes an additional argument controlling the installation. - - For example, - ``` motoko - await (system Lib.Node)(#upgrade a)(i); - ``` - upgrades actor `a` with the code for a new instance of class `Lib.Node`, - passing constructor argument `(i)`. - - * Performance improvements for assigment-heavy code (thanks to nomeata) (#3406) - -## 0.6.30 (2022-08-11) - -* motoko (`moc`) - - * add primitives - ```motoko - shiftLeft : (Nat, Nat32) -> Nat - shiftRight : (Nat, Nat32) -> Nat - ``` - for efficiently multiplying/dividing a `Nat` by a power of 2 - (#3112) - - * add primitives - ```motoko - rts_mutator_instructions : () -> Nat - rts_collector_instructions : () -> Nat - ``` - to report approximate IC instruction costs of the last message - due to mutation (computation) and collection (GC), respectively (#3381) - -* motoko-base - - * Add - ```motoko - Buffer.fromArray - Buffer.fromVarArray - ``` - for efficiently adding an array to a `Buffer` - (dfinity/motoko-base#389) - - * Add - ```motoko - Iter.sort : (xs : Iter, compare : (A, A) -> Order) : Iter - ``` - for sorting an `Iter` given a comparison function - (dfinity/motoko-base#406) - - * Performance: `HashMap` now avoids re-computing hashes on `resize` - (dfinity/motoko-base#394) - -## 0.6.29 (2022-06-10) - -* motoko (`moc`) - - * The language server now supports explicit symbol imports (thanks - to rvanasa) (#3282) - * The language server now has improved support for navigating to - definitions in external modules (thanks to rvanasa) (#3263) - * Added a primitive `textCompare` allowing more efficient three-way - `Text` comparisons (#3298) - * Fixed a typing bug with annotated, recursive records (#3268) - -* motoko-base - - * Add - ```motoko - ExperimentalInternetComputer.countInstruction : (comp : () -> ()) -> Nat64 - ``` - to count the Wasm instructions performed during execution of `comp()` (dfinity/motoko-base#381) - - * Add - ```motoko - ExperimentalStableMemory.stableVarQuery : () -> (shared query () -> async {size : Nat64}) - ``` - for estimating stable variable storage requirements during upgrade - (dfinity/motoko-base#365) - * Performance improvement to `Text.compare` (dfinity/motoko-base#382) - -## 0.6.28 (2022-05-19) - -* motoko (`moc`) - - * Add `to_candid`, `from_candid` language constructs for Candid serialization to/from Blobs (#3155) - * New `system` field 'inspect' for accepting/declining canister ingress messages (see doc) (#3210) - -## 0.6.27 (2022-05-04) - -* motoko (`moc`) - - * Importing modules by relative path is now more robust (#3215). - * Performance: persisting stable variables to stable memory is now - performed in streaming fashion, reducing heap consumption and - copying during an upgrade (#3149). - * Performance: local 32- and 64-bit numeric values are now stored in - using unboxed form when possible (thanks to nomeata) (#3207). - -* motoko-base - - * Fixed a bug in `Trie.filter` (and `Trie.mapFilter`) which could - lead to missing matches in some cases (dfinity/motoko-base#371). - -## 0.6.26 (2022-04-20) - -* motoko (`moc`) - - * Performance: inline prim-wrapping functions (thanks to nomeata) (#3159) - * Improve type pretty printer to mirror type parser (avoids producing unparseable stable variable signatures) (#3190) - * Adds new flag `--omit-metadata` to omit certain metadata sections from `actor` (and `actor class`) Wasm (#3164) - * Performance: avoid redundant heap allocation when deserializing compact Candid `int` and `nat` values (#3173) - * Added a primitive to obtain stable variable memory footprint (#3049) - -* motoko-base - - * Fixed the 32-bit range limitation of `Hash.hash: Nat -> Nat32` and - deprecate most functions in `Hash` (dfinity/motoko-base#366). - * Add `List.toIter` (thanks to hoosan) (dfinity/motoko-base#336). - -## 0.6.25 (2022-03-07) - -* motoko (`moc`) - - * bugfix: fix bogus elision of type constructors sharing names with primitive types in `--stable-types` section and `.most` file (#3140) - -## 0.6.24 (2022-03-06) - -* motoko (`moc`) - - * bugfix: fix bogus identification of distinct type constructors - in --stable-types section and .most file (#3140) - -## 0.6.23 (2022-03-05) - -* motoko (`moc`) - - * bugfix: fix pretty printing of (stable) types and #3128 (#3130) - - * Collect constructors *transitively* before emitting a .most file. - * Modifies type pretty printer to produce well-formed types and stable type signatures. - -## 0.6.22 (2022-02-24) - -* motoko (`moc`) - - * Fix: remove bogus error when transitively importing module with - selective field imports (#3121) - * Fix: Treating eponymous types from separate candid files (#3103) - -* Various reports from CI are now pushed to - https://dfinity.github.io/motoko (#3113) - -## 0.6.21 (2022-01-31) - -* motoko (`moc`) - - * Emit new ICP metadata custom section 'motoko:compiler' with compiler release or revision in UTF8 (e.g. "0.6.21"). Default is `icp:private` (#3091). - * Generalized `import` supporting pattern matching and selective field imports (#3076). - * Fix: insert critical overflow checks preventing rare heap corruptions - in out-of-memory allocation and stable variable serialization (#3077). - * Implement support for 128-bit Cycles-API (#3042). - -* motoko-base - - * `ExperimentalInternetComputer` library, exposing low-level, binary `call` function (a.k.a. "raw calls") (dfinity/motoko-base#334, Motoko #3806). - * `Principal.fromBlob` added (dfinity/motoko-base#331). - -## 0.6.20 (2022-01-11) - -* motoko - - * Implement support for `heartbeat` system methods (thanks to ninegua) (#2971) - -* motoko-base - - * Add `Iter.filter : (Iter, A -> Bool) -> Iter` (thanks to jzxchiang1) (dfinity/motoko-base#328). - -## 0.6.19 (2022-01-05) - -* motoko-base - - * Fixed a bug in the `RBTree.size()` method. - -## 0.6.18 (2021-12-20) - -* moc - - * Add runtime support for low-level, direct access to 64-bit IC stable memory, including documentation. - * Add compiler flag `--max-stable-pages ` to cap any use of `ExperimentalStableMemory.mo` (see below), while reserving space for stable variables. - Defaults to 65536 (4GiB). - -* motoko-base - - * (Officially) add `ExperimentalStableMemory.mo` library, exposing 64-bit IC stable memory - -* BREAKING CHANGE (Minor): - The previously available (but unadvertised) `ExperimentalStableMemory.mo` used - `Nat32` offsets. This one uses `Nat64` offsets to (eventually) provide access to more address space. - -## 0.6.17 (2021-12-10) - -* Improved handling of one-shot messages facilitating zero-downtime - upgrades (#2938). -* Further performance improvements to the mark-compact garbage - collector (#2952, #2973). -* Stable variable checking for `moc.js` (#2969). -* A bug was fixed in the scoping checker (#2977). - -## 0.6.16 (2021-12-03) - -* Minor performance improvement to the mark-compact garbage collector - - -## 0.6.15 (2021-11-26) - -* Fixes crash when (ill-typed) `switch` expression on non-variant - value has variant alternatives (#2934) - -## 0.6.14 (2021-11-19) - -* The compiler now embeds the existing Candid interface and new - _stable signature_ of a canister in additional Wasm custom sections, - to be selectively exposed by the IC, and to be used by tools such as `dfx` - to verify upgrade compatibility (see extended documentation). - - New compiler options: - - * `--public-metadata `: emit ICP custom section `` (`candid:args` or `candid:service` or `motoko:stable-types`) as `public` (default is `private`) - * `--stable-types`: emit signature of stable types to `.most` file - * `--stable-compatible
 `: test upgrade compatibility between stable-type signatures  `
` and ``
-
-  A Motoko canister upgrade is safe provided:
-
-    * the canister's Candid interface evolves to a Candid subtype; and
-    * the canister's Motoko stable signature evolves to a _stable-compatible_ one.
-
-  (Candid subtyping can be verified using tool `didc` available at:
-   https://github.com/dfinity/candid.)
-
-* BREAKING CHANGE (Minor):
-  Tightened typing for type-annotated patterns (including function parameters)
-  to prevent some cases of unintended and counter-intuitive type propagation.
-
-  This may break some rare programs that were accidentally relying on that
-  propagation. For example, the indexing `xs[i]` in the following snippet
-  happend to type-check before, because `i` was given the more precise
-  type `Nat` (inferred from `run`'s parameter type), regardless of the
-  overly liberal declaration as an `Int`:
-
-  ```motoko
-  func run(f : Nat -> Text) {...};
-  let xs = ["a", "b", "c"];
-  run(func(i : Int) { xs[i] });
-  ```
-  This no longer works, `i` has to be declared as `Nat` (or the type omitted).
-
-  If you encounter such cases, please adjust the type annotation.
-
-* Improved garbage collection scheduling
-
-* Miscellaneous performance improvements
-  - code generation for `for`-loops over arrays has improved
-  - slightly sped up `Int` equality comparisons
-
-## 0.6.13 (2021-11-19)
-
-*Pulled*
-
-## 0.6.12 (2021-10-22)
-
-* `for` loops over arrays are now converted to more efficient
-  index-based iteration (#2831). This can result in significant cycle
-  savings for tight loops, as well as slightly less memory usage.
-
-* Add type union and intersection. The type expression
-
-  ```motoko
-  T and U
-  ```
-  produces the greatest lower bound of types `T` and `U`, that is,
-  the greatest type that is a subtype of both. Dually,
-
-  ```motoko
-  T or U
-  ```
-  produces the least upper bound of types `T` and `U`, that is,
-  the smallest type that is a supertype of both.
-
-  One use case of the former is "extending" an existing object type:
-
-  ``` motoko
-  type Person = {name : Text; address : Text};
-  type Manager = Person and {underlings : [Person]};
-  ```
-  Similarly, the latter can be used to "extend" a variant type:
-  ```motoko
-  type Workday = {#mon; #tue; #wed; #thu; #fri};
-  type Weekday = Workday or {#sat; #sun};
-  ```
-
-## 0.6.11 (2021-10-08)
-
-* Assertion error messages are now reproducible (#2821)
-
-## 0.6.10 (2021-09-23)
-
-* moc
-
-  * documentation changes
-
-* motoko-base
-
-  * documentation changes
-
-## 0.6.9 (2021-09-15)
-
-* motoko-base
-
-  * add Debug.trap : Text -> None (dfinity/motoko-base#288)
-
-## 0.6.8 (2021-09-06)
-
-* Introduce primitives for `Int` ⇔ `Float` conversions (#2733)
-* Bump LLVM toolchain to version 12 (#2542)
-* Support extended name linker sections (#2760)
-* Fix crashing bug for formatting huge floats (#2737)
-
-## 0.6.7 (2021-08-16)
-
-* moc
-
-  *  Optimize field access by exploiting field ordering (#2708)
-  *  Fix handling of self references in mark-compact GC (#2721)
-  *  Restore CI reporting of perf-regressions (#2643)
-
-* motoko-base:
-
-  * Fix bug in `AssocList.diff` (dfinity/motoko-base#277)
-  * Deprecate unsafe or redundant functions in library `Option` ( `unwrap`, `assertSome`, `assertNull`) (#275)
-
-## 0.6.6 (2021-07-30)
-
-* Vastly improved garbage collection scheduling: previously Motoko runtime would do GC
-  after every update message. We now schedule a GC when
-
-  1. Heap grows more than 50% and 10 MiB since the last GC, or
-  2. Heap size is more than 3 GiB
-
-  (1) is to make sure we don't do GC on tiny heaps or after only small amounts of allocation.
-  (2) is to make sure that on large heaps we will have enough allocation space during the next message.
-
-  This scheduling reduces cycles substantially, but may moderately increase memory usage.
-
-  New flag `--force-gc` restores the old behavior.
-
-* Fix bug in compacting gc causing unnecessary memory growth (#2673)
-
-* Trap on attempt to upgrade when canister not stopped and there are outstanding callbacks.
-  (This failure mode can be avoided by stopping the canister before upgrade.)
-
-* Fix issue #2640 (leaked `ClosureTable` entry when awaiting futures fails).
-
-## 0.6.5 (2021-07-08)
-
-* Add alternative, _compacting_ gc, enabled with new moc flag `--compacting-gc`.
-  The compacting gc supports larger heap sizes than the default, 2-space copying collector.
-
-  NOTE: Dfx 0.7.6 adds optional field `"args"` to `dfx.json` files,
-  so Motoko canisters can specify `moc` command-line arguments. E.g.,
-
-  ```json
-  ...
-     "type" : "motoko"
-     ...
-     "args" : "--compacting-gc"
-  ...
-  ```
-
-* Documentation fixes.
-* Command line tools: `--help` option provides better documentation of command line
-  options that have arguments.
-* Fix issue #2319 (crash on import of Candid class).
-
-## 0.6.4 (2021-06-12)
-
-* For release builds, the banner (`moc --version`) now includes the release
-  version.
-
-* Fix MacOS release builds (the 0.6.3 tarball for MacOS contained the linux binaries)
-
-## 0.6.3 (2021-06-10)
-
-* Motoko is now open source!
-
-* Better internal consistency checking of the intermediate representation
-
-## 0.6.2 (2021-05-24)
-
-* motoko-base:
-
-  * reformat to style guidelines
-  * add type bindings `Nat.Nat`, `Nat8.Nat8` etc. to libraries for primitive types.
-
-* Bugfix: generation of candid from Motoko:
-
-  * no longer confused by distinct, but eponymous, type definitions (Bug: #2529);
-  * numbers eponymous types and specializations from 1 (not 2);
-  * avoids long chains of type equalities by normalizing before translation.
-
-## 0.6.1 (2021-04-30)
-
-* Internal: Update to IC interface spec 0.17 (adapt to breaking change to signature of `create_canister`)
-
-## 0.6.0 (2021-04-16)
-
-* BREAKING CHANGE:
-  The old-style object and block syntax deprecated in 0.5.0 is finally removed.
-
-* Record punning: As already supported in patterns, short object syntax in
-  expressions now allows omitting the right-hand side if it is an identifier
-  of the same name as the label. That is,
-
-  ```motoko
-  {a; b = 1; var c}
-  ```
-
-  is short for
-
-  ```motoko
-  {a = a; b = 1; var c = c}
-  ```
-
-  assuming respective variables are in scope.
-
-* BREAKING CHANGE:
-  The types `Word8`, `Word16`, `Word32` and `Word64` have been removed.
-  This also removed the `blob.bytes()` iterator.
-
-  Motoko base also dropped the `Word8`, `Word16`, `Word32` and `Word64`
-  modules.
-
-  This concludes the transition to the other fixed-width types that began with
-  version 0.5.8
-
-* BREAKING CHANGE (Minor):
- `await` on a completed future now also commits state and suspends
-  computation, to ensure every await, regardless of its future's state,
-  is a commit point for state changes and tentative message sends.
-
-  (Previously, only awaits on pending futures would force a commit
-   and suspend, while awaits on completed futures would continue
-   execution without an incremental commit, trading safety for speed.)
-
-* motoko-base: fixed bug in `Text.compareWith`.
-
-## 0.5.15 (2021-04-13)
-
-* Bugfix: `Blob.toArray` was broken.
-
-## 0.5.14 (2021-04-09)
-
-* BREAKING CHANGE (Minor): Type parameter inference will no longer default
-  under-constrained type parameters that are invariant in the result, but
-  require an explicit type argument.
-  This is to avoid confusing the user by inferring non-principal types.
-
-  For example, given (invariant) class `Box`:
-
-  ```motoko
-    class Box(a : A) { public var value = a; };
-  ```
-
-  the code
-
-  ```motoko
-    let box = Box(0); // rejected
-  ```
-
-  is rejected as ambiguous and requires an instantiation, type annotation or
-  expected type. For example:
-
-  ```motoko
-    let box1 = Box(0); // accepted
-    let box2 : Box = Box(0); // accepted
-  ```
-
-  Note that types `Box` and `Box` are unrelated by subtyping,
-  so neither is best (or principal) in the ambiguous, rejected case.
-
-* Bugfix: Type components in objects/actors/modules correctly ignored
-  when involved in serialization, equality and `debug_show`, preventing
-  the compiler from crashing.
-
-* motoko-base: The `Text.hash` function was changed to a better one.
-  If you stored hashes as stable values (which you really shouldn't!)
-  you must rehash after upgrading.
-
-* motoko-base: Conversion functions between `Blob` and `[Nat8]` are provided.
-
-* When the compiler itself crashes, it will now ask the user to report the
-  backtrace at the DFINITY forum
-
-## 0.5.13 (2021-03-25)
-
-* The `moc` interpreter now pretty-prints values (as well as types) in the
-  repl, producing more readable output for larger values.
-
-* The family of `Word` types are deprecated, and mentioning them produces a warning.
-  These type will be removed completely in a subsequent release.
-  See the user’s guide, section “Word types”, for a migration guide.
-
-* motoko base: because of this deprecation, the `Char.from/toWord32()`
-  functions are removed. Migrate away from `Word` types, or use
-  `Word32.from/ToChar` for now.
-
-## 0.5.12 (2021-03-23)
-
-* The `moc` compiler now pretty-prints types in error messages and the repl,
-  producing more readable output for larger types.
-
-* motoko base: fixed bug in `Text.mo` affecting partial matches in,
-  for example, `Text.replace` (GH issue #234).
-
-## 0.5.11 (2021-03-12)
-
-* The `moc` compiler no longer rejects occurrences of private or
-  local type definitions in public interfaces.
-
-  For example,
-
-  ```motoko
-  module {
-    type List = ?(Nat, List); // private
-    public func cons(n : Nat, l : List) : List { ?(n , l) };
-  }
-  ```
-
-  is now accepted, despite `List` being private and appearing in the type
-  of public member `cons`.
-
-* Type propagation for binary operators has been improved. If the type of one of
-  the operands can be determined locally, then the other operand is checked
-  against that expected type. This should help avoiding tedious type annotations
-  in many cases of literals, e.g., `x == 0` or `2 * x`, when `x` has a special
-  type like `Nat8`.
-
-* The `moc` compiler now rejects type definitions that are non-_productive_ (to ensure termination).
-
-  For example, problematic types such as:
-
-  ```motoko
-  type C = C;
-  type D = D;
-  type E = F;
-  type F = E;
-  type G = Fst, Any>;
-  ```
-
-  are now rejected.
-
-* motoko base: `Text` now contains `decodeUtf8` and `encodeUtf8`.
-
-## 0.5.10 (2021-03-02)
-
-* User defined deprecations
-
-  Declarations in modules can now be annotated with a deprecation comment, which make the compiler emit warnings on usage.
-
-  This lets library authors warn about future breaking changes:
-
-  As an example:
-
-  ```motoko
-  module {
-    /// @deprecated Use `bar` instead
-    public func foo() {}
-
-    public func bar() {}
-  }
-  ```
-
-  will emit a warning whenever `foo` is used.
-
-* The `moc` compiler now rejects type definitions that are _expansive_, to help ensure termination.
-  For example, problematic types such as `type Seq = ?(T, Seq<[T]>)` are rejected.
-
-* motoko base: `Time.Time` is now public
-
-## 0.5.9 (2021-02-19)
-
-* The `moc` compiler now accepts the `-Werror` flag to turn warnings into errors.
-
-* The language server now returns documentation comments alongside
-  completions and hover notifications
-
-## 0.5.8 (2021-02-12)
-
-* Wrapping arithmetic and bit-wise operations on `NatN` and `IntN`
-
-  The conventional arithmetic operators on `NatN` and `IntN` trap on overflow.
-  If wrap-around semantics is desired, the operators `+%`, `-%`, `*%` and `**%`
-  can be used. The corresponding assignment operators (`+%=` etc.) are also available.
-
-  Likewise, the bit fiddling operators (`&`, `|`, `^`, `<<`, `>>`, `<<>`,
-  `<>>` etc.) are now also available on `NatN` and `IntN`. The right shift
-  operator (`>>`) is an unsigned right shift on `NatN` and a signed right shift
-  on `IntN`; the `+>>` operator is _not_ available on these types.
-
-  The motivation for this change is to eventually deprecate and remove the
-  `WordN` types.
-
-  Therefore, the wrapping arithmetic operations on `WordN` are deprecated and
-  their use will print a warning. See the user’s guide, section “Word types”,
-  for a migration guide.
-
-* For values `x` of type `Blob`, an iterator over the elements of the blob
-  `x.vals()` is introduced. It works like `x.bytes()`, but returns the elements
-  as type `Nat8`.
-
-* `mo-doc` now generates cross-references for types in signatures in
-  both the Html as well as the Asciidoc output. So a signature like
-  `fromIter : I.Iter -> List.List` will now let you click on
-  `I.Iter` or `List.List` and take you to their definitions.
-
-* Bugfix: Certain ill-typed object literals are now prevented by the type
-  checker.
-
-* Bugfix: Avoid compiler aborting when object literals have more fields than
-  their type expects.
-
-## 0.5.7 (2021-02-05)
-
-* The type checker now exploits the expected type, if any,
-  when typing object literal expressions.
-  So `{ x = 0 } : { x : Nat8 }` now works as expected
-  instead of requiring an additional type annotation on `0`.
-
-## 0.5.6 (2021-01-22)
-
-* The compiler now reports errors and warnings with an additional _error code_
-  This code can be used to look up a more detailed description for a given error by passing the `--explain` flag with a code to the compiler.
-  As of now this isn't going to work for most codes because the detailed descriptions still have to be written.
-* Internal: The parts of the RTS that were written in C have been ported to Rust.
-
-## 0.5.5 (2021-01-15)
-
-* new `moc` command-line arguments `--args ` and `--args0 ` for
-  reading newline/NUL terminated arguments from ``.
-* motoko base: documentation examples are executable in the browser
-
-## 0.5.4 (2021-01-07)
-
-* _Option blocks_ `do ? ` and _option checks_ ` !`.
-  Inside an option block, an option check validates that its operand expression is not `null`.
-  If it is, the entire option block is aborted and evaluates to `null`.
-  This simplifies consecutive null handling by avoiding verbose `switch` expressions.
-
-  For example, the expression `do? { f(x!, y!) + z!.a }` evaluates to `null` if either `x`, `y` or `z` is `null`;
-  otherwise, it takes the options' contents and ultimately returns `?r`, where `r` is the result of the addition.
-
-* BREAKING CHANGE (Minor):
-  The light-weight `do ` form of the recently added, more general `do ` form,
-  is no longer legal syntax.
-  That is, the argument to a `do` or `do ?` expression *must* be a block `{ ... }`,
-  never a simple expression.
-
-## 0.5.3 (2020-12-10)
-
-* Nothing new, just release moc.js to CDN
-
-## 0.5.2 (2020-12-04)
-
-* Bugfix: gracefully handle importing ill-typed actor classes
-
-## 0.5.1 (2020-11-27)
-
-* BREAKING CHANGE: Simple object literals of the form `{a = foo(); b = bar()}`
-  no longer bind the field names locally. This enables writing expressions
-  like `func foo(a : Nat) { return {x = x} }`.
-
-  However, this breaks expressions like `{a = 1; b = a + 1}`. Such object
-  shorthands now have to be written differently, e.g., with an auxiliary
-  declaration, as in `let a = 1; {a = a; b = a + 1}`, or by using the "long"
-  object syntax `object {public let a = 1; public let b = a + 1}`.
-
-## 0.5.0 (2020-11-27)
-
-* BREAKING CHANGE: Free-standing blocks are disallowed
-
-  Blocks are only allowed as sub-expressions of control flow expressions like
-  `if`, `loop`, `case`, etc. In all other places, braces are always considered
-  to start an object literal.
-
-  To use blocks in other positions, the new `do ` expression can be
-  used.
-
-  The more liberal syntax is still allowed for now but deprecated, i.e.,
-  produces a warning.
-
-* BREAKING CHANGE: actor creation is regarded as asynchronous:
-
-  * Actor declarations are asynchronous and can only be used in asynchronous
-    contexts.
-  * The return type of an actor class, if specified, must be an async actor
-    type.
-  * To support actor declaration, the top-level context of an interpreted
-    program is an asynchronous context, allowing implicit and explicit await
-    expressions.
-
-  (Though breaking, this change mostly affects interpreted programs and
-  compiled programs with explicate actor class return types)
-
-* Candid support is updated to latest changes of the Candid spec, in particular
-  the ability to extend function with optional parameters in a backward
-  compatible way.
-
-  Motoko passes the official Candid compliance test suite.
-
-* RTS: Injecting a value into an option type (`? `) no longer
-  requires heap allocation in most cases. This removes the memory-tax
-  of using iterators.
-
-* Bugfix: Passing cycles to the instantiation of an actor class works now.
-
-* Various bug fixes and documentation improvements.
-
-## 0.4.6 (2020-11-13)
-
-* Significant documentation improvements
-* Various bugfixes
-* Improved error messages
-* Initial DWARF support
-* Candid compliance improvements:
-  * Strict checking of utf8 strings
-  * More liberal parsing of leb128-encoded numbers
-* New motoko-base:
-  * The Random library is added
-
-## 0.4.5 (2020-10-06)
-
-* BREAKING CHANGE: a library containing a single actor class is
-  imported as a module, providing access to both the class type and
-  class constructor function as module components. Restores the
-  invariant that imported libraries are modules.
-* Backend: Compile captured actor class parameters statically (#2022)
-* flip the default for -g (#1546)
-* Bug fix: reject array indexing as non-static (could trap) (#2011)
-* Initialize tuple length fields (#1992)
-* Warns for structural equality on abstract types (#1972)
-* Funds Imperative API (#1922)
-* Restrict subtyping (#1970)
-* Continue labels always have unit codomain (#1975)
-* Compile.ml: target and use new builder call pattern (#1974)
-* fix scope var bugs (#1973)
-
-## 0.4.4 (2020-09-21)
-
-* Actor class export
-* Accept unit installation args for actors
-* Reject platform actor (class) programs with additional decs
-* Handle IO exceptions at the top-level
-* RTS: Remove duplicate array and blob allocation code
-* RTS: Fix pointer arithmetic in BigInt collection function
-
-## 0.4.3 (2020-09-14)
-
-* Preliminary support for actor class import and dynamic canister installation.
-  Surface syntax may change in future.
-* BREAKING CHANGE: a compilation unit/file defining an actor or actor class may *only* have leading `import` declarations; other leading declarations (e.g. `let` or `type`) are no longer supported.
-* Rust GC
-
-## 0.4.2 (2020-08-18)
-
-* Polymorphic equality.  `==` and `!=` now work on all shareable types.
-
-## 0.4.1 (2020-08-13)
-
-* Switching to bumping the third component of the version number
-* Bugfix: clashing declarations via function and class caught (#1756)
-* Bugfix: Candid `bool` decoding rejects invalid input (#1783)
-* Canisters can take installation arguments (#1809)
-  NB: Communicating the type of the canister installation methods is still
-  missing.
-* Optimization: Handling of `Bool` in the backend.
-
-## 0.4 (2020-08-03)
-
-* Candid pretty printer to use shorthand when possible (#1774)
-* fix candid import to use the new id format (#1787)
-
-## 0.3 (2020-07-31)
-
-* Fixes an issue with boolean encoding to Candid
-* Converts the style guide to asciidocs
-
-## 0.2 (2020-07-30)
-
-* The `Blob` type round-trips through candid type export/import (#1744)
-* Allow actor classes to know the caller of their constructor (#1737)
-* Internals: `Prim.time()` provided (#1747)
-* Performance: More dead code removal (#1752)
-* Performance: More efficient arithmetic with unboxed values (#1693, #1757)
-* Canister references are now parsed and printed according to the new
-  base32-based textual format (#1732).
-* The runtime is now embedded into `moc` and need not be distributed separately
-  (#1772)
-
-## 0.1 (2020-07-20)
-
-* Beginning of the changelog. Released with dfx-0.6.0.
-
-
diff --git a/docs/languages/motoko/reference/compiler-ref.md b/docs/languages/motoko/reference/compiler-ref.md
index 46505522..ed4ccf87 100644
--- a/docs/languages/motoko/reference/compiler-ref.md
+++ b/docs/languages/motoko/reference/compiler-ref.md
@@ -1,7 +1,8 @@
 ---
-sidebar_position: 15
-description: "Motoko language documentation"
 title: "Compiler reference"
+description: "The Motoko compiler (moc) is the primary tool for compiling Motoko programs into executable WebAssembly (Wasm) modules."
+sidebar:
+  order: 5
 ---
 
 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.
@@ -52,7 +53,7 @@ You can use the following options with the `moc` command.
 | `--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).                             |
-| `--implicit-derivation-depth `         | Maximum recursion depth for [implicit](/languages/motoko/fundamentals/implicit-parameters) argument derivation (default 100). Raise if a complex derivation is rejected as depth-limited.                                                                                                |
+| `--implicit-derivation-depth `         | Maximum recursion depth for [implicit](./fundamentals/11-implicit-parameters.md) argument derivation (default 100). Raise if a complex derivation is rejected as depth-limited.                                                                                                |
 | `--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).                                                        |
diff --git a/docs/languages/motoko/reference/error-codes.md b/docs/languages/motoko/reference/error-codes.md
index cab2c229..3dcfd960 100644
--- a/docs/languages/motoko/reference/error-codes.md
+++ b/docs/languages/motoko/reference/error-codes.md
@@ -1,7 +1,8 @@
 ---
-sidebar_position: 1
-description: "Motoko language documentation"
 title: "Error code reference"
+description: "Reference for Motoko compiler error codes with examples and explanations."
+sidebar:
+  order: 2
 ---
 
 
@@ -17,7 +18,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/actors/state). |
+| M0033 | Async has non-shared content type. | ```async { var counter = 0 }``` | Async blocks cannot contain mutable [state](../fundamentals/actors/state.md). |
 | 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 +34,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/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. |
+| M0090 | Actor reference must have an [actor](../fundamentals/actors/actors-async.md) type .| ```let a = actor { ... }; a.someMethod();``` | The variable `a` must have an explicit [actor](../fundamentals/actors/actors-async.md) 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 +45,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/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. |
+| M0149 | An immutable [record](../fundamentals/types/records.md) field (declared without `var`) was supplied where a mutable [record](../fundamentals/types/records.md) field (specified with `var`), was expected. | ```type Mutable = { var x : Nat }; func set(r : Mutable) { ... }; set({ x = 10 });``` | Immutable [record](../fundamentals/types/records.md) provided where mutable was expected. |
+| M0150 | A mutable [record](../fundamentals/types/records.md) field (declared with `var`) was supplied where an immutable [record](../fundamentals/types/records.md) 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
index d4364f0b..a73c193a 100644
--- a/docs/languages/motoko/reference/language-manual.md
+++ b/docs/languages/motoko/reference/language-manual.md
@@ -1,7 +1,8 @@
 ---
-sidebar_position: 16
-description: "Motoko language documentation"
 title: "Language reference"
+description: "Complete Motoko language reference covering syntax, types, expressions, declarations, and built-in operations."
+sidebar:
+  order: 1
 ---