From 34a4f7bdd86d3e06595670b4a5b4b0ca28e452e2 Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Sat, 31 Jan 2026 11:48:07 +0100 Subject: [PATCH 1/3] idiomatic: remove weasel words --- .../meaningful-doc-comments.md | 2 +- .../meaningful-doc-comments/avoid-redundancy.md | 4 ++-- .../meaningful-doc-comments/exercise.md | 6 +++--- .../predictable-api/common-traits/serde.md | 4 ++-- .../naming-conventions/as-and-ref.md | 4 ++-- .../predictable-api/naming-conventions/by.md | 2 +- .../predictable-api/naming-conventions/from.md | 4 ++-- .../predictable-api/naming-conventions/get.md | 2 +- .../naming-conventions/into_inner.md | 6 +++--- .../predictable-api/naming-conventions/to.md | 6 +++--- .../naming-conventions/with-constructor.md | 4 ++-- src/idiomatic/leveraging-the-type-system.md | 13 ++++++------- .../borrow-checker-invariants.md | 6 +++--- .../generalizing-ownership.md | 4 ++-- .../phantomdata-03-lifetimes.md | 4 ++-- .../leveraging-the-type-system/extension-traits.md | 5 +++-- .../leveraging-the-type-system/newtype-pattern.md | 2 +- src/idiomatic/leveraging-the-type-system/raii.md | 6 +++--- .../leveraging-the-type-system/raii/drop_bomb.md | 4 ++-- .../token-types/branded-02-phantomdata.md | 2 +- .../polymorphism/from-oop-to-rust/composition.md | 2 +- .../dynamic-dispatch/dyn-compatible.md | 4 ++-- .../from-oop-to-rust/dynamic-dispatch/pitfalls.md | 4 ++-- .../polymorphism/refresher/trait-bounds.md | 4 ++-- src/idiomatic/welcome.md | 4 ++-- 25 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/idiomatic/foundations-api-design/meaningful-doc-comments.md b/src/idiomatic/foundations-api-design/meaningful-doc-comments.md index 2da5ff7c867d..0c31ac32239c 100644 --- a/src/idiomatic/foundations-api-design/meaningful-doc-comments.md +++ b/src/idiomatic/foundations-api-design/meaningful-doc-comments.md @@ -17,7 +17,7 @@ fn connect() -> Result<(), Error> {...}
-- Doc comments are the most common form of documentation developers engage with. +- Doc comments are the primary form of documentation developers engage with. - Good doc comments provide information that the code, names, and types cannot, without restating the obvious information. diff --git a/src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md b/src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md index 2aefebaf5558..b0a1db431c07 100644 --- a/src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +++ b/src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md @@ -4,8 +4,8 @@ minutes: 15 # Avoiding Redundancy -Names and type signatures communicate a lot of information, don't repeat it in -comments! +Names and type signatures communicate significant information, don't repeat it +in comments! ```rust,compile_fail // Repeats name/type information. Can omit! diff --git a/src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md b/src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md index 1d34a702b12b..aadff518b277 100644 --- a/src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +++ b/src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md @@ -39,9 +39,9 @@ fn sort_quickly(to_sort: &mut [T]) { ... } - Ask the class: Now we have more detail, how should we comment this function? - The point being implementation detail vs not depends a lot on what the public - contract is (e.g., can you supply untrusted data or not), and this requires - careful judgement. + The point being implementation detail vs not depends significantly on what the + public contract is (e.g., can you supply untrusted data or not), and this + requires careful judgement. Consider if a comment is explaining that a for-loop is used (unnecessary detail) or if it is explaining that the algorithms used internally have known diff --git a/src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md b/src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md index c37ca609e9e1..c7b2880bfa11 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md +++ b/src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md @@ -32,7 +32,7 @@ struct Data { erroneously saved to disk or sent over a network, consider not implementing Serialize/Deserialize for that type. - Shares security concerns with `Debug`, but given serialization is often used - in networking there can be higher stakes. + Shares security concerns with `Debug`, but given serialization is frequently + used in networking there can be higher stakes.
diff --git a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md index e316c8306572..23cc408fdeac 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +++ b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md @@ -36,8 +36,8 @@ impl OwnedFd { - Method that returns a borrow of the primary piece of contained data. -- The borrowing relationship is most often straightforward: the return value is - a reference that borrows `self`. +- The borrowing relationship is typically straightforward: the return value is a + reference that borrows `self`. - Borrowing can also be subtle, and merely implied. diff --git a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md index 7a980900c650..61a657eb95a0 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +++ b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md @@ -43,7 +43,7 @@ data. `sort_by` takes a comparator function directly. -- Most often seen in methods that sort or otherwise manipulate a slice with a +- Commonly seen in methods that sort or otherwise manipulate a slice with a custom sort or comparison function rather than by the `Ord` implementation of the type itself. diff --git a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md index cd9dc2501286..baa2419e7429 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md +++ b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md @@ -31,8 +31,8 @@ impl u32 {
- Prefix for constructor-style, `From`-trait-style functions. -- These functions can take multiple arguments, but usually imply the user is - doing more of the work than a usual constructor would. +- These functions can take multiple arguments, but imply the user is expected to + provide the data that the type is composed of. `new` is still preferred for most constructor-style functions, the implication for `from` is transformation of one data type to another. diff --git a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/get.md b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/get.md index 2e4bdc1cd890..08e2d9986bad 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/get.md +++ b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/get.md @@ -19,7 +19,7 @@ impl OnceCell {
- Gets are trivial, they get a value! -Immutable by default, for the most part. +Immutable by default. Should not panic. May return an option or result, depending on the framework. diff --git a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md index 3d5511b7898d..7fa831c4aeab 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md +++ b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md @@ -27,9 +27,9 @@ impl Cell {
-- `into_inner` is a method usually found on newtypes: types whose main purpose - is to wrap around an existing type and be semantically distinct from other - uses of that inner type. +- `into_inner` is a method found on newtypes: types whose main purpose is to + wrap around an existing type and be semantically distinct from other uses of + that inner type. This kind of method is also found on types like `Cell`, which exclusively own the internal data. diff --git a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md index 2a019eca44bd..b60a41bc13c4 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +++ b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md @@ -30,9 +30,9 @@ impl u32 { non-trivial type conversion, or even a data transformation. For example, `str::to_uppercase`. -- "to" methods most commonly take `&self`. However they can take `self` by value - if the type implements `Copy`: this also ensures that the conversion method - call does not consume `self`. +- "to" methods take `&self`. However they can take `self` by value if the type + implements `Copy`: this also ensures that the conversion method call does not + consume `self`. - If you simply want to define a method that takes `&self` and returns an owned value of the same type, implement the `Clone` trait. diff --git a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md index 3e92fdfe86f1..597d2e98103a 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md +++ b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md @@ -18,8 +18,8 @@ impl Vec {
-- `with` can appear as a constructor prefix, most commonly when initializing - heap memory for container types. +- `with` can appear as a constructor prefix, typically when initializing heap + memory for container types. In this case, it's distinct from `new` constructors because it specifies the value for something that is not usually cared about by API users. diff --git a/src/idiomatic/leveraging-the-type-system.md b/src/idiomatic/leveraging-the-type-system.md index d7a871b4b69b..f70ce00d5d48 100644 --- a/src/idiomatic/leveraging-the-type-system.md +++ b/src/idiomatic/leveraging-the-type-system.md @@ -7,8 +7,8 @@ minutes: 5 Rust's type system is _expressive_: you can use types and traits to build abstractions that make your code harder to misuse. -In some cases, you can go as far as enforcing correctness at _compile-time_, -with no runtime overhead. +It is possible to enforce correctness at _compile-time_, with no runtime +overhead. Types and traits can model concepts and constraints from your business domain. With careful design, you can improve the clarity and maintainability of the @@ -18,8 +18,7 @@ entire codebase. Additional items speaker may mention: -- Rust's type system borrows a lot of ideas from functional programming - languages. +- Rust's type system borrows ideas from functional programming languages. For example, Rust's enums are known as "algebraic data types" in languages like Haskell and OCaml. You can take inspiration from learning material geared @@ -42,9 +41,9 @@ Additional items speaker may mention: doesn't support inheritance, and object decomposition should take into account the constraints introduced by the borrow checker. -- Mention that type-level programming can be often used to create "zero-cost - abstractions", although the label can be misleading: the impact on compile - times and code complexity may be significant. +- Mention that type-level programming creates "zero-cost abstractions", although + the label can be misleading: the impact on compile times and code complexity + may be significant.
diff --git a/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md b/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md index 6d3399cc3db5..f4a795272dd1 100644 --- a/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +++ b/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md @@ -59,7 +59,7 @@ fn main() { - We've also used types to shape and restrict APIs already using [the Typestate pattern](../leveraging-the-type-system/typestate-pattern.md). -- Language features are often introduced for a specific purpose. +- Language features are frequently introduced for a specific purpose. Over time, users may develop ways of using a feature in ways that were not predicted when they were introduced. @@ -67,8 +67,8 @@ fn main() { Java 5 introduced Generics in 2004 with the [main stated purpose of enabling type-safe collections](https://jcp.org/en/jsr/detail?id=14). - Adoption was slow at first, but some new projects began designing their APIs - around generics from the beginning. + Adoption was slow at first, but several new projects began designing their + APIs around generics from the beginning. Since then, users and developers of the language expanded the use of generics to other areas of type-safe API design: diff --git a/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md b/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md index 6e77915cdded..afe1c5fa6bfc 100644 --- a/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +++ b/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md @@ -63,10 +63,10 @@ fn demo_denied() { `shared_again_again` reference is taken from `&value`. - Remember that every `&T` and `&mut T` has a lifetime, just one the user - doesn't have to annotate or think about most of the time. + doesn't have to annotate or think about typically. We rarely specify lifetimes because the Rust compiler allows us to _elide_ - them in most cases. See: + them in the majority of cases. See: [Lifetime Elision](../../../lifetimes/lifetime-elision.md)
diff --git a/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md b/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md index 7896e62ef2bb..895a2245bb9d 100644 --- a/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +++ b/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md @@ -4,8 +4,8 @@ minutes: 15 # PhantomData 3/4: Lifetimes for External Resources -The invariants of external resources often match what we can do with lifetime -rules. +The invariants of external resources typically match what we can do with +lifetime rules. ```rust,editable // use std::marker::PhantomData; diff --git a/src/idiomatic/leveraging-the-type-system/extension-traits.md b/src/idiomatic/leveraging-the-type-system/extension-traits.md index 5a32674a9c84..9595d34d9559 100644 --- a/src/idiomatic/leveraging-the-type-system/extension-traits.md +++ b/src/idiomatic/leveraging-the-type-system/extension-traits.md @@ -38,7 +38,8 @@ pattern** to work around this limitation. Highlight how the compiler error message nudges you towards the extension trait pattern. -- Explain how many type-system restrictions in Rust aim to prevent _ambiguity_. +- Explain how the numerous type-system restrictions in Rust aim to prevent + _ambiguity_. What would happen if you were allowed to define new inherent methods on foreign types? Different crates in your dependency tree might end up defining @@ -57,7 +58,7 @@ pattern** to work around this limitation. new inherent methods on foreign types. - Other languages (e.g, Kotlin, C#, Swift) allow adding methods to existing - types, often called "extension methods." This leads to different trade-offs in + types, known as "extension methods." This leads to different trade-offs in terms of potential ambiguities and the need for global reasoning.
diff --git a/src/idiomatic/leveraging-the-type-system/newtype-pattern.md b/src/idiomatic/leveraging-the-type-system/newtype-pattern.md index 330e465b5bad..3aa89bef8718 100644 --- a/src/idiomatic/leveraging-the-type-system/newtype-pattern.md +++ b/src/idiomatic/leveraging-the-type-system/newtype-pattern.md @@ -4,7 +4,7 @@ minutes: 5 # Newtype Pattern -A _newtype_ is a wrapper around an existing type, often a primitive: +A _newtype_ is a wrapper around an existing type, typically a primitive: ```rust /// A unique user identifier, implemented as a newtype around `u64`. diff --git a/src/idiomatic/leveraging-the-type-system/raii.md b/src/idiomatic/leveraging-the-type-system/raii.md index 25eec34cdb16..48ff2b4a8420 100644 --- a/src/idiomatic/leveraging-the-type-system/raii.md +++ b/src/idiomatic/leveraging-the-type-system/raii.md @@ -82,9 +82,9 @@ fn main() -> Result<(), std::io::Error> { The `Drop` trait has another important limitation: it is not `async`. -This means you cannot `await` inside a destructor, which is often needed when -cleaning up asynchronous resources like sockets, database connections, or tasks -that must signal completion to another system. +This means you cannot `await` inside a destructor, which is frequently needed +when cleaning up asynchronous resources like sockets, database connections, or +tasks that must signal completion to another system. - Learn more: diff --git a/src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md b/src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md index 47272298fee6..43762a0293c1 100644 --- a/src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +++ b/src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md @@ -7,7 +7,7 @@ minutes: 15 Use `Drop` to enforce invariants and detect incorrect API usage. A "drop bomb" panics if a value is dropped without being explicitly finalized. -This pattern is often used when the finalizing operation (like `commit()` or +This pattern is commonly used when the finalizing operation (like `commit()` or `rollback()`) needs to return a `Result`, which cannot be done from `Drop`. ```rust,editable @@ -57,7 +57,7 @@ fn main() -> io::Result<()> { in an unfinished state. The destructor panics if the transaction has not been explicitly finalized (for example, with `commit()`). -- The finalizing operation (such as `commit()`) usually takes `self` by value. +- The finalizing operation (such as `commit()`) typically takes `self` by value. This ensures that once the transaction is finalized, the original object can no longer be used. diff --git a/src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md b/src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md index e2a33b2c564b..59752578d997 100644 --- a/src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +++ b/src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md @@ -53,7 +53,7 @@ fn main() { This is useful in many cases, as it means two different lifetimes can be treated as if they were the same in the regions they do overlap. - This is usually what we want. But here we want to use lifetimes as a way to + This is typically what we want. But here we want to use lifetimes as a way to distinguish values so we say that a token only applies to a single variable without having to create a newtype for every single variable we declare. diff --git a/src/idiomatic/polymorphism/from-oop-to-rust/composition.md b/src/idiomatic/polymorphism/from-oop-to-rust/composition.md index 3324813d1974..a47f4cc666a5 100644 --- a/src/idiomatic/polymorphism/from-oop-to-rust/composition.md +++ b/src/idiomatic/polymorphism/from-oop-to-rust/composition.md @@ -26,7 +26,7 @@ pub struct User { different types. This has downsides, largely in ergonomics of field access, but gives - developers a lot of control and clarity over what a type does and it has + developers significant control and clarity over what a type does and it has access to. - When deriving traits, make sure all the field types of a struct or variant diff --git a/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md b/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md index f81f3d34e0a2..a27498e9ff73 100644 --- a/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +++ b/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md @@ -27,8 +27,8 @@ pub trait Trait { - This was previously called _object safe traits_ or _object safety_. -- Dynamic dispatch offloads a lot of compile-time type information into runtime - vtable information. +- Dynamic dispatch offloads significant compile-time type information into + runtime vtable information. If a concept is incompatible with what we can meaningfully store in a vtable, either the trait stops being dyn compatible or those methods are excluded from diff --git a/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md b/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md index eb83e51fa0fc..b88a17b1c488 100644 --- a/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +++ b/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md @@ -42,8 +42,8 @@ fn main() { - The above example takes things to the absurd: If adding numbers were tied up in the dynamic dispatch process, it would be difficult to do anything at all. - But dynamic dispatch is often hidden in a lot of programming languages: here's - it is more explicit. + But dynamic dispatch is often hidden in many programming languages: here's it + is more explicit. In the `i32` implementation of `AddDyn`, first we need to attempt to downcast the `rhs` argument to the same type as `i32`, silently failing if this isn't diff --git a/src/idiomatic/polymorphism/refresher/trait-bounds.md b/src/idiomatic/polymorphism/refresher/trait-bounds.md index bb6db4fe529d..ae99bb0a3411 100644 --- a/src/idiomatic/polymorphism/refresher/trait-bounds.md +++ b/src/idiomatic/polymorphism/refresher/trait-bounds.md @@ -23,8 +23,8 @@ fn main() {
-- Traits are most commonly used as bounds on generic type parameters for a - function or method. +- Traits are typically used as bounds on generic type parameters for a function + or method. Without a trait bound on a generic type parameter, we don't have access to any behavior to write functions and methods with. diff --git a/src/idiomatic/welcome.md b/src/idiomatic/welcome.md index efe7499269bf..3b64dfcbea96 100644 --- a/src/idiomatic/welcome.md +++ b/src/idiomatic/welcome.md @@ -49,8 +49,8 @@ languages like Swift, Kotlin, C#, or TypeScript. in the standard library - e.g., methods should be called "push" not "push_back", "is_empty" not "empty" etc.) - Know the vocabulary types and traits in the standard library, and use them - in your APIs. If something feels like a basic type/algorithm, check in the - standard library first. + in your APIs. If something appears to be a basic type/algorithm, check in + the standard library first! - Use well-established API design patterns that we will discuss later in this class (e.g., newtype, owned/view type pairs, error handling) - Write meaningful and effective doc comments (e.g., don't merely repeat the From 3b8d8478ba645db98ca4d2347f2a25074a693e0d Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Sat, 14 Feb 2026 11:27:50 +0100 Subject: [PATCH 2/3] idiomatic: revert non-significant changes --- .../meaningful-doc-comments.md | 2 +- .../meaningful-doc-comments/avoid-redundancy.md | 4 ++-- .../meaningful-doc-comments/exercise.md | 6 +++--- .../predictable-api/common-traits/serde.md | 4 ++-- .../naming-conventions/as-and-ref.md | 4 ++-- .../predictable-api/naming-conventions/by.md | 2 +- .../naming-conventions/with-constructor.md | 4 ++-- src/idiomatic/leveraging-the-type-system.md | 13 +++++++------ .../borrow-checker-invariants.md | 6 +++--- .../generalizing-ownership.md | 4 ++-- .../phantomdata-03-lifetimes.md | 4 ++-- .../leveraging-the-type-system/extension-traits.md | 5 ++--- .../leveraging-the-type-system/newtype-pattern.md | 2 +- src/idiomatic/leveraging-the-type-system/raii.md | 6 +++--- .../leveraging-the-type-system/raii/drop_bomb.md | 4 ++-- .../token-types/branded-02-phantomdata.md | 2 +- .../polymorphism/from-oop-to-rust/composition.md | 2 +- .../dynamic-dispatch/dyn-compatible.md | 4 ++-- .../from-oop-to-rust/dynamic-dispatch/pitfalls.md | 4 ++-- .../polymorphism/refresher/trait-bounds.md | 4 ++-- src/idiomatic/welcome.md | 4 ++-- 21 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/idiomatic/foundations-api-design/meaningful-doc-comments.md b/src/idiomatic/foundations-api-design/meaningful-doc-comments.md index 0c31ac32239c..2da5ff7c867d 100644 --- a/src/idiomatic/foundations-api-design/meaningful-doc-comments.md +++ b/src/idiomatic/foundations-api-design/meaningful-doc-comments.md @@ -17,7 +17,7 @@ fn connect() -> Result<(), Error> {...}
-- Doc comments are the primary form of documentation developers engage with. +- Doc comments are the most common form of documentation developers engage with. - Good doc comments provide information that the code, names, and types cannot, without restating the obvious information. diff --git a/src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md b/src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md index b0a1db431c07..2aefebaf5558 100644 --- a/src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +++ b/src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md @@ -4,8 +4,8 @@ minutes: 15 # Avoiding Redundancy -Names and type signatures communicate significant information, don't repeat it -in comments! +Names and type signatures communicate a lot of information, don't repeat it in +comments! ```rust,compile_fail // Repeats name/type information. Can omit! diff --git a/src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md b/src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md index aadff518b277..1d34a702b12b 100644 --- a/src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +++ b/src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md @@ -39,9 +39,9 @@ fn sort_quickly(to_sort: &mut [T]) { ... } - Ask the class: Now we have more detail, how should we comment this function? - The point being implementation detail vs not depends significantly on what the - public contract is (e.g., can you supply untrusted data or not), and this - requires careful judgement. + The point being implementation detail vs not depends a lot on what the public + contract is (e.g., can you supply untrusted data or not), and this requires + careful judgement. Consider if a comment is explaining that a for-loop is used (unnecessary detail) or if it is explaining that the algorithms used internally have known diff --git a/src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md b/src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md index c7b2880bfa11..c37ca609e9e1 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md +++ b/src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md @@ -32,7 +32,7 @@ struct Data { erroneously saved to disk or sent over a network, consider not implementing Serialize/Deserialize for that type. - Shares security concerns with `Debug`, but given serialization is frequently - used in networking there can be higher stakes. + Shares security concerns with `Debug`, but given serialization is often used + in networking there can be higher stakes.
diff --git a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md index 23cc408fdeac..e316c8306572 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +++ b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md @@ -36,8 +36,8 @@ impl OwnedFd { - Method that returns a borrow of the primary piece of contained data. -- The borrowing relationship is typically straightforward: the return value is a - reference that borrows `self`. +- The borrowing relationship is most often straightforward: the return value is + a reference that borrows `self`. - Borrowing can also be subtle, and merely implied. diff --git a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md index 61a657eb95a0..7a980900c650 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +++ b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md @@ -43,7 +43,7 @@ data. `sort_by` takes a comparator function directly. -- Commonly seen in methods that sort or otherwise manipulate a slice with a +- Most often seen in methods that sort or otherwise manipulate a slice with a custom sort or comparison function rather than by the `Ord` implementation of the type itself. diff --git a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md index 597d2e98103a..3e92fdfe86f1 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md +++ b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md @@ -18,8 +18,8 @@ impl Vec {
-- `with` can appear as a constructor prefix, typically when initializing heap - memory for container types. +- `with` can appear as a constructor prefix, most commonly when initializing + heap memory for container types. In this case, it's distinct from `new` constructors because it specifies the value for something that is not usually cared about by API users. diff --git a/src/idiomatic/leveraging-the-type-system.md b/src/idiomatic/leveraging-the-type-system.md index f70ce00d5d48..d7a871b4b69b 100644 --- a/src/idiomatic/leveraging-the-type-system.md +++ b/src/idiomatic/leveraging-the-type-system.md @@ -7,8 +7,8 @@ minutes: 5 Rust's type system is _expressive_: you can use types and traits to build abstractions that make your code harder to misuse. -It is possible to enforce correctness at _compile-time_, with no runtime -overhead. +In some cases, you can go as far as enforcing correctness at _compile-time_, +with no runtime overhead. Types and traits can model concepts and constraints from your business domain. With careful design, you can improve the clarity and maintainability of the @@ -18,7 +18,8 @@ entire codebase. Additional items speaker may mention: -- Rust's type system borrows ideas from functional programming languages. +- Rust's type system borrows a lot of ideas from functional programming + languages. For example, Rust's enums are known as "algebraic data types" in languages like Haskell and OCaml. You can take inspiration from learning material geared @@ -41,9 +42,9 @@ Additional items speaker may mention: doesn't support inheritance, and object decomposition should take into account the constraints introduced by the borrow checker. -- Mention that type-level programming creates "zero-cost abstractions", although - the label can be misleading: the impact on compile times and code complexity - may be significant. +- Mention that type-level programming can be often used to create "zero-cost + abstractions", although the label can be misleading: the impact on compile + times and code complexity may be significant.
diff --git a/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md b/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md index f4a795272dd1..6d3399cc3db5 100644 --- a/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +++ b/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md @@ -59,7 +59,7 @@ fn main() { - We've also used types to shape and restrict APIs already using [the Typestate pattern](../leveraging-the-type-system/typestate-pattern.md). -- Language features are frequently introduced for a specific purpose. +- Language features are often introduced for a specific purpose. Over time, users may develop ways of using a feature in ways that were not predicted when they were introduced. @@ -67,8 +67,8 @@ fn main() { Java 5 introduced Generics in 2004 with the [main stated purpose of enabling type-safe collections](https://jcp.org/en/jsr/detail?id=14). - Adoption was slow at first, but several new projects began designing their - APIs around generics from the beginning. + Adoption was slow at first, but some new projects began designing their APIs + around generics from the beginning. Since then, users and developers of the language expanded the use of generics to other areas of type-safe API design: diff --git a/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md b/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md index afe1c5fa6bfc..6e77915cdded 100644 --- a/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +++ b/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md @@ -63,10 +63,10 @@ fn demo_denied() { `shared_again_again` reference is taken from `&value`. - Remember that every `&T` and `&mut T` has a lifetime, just one the user - doesn't have to annotate or think about typically. + doesn't have to annotate or think about most of the time. We rarely specify lifetimes because the Rust compiler allows us to _elide_ - them in the majority of cases. See: + them in most cases. See: [Lifetime Elision](../../../lifetimes/lifetime-elision.md)
diff --git a/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md b/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md index 895a2245bb9d..7896e62ef2bb 100644 --- a/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +++ b/src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md @@ -4,8 +4,8 @@ minutes: 15 # PhantomData 3/4: Lifetimes for External Resources -The invariants of external resources typically match what we can do with -lifetime rules. +The invariants of external resources often match what we can do with lifetime +rules. ```rust,editable // use std::marker::PhantomData; diff --git a/src/idiomatic/leveraging-the-type-system/extension-traits.md b/src/idiomatic/leveraging-the-type-system/extension-traits.md index 9595d34d9559..5a32674a9c84 100644 --- a/src/idiomatic/leveraging-the-type-system/extension-traits.md +++ b/src/idiomatic/leveraging-the-type-system/extension-traits.md @@ -38,8 +38,7 @@ pattern** to work around this limitation. Highlight how the compiler error message nudges you towards the extension trait pattern. -- Explain how the numerous type-system restrictions in Rust aim to prevent - _ambiguity_. +- Explain how many type-system restrictions in Rust aim to prevent _ambiguity_. What would happen if you were allowed to define new inherent methods on foreign types? Different crates in your dependency tree might end up defining @@ -58,7 +57,7 @@ pattern** to work around this limitation. new inherent methods on foreign types. - Other languages (e.g, Kotlin, C#, Swift) allow adding methods to existing - types, known as "extension methods." This leads to different trade-offs in + types, often called "extension methods." This leads to different trade-offs in terms of potential ambiguities and the need for global reasoning.
diff --git a/src/idiomatic/leveraging-the-type-system/newtype-pattern.md b/src/idiomatic/leveraging-the-type-system/newtype-pattern.md index 3aa89bef8718..330e465b5bad 100644 --- a/src/idiomatic/leveraging-the-type-system/newtype-pattern.md +++ b/src/idiomatic/leveraging-the-type-system/newtype-pattern.md @@ -4,7 +4,7 @@ minutes: 5 # Newtype Pattern -A _newtype_ is a wrapper around an existing type, typically a primitive: +A _newtype_ is a wrapper around an existing type, often a primitive: ```rust /// A unique user identifier, implemented as a newtype around `u64`. diff --git a/src/idiomatic/leveraging-the-type-system/raii.md b/src/idiomatic/leveraging-the-type-system/raii.md index 48ff2b4a8420..25eec34cdb16 100644 --- a/src/idiomatic/leveraging-the-type-system/raii.md +++ b/src/idiomatic/leveraging-the-type-system/raii.md @@ -82,9 +82,9 @@ fn main() -> Result<(), std::io::Error> { The `Drop` trait has another important limitation: it is not `async`. -This means you cannot `await` inside a destructor, which is frequently needed -when cleaning up asynchronous resources like sockets, database connections, or -tasks that must signal completion to another system. +This means you cannot `await` inside a destructor, which is often needed when +cleaning up asynchronous resources like sockets, database connections, or tasks +that must signal completion to another system. - Learn more: diff --git a/src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md b/src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md index 43762a0293c1..47272298fee6 100644 --- a/src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +++ b/src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md @@ -7,7 +7,7 @@ minutes: 15 Use `Drop` to enforce invariants and detect incorrect API usage. A "drop bomb" panics if a value is dropped without being explicitly finalized. -This pattern is commonly used when the finalizing operation (like `commit()` or +This pattern is often used when the finalizing operation (like `commit()` or `rollback()`) needs to return a `Result`, which cannot be done from `Drop`. ```rust,editable @@ -57,7 +57,7 @@ fn main() -> io::Result<()> { in an unfinished state. The destructor panics if the transaction has not been explicitly finalized (for example, with `commit()`). -- The finalizing operation (such as `commit()`) typically takes `self` by value. +- The finalizing operation (such as `commit()`) usually takes `self` by value. This ensures that once the transaction is finalized, the original object can no longer be used. diff --git a/src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md b/src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md index 59752578d997..e2a33b2c564b 100644 --- a/src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +++ b/src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md @@ -53,7 +53,7 @@ fn main() { This is useful in many cases, as it means two different lifetimes can be treated as if they were the same in the regions they do overlap. - This is typically what we want. But here we want to use lifetimes as a way to + This is usually what we want. But here we want to use lifetimes as a way to distinguish values so we say that a token only applies to a single variable without having to create a newtype for every single variable we declare. diff --git a/src/idiomatic/polymorphism/from-oop-to-rust/composition.md b/src/idiomatic/polymorphism/from-oop-to-rust/composition.md index a47f4cc666a5..3324813d1974 100644 --- a/src/idiomatic/polymorphism/from-oop-to-rust/composition.md +++ b/src/idiomatic/polymorphism/from-oop-to-rust/composition.md @@ -26,7 +26,7 @@ pub struct User { different types. This has downsides, largely in ergonomics of field access, but gives - developers significant control and clarity over what a type does and it has + developers a lot of control and clarity over what a type does and it has access to. - When deriving traits, make sure all the field types of a struct or variant diff --git a/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md b/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md index a27498e9ff73..f81f3d34e0a2 100644 --- a/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +++ b/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md @@ -27,8 +27,8 @@ pub trait Trait { - This was previously called _object safe traits_ or _object safety_. -- Dynamic dispatch offloads significant compile-time type information into - runtime vtable information. +- Dynamic dispatch offloads a lot of compile-time type information into runtime + vtable information. If a concept is incompatible with what we can meaningfully store in a vtable, either the trait stops being dyn compatible or those methods are excluded from diff --git a/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md b/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md index b88a17b1c488..eb83e51fa0fc 100644 --- a/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +++ b/src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md @@ -42,8 +42,8 @@ fn main() { - The above example takes things to the absurd: If adding numbers were tied up in the dynamic dispatch process, it would be difficult to do anything at all. - But dynamic dispatch is often hidden in many programming languages: here's it - is more explicit. + But dynamic dispatch is often hidden in a lot of programming languages: here's + it is more explicit. In the `i32` implementation of `AddDyn`, first we need to attempt to downcast the `rhs` argument to the same type as `i32`, silently failing if this isn't diff --git a/src/idiomatic/polymorphism/refresher/trait-bounds.md b/src/idiomatic/polymorphism/refresher/trait-bounds.md index ae99bb0a3411..bb6db4fe529d 100644 --- a/src/idiomatic/polymorphism/refresher/trait-bounds.md +++ b/src/idiomatic/polymorphism/refresher/trait-bounds.md @@ -23,8 +23,8 @@ fn main() {
-- Traits are typically used as bounds on generic type parameters for a function - or method. +- Traits are most commonly used as bounds on generic type parameters for a + function or method. Without a trait bound on a generic type parameter, we don't have access to any behavior to write functions and methods with. diff --git a/src/idiomatic/welcome.md b/src/idiomatic/welcome.md index 3b64dfcbea96..efe7499269bf 100644 --- a/src/idiomatic/welcome.md +++ b/src/idiomatic/welcome.md @@ -49,8 +49,8 @@ languages like Swift, Kotlin, C#, or TypeScript. in the standard library - e.g., methods should be called "push" not "push_back", "is_empty" not "empty" etc.) - Know the vocabulary types and traits in the standard library, and use them - in your APIs. If something appears to be a basic type/algorithm, check in - the standard library first! + in your APIs. If something feels like a basic type/algorithm, check in the + standard library first. - Use well-established API design patterns that we will discuss later in this class (e.g., newtype, owned/view type pairs, error handling) - Write meaningful and effective doc comments (e.g., don't merely repeat the From cb73531dcc922f4609ac14f72077743265cf10af Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Mon, 23 Feb 2026 13:58:02 +0100 Subject: [PATCH 3/3] idiomatic: updates from review comments --- .../predictable-api/naming-conventions/from.md | 7 ++----- .../predictable-api/naming-conventions/into_inner.md | 6 +++--- .../predictable-api/naming-conventions/to.md | 6 +++--- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md index baa2419e7429..d6dec2631cfb 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md +++ b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md @@ -31,11 +31,8 @@ impl u32 {
- Prefix for constructor-style, `From`-trait-style functions. -- These functions can take multiple arguments, but imply the user is expected to - provide the data that the type is composed of. - - `new` is still preferred for most constructor-style functions, the implication - for `from` is transformation of one data type to another. +- `new` is preferred for constructor-style functions, the implication for `from` + is transformation of one data type to another. - Ask: Without looking at the standard library documentation, what would the argument type of `u32::from_be` be? diff --git a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md index 7fa831c4aeab..3d5511b7898d 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md +++ b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md @@ -27,9 +27,9 @@ impl Cell {
-- `into_inner` is a method found on newtypes: types whose main purpose is to - wrap around an existing type and be semantically distinct from other uses of - that inner type. +- `into_inner` is a method usually found on newtypes: types whose main purpose + is to wrap around an existing type and be semantically distinct from other + uses of that inner type. This kind of method is also found on types like `Cell`, which exclusively own the internal data. diff --git a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md index b60a41bc13c4..2a019eca44bd 100644 --- a/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +++ b/src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md @@ -30,9 +30,9 @@ impl u32 { non-trivial type conversion, or even a data transformation. For example, `str::to_uppercase`. -- "to" methods take `&self`. However they can take `self` by value if the type - implements `Copy`: this also ensures that the conversion method call does not - consume `self`. +- "to" methods most commonly take `&self`. However they can take `self` by value + if the type implements `Copy`: this also ensures that the conversion method + call does not consume `self`. - If you simply want to define a method that takes `&self` and returns an owned value of the same type, implement the `Clone` trait.