From 85c03991ad29d8e0f82bfa47afeaca92bd2c19a4 Mon Sep 17 00:00:00 2001 From: Anders Christiansen Sørby Date: Thu, 06 Aug 2026 21:22:49 +0000 Subject: [PATCH] docs: update use/open and attribute examples to explicit {}/#[...] syntax Every code example across docs/src/*.md and AGENTS.md showing `use`/ `open` now uses explicit `{names}` (or `{}`/`{*}` where appropriate) instead of bare form, and every `@[...]` example is now `#[...]`, with a one-line note that the old spellings still parse but are deprecated. Matches the tree-wide source conversion from the previous two commits. Co-Authored-By: Claude Sonnet 5 --- AGENTS.md | 31 +++++++++++++++++-------------- docs/src/error-handling.md | 4 ++-- docs/src/getting-started.md | 8 ++++---- docs/src/instances.md | 4 ++-- docs/src/introduction.md | 10 +++++----- docs/src/io-monad.md | 30 +++++++++++++++--------------- docs/src/modules.md | 49 +++++++++++++++++++++++++++++-------------------- docs/src/reference.md | 30 +++++++++++++++++------------- 8 file(s) changed, 91 insertion(s)(+), 75 deletion(s)(-) diff --git a/AGENTS.md b/AGENTS.md --- a/AGENTS.md +++ b/AGENTS.md @@ -55,7 +55,7 @@ # Run with debug output cargo run -- run examples/hello.mo -- --debug -# Run @[test] annotated definitions +# Run #[test] annotated definitions cargo run -- test init/tests.mo # Run the bootstrapped cli in lang/main.mo @@ -428,31 +428,34 @@ ### Module Imports ```monad -// Load a module -use prelude -use io +// Load a module, listing exactly the names needed +use io {IO} // Open namespace. Make defs available without given prefix. -open IO +open IO {println} ``` + +`{*}` imports/opens everything explicitly; a bare `use`/`open` (no braces) still parses but is deprecated in favor of an explicit filter. ### Native Functions -Call Rust functions from Monad using the `@[native "..."]` attribute: +Call Rust functions from Monad using the `#[native "..."]` attribute: ```monad -@[native "add"] +#[native "add"] def add (a: I64) (b: I64) : I64 ``` ## Attributes -Declarations can be annotated with `@[...]` attributes: +Declarations can be annotated with `#[...]` attributes: ```monad -@[native "function_name"] // Declare a Rust-native function -@[test] // Mark as a test (run via `cargo run -- test `) +#[native "function_name"] // Declare a Rust-native function +#[test] // Mark as a test (run via `cargo run -- test `) ``` + +`@[...]` is the older spelling of the same syntax — it still parses, but the compiler warns and suggests `#[...]` instead. ## Operators @@ -536,14 +539,14 @@ # Run tests from a single file cargo run -- test init/tests.mo -# Run tests from an entire directory (recursively finds all .mo files with @[test]) +# Run tests from an entire directory (recursively finds all .mo files with #[test]) cargo run -- test init/ # Run all test suites cargo run -- test init/ && cargo run -- test examples/ ``` -The test runner supports both files and directories. When given a directory, it recursively scans for `.mo` files and runs any definitions annotated with `@[test]`, reporting pass/fail. +The test runner supports both files and directories. When given a directory, it recursively scans for `.mo` files and runs any definitions annotated with `#[test]`, reporting pass/fail. ### Pre-commit @@ -581,7 +584,7 @@ 1. Add Rust implementation in `core/src/eval/native.rs` 2. Declare in a `.mo` file: ```monad -@[native "function_name"] +#[native "function_name"] def function_name (args: Types) : ReturnType ``` @@ -945,7 +948,7 @@ 1. **Add a parser test** (`core/src/parser/test/`) if the bug involves syntax 2. **Add an eval test** (`core/src/eval/test.rs`) if the bug involves evaluation -3. **Add a Monad test** — use `@[test]` in: +3. **Add a Monad test** — use `#[test]` in: - `init/tests.mo` for bugs involving core language semantics (prelude types, operators, etc.) - `std/_test.mo` for bugs in `std/` modules (concurrency, collections, etc.) - Never add `std/`-dependent tests to `init/tests.mo` — `init/` must not depend on `std/` diff --git a/docs/src/error-handling.md b/docs/src/error-handling.md --- a/docs/src/error-handling.md +++ b/docs/src/error-handling.md @@ -103,8 +103,8 @@ Error handling in effectful code: ```monad -use io -open IO +use io {IO} +open IO {println} def main (args : List String) : IO Unit := match List.first args { diff --git a/docs/src/getting-started.md b/docs/src/getting-started.md --- a/docs/src/getting-started.md +++ b/docs/src/getting-started.md @@ -13,8 +13,8 @@ Let's start with the classic "Hello, World!" program: ```monad -use io -open IO +use io {IO} +open IO {println} def main (args : List String) : IO Unit := println "Hello, World!" ``` @@ -149,8 +149,8 @@ Monad supports infix operators with defined precedence: ```monad -use init -use math +use init {} +use math {} def result : I64 := 3 + 4 * 2 // 11 (multiplication binds tighter) ``` diff --git a/docs/src/instances.md b/docs/src/instances.md --- a/docs/src/instances.md +++ b/docs/src/instances.md @@ -72,8 +72,8 @@ Once an instance is defined, its methods are available through the class: ```monad -use init -use math +use init {} +use math {} def result : I64 := 3 + 4 // Uses I64.add via Add instance ``` diff --git a/docs/src/introduction.md b/docs/src/introduction.md --- a/docs/src/introduction.md +++ b/docs/src/introduction.md @@ -14,8 +14,8 @@ Here is a simple example: ```monad -use io -open IO +use io {IO} +open IO {println} def main (args : List String) : IO Unit := println "Hello, World!" ``` @@ -38,9 +38,9 @@ ## Quick Example ```monad -use io -use init -open IO +use io {IO} +use init {} +open IO {println} def factorial (n : I64) : I64 := if n == 0 diff --git a/docs/src/io-monad.md b/docs/src/io-monad.md --- a/docs/src/io-monad.md +++ b/docs/src/io-monad.md @@ -7,8 +7,8 @@ `IO A` represents a computation that, when executed, produces an `A` and may have side effects: ```monad -use io -open IO +use io {IO} +open IO {println} def main (args : List String) : IO Unit := println "Hello, World!" ``` @@ -18,8 +18,8 @@ ### Printing Output ```monad -use io -open IO +use io {IO} +open IO {println} def main (args : List String) : IO Unit := println "Hello, World!" @@ -56,8 +56,8 @@ ### Standard `do { ... }` syntax ```monad -use io -open IO +use io {IO} +open IO {println} def greet : IO Unit := do { @@ -72,8 +72,8 @@ Functions can use `{ ... }` directly instead of `:= do { ... }`: ```monad -use io -open IO +use io {IO} +open IO {println} def greet : IO Unit { println "Enter your name:" @@ -110,19 +110,19 @@ IO operations are implemented as native functions that call Rust code: ```monad -@[native println] +#[native println] def IO.println (s : String) : IO Unit ``` -The `@[native name]` attribute marks a function as implemented in Rust. +The `#[native name]` attribute marks a function as implemented in Rust. ## Running IO Programs The runtime executes the `main` function: ```monad -use io -open IO +use io {IO} +open IO {println} def main (args : List String) : IO Unit := println "Starting..." @@ -139,9 +139,9 @@ ## Combining IO with Other Types ```monad -use io -use init -open IO +use io {IO} +use init {} +open IO {println} def printResult (r : Result String I64) : IO Unit := match r { diff --git a/docs/src/modules.md b/docs/src/modules.md --- a/docs/src/modules.md +++ b/docs/src/modules.md @@ -8,44 +8,48 @@ ## Importing Modules -Use `use` to bring a module into scope: +Use `use` to bring a module into scope, listing exactly the names you need in `{...}`: ```monad -use io -use init -use math +use io {IO} +use init {IO} +use math {} ``` -After `use io`, you can access definitions with their full path: +An empty `{}` still imports the module (for qualified access) without bringing any bare names into scope. + +After `use io {...}`, you can access definitions with their full path: ```monad -use io +use io {IO} def main (args : List String) : IO Unit := IO.println "Hello" ``` +Bare `use io` (no braces) still parses but is deprecated — the compiler warns and suggests `use io {*}`. + ## Opening Modules -Use `open` to make a module's definitions available without prefixes: +Use `open` to make a module's definitions available without prefixes, again naming exactly what you need: ```monad -use io -open IO +use io {IO} +open IO {println} def main (args : List String) : IO Unit := println "Hello" ``` -Now `println` is available directly instead of `IO.println`. +Now `println` is available directly instead of `IO.println`. Like `use`, a bare `open IO` (no braces) still parses but is deprecated in favor of an explicit filter — `open IO {*}` if you genuinely need everything. ## Opening Standard Types The prelude opens several types by default: ```monad -open Unit // makes `unit` available -open Bool // makes `true`, `false` available -open Result // makes `ok`, `err` available -open Option // makes `some`, `none` available +open Unit {unit} // makes `unit` available +open Bool {and, false, not, or, true} +open Result {err, ok} +open Option {none, some} ``` ## Module Paths @@ -53,7 +57,7 @@ Definitions are accessed using dot notation: ```monad -use init +use init {} def result : I64 := I64.add 3 4 ``` @@ -77,9 +81,9 @@ ## Complete Example ```monad -use io -use init -open IO +use io {IO} +use init {} +open IO {println} def say_hello (s : String) : IO Unit := println s @@ -90,11 +94,16 @@ |> say_hello ``` +## Unused Imports + +The compiler warns when an explicitly-listed `use`/`open` name is never referenced in the file — remove it, or run `monad-rs organize-imports --write` to have the compiler rewrite (and, where a `use` contributes nothing at all, delete) the declaration for you. + ## Summary - Each `.mo` file is a module -- `use` brings modules into scope -- `open` makes definitions available without prefixes +- `use Module {names}` brings a module into scope, selecting exactly which names become bare-accessible +- `open Module {names}` makes definitions available without prefixes +- `{*}` imports/opens everything explicitly; bare `use`/`open` (no braces) still works but is deprecated - Dot notation accesses definitions by path - Standard library modules provide common functionality diff --git a/docs/src/reference.md b/docs/src/reference.md --- a/docs/src/reference.md +++ b/docs/src/reference.md @@ -157,29 +157,31 @@ ## Attributes -Declarations can be annotated with `@[...]` attributes: +Declarations can be annotated with `#[...]` attributes: ```monad -@[native "function_name"] // Declare a Rust-native function -@[test] // Mark as a test (run via `cargo run -- test `) +#[native "function_name"] // Declare a Rust-native function +#[test] // Mark as a test (run via `cargo run -- test `) ``` + +`@[...]` is the older spelling of the same syntax — it still parses, but the compiler warns and suggests `#[...]` instead. ## Native Functions Mark functions as implemented in Rust: ```monad -@[native nativeName] +#[native nativeName] def functionName (params) : ReturnType ``` Example from the standard library: ```monad -@[native println] +#[native println] def IO.println (s : String) : IO Unit -@[native num_add] +#[native num_add] def I64.add (a b : I64) : I64 ``` @@ -297,22 +299,24 @@ } // Native function -@[native println] +#[native println] def IO.println (s : String) : IO Unit ``` ## Modules ```monad -// Import module -use io +// Import module, listing exactly the names needed +use io {IO} -// Open module (no prefix needed) -open IO +// Open module (no prefix needed), same explicit-names convention +open IO {println} -// Access by path +// Access by path — always works, whether or not a name is also open'd IO.println "hello" ``` + +`{*}` imports/opens everything; a bare `use`/`open` with no braces at all still parses but is deprecated in favor of an explicit filter. ## Dot Macro @@ -410,7 +414,7 @@ # Run with debug output cargo run -- run file.mo -- --debug -# Run @[test] annotated definitions +# Run #[test] annotated definitions cargo run -- test file.mo # Compile to native binary (requires llvm feature) -- tangled.sh