diff --git a/src/idiomatic/leveraging-the-type-system.md b/src/idiomatic/leveraging-the-type-system.md index 21e1fae5..5da0e62b 100644 --- a/src/idiomatic/leveraging-the-type-system.md +++ b/src/idiomatic/leveraging-the-type-system.md @@ -4,15 +4,15 @@ minutes: 5 # Leveraging the Type System -Rust's type system is _expressive_.\ -We can use types and traits to build abstractions that make our code harder to -misuse. In some cases, we can even go as far as enforcing correctness at -_compile-time_. Quite often, these abstractions have no runtime -overhead[^zero-cost]. +Rust's type system is _expressive_: you can use types and traits to build +abstractions that make your code harder to misuse. -The type system can also be used to model concepts and constraints from your -business domain. By designing our types carefully, we can improve the clarity -and maintainability of the entire codebase. +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 +entire codebase.
@@ -36,12 +36,12 @@ Additional items speaker may mention: doesn't support inheritance, and object boundaries must be mindful of the constraints introduced by the borrow-checker. +- Mention that type-level abstractions are often referred to as "zero-cost + abstractions", although the label can be misleading: the impact on compile + times and code complexity may be significant. +
{{%segment outline}} [1]: https://pragprog.com/titles/swdddf/domain-modeling-made-functional/ - -[^zero-cost]: They often referred to as "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/newtype-pattern/parse-don-t-validate.md b/src/idiomatic/leveraging-the-type-system/newtype-pattern/parse-don-t-validate.md index 452f564c..ae503e2b 100644 --- a/src/idiomatic/leveraging-the-type-system/newtype-pattern/parse-don-t-validate.md +++ b/src/idiomatic/leveraging-the-type-system/newtype-pattern/parse-don-t-validate.md @@ -36,27 +36,26 @@ impl Username { - The newtype pattern, combined with Rust's module and visibility system, can be used to _guarantee_ that instances of a given type satisfy a set of invariants.\ - In the example above, the raw `String` stored inside the - `Username` struct can't be accessed directly from other modules or crates, - since it's not marked as `pub` or `pub(in ...)`. Consumers of the `Username` - type are forced to use the `new` method to create instances. In turn, `new` - performs validation, thus ensuring that all instances of `Username` satisfy - those checks. + In the example above, the raw `String` stored inside the `Username` struct + can't be accessed directly from other modules or crates, since it's not marked + as `pub` or `pub(in ...)`. Consumers of the `Username` type are forced to use + the `new` method to create instances. In turn, `new` performs validation, thus + ensuring that all instances of `Username` satisfy those checks. - The `as_str` method allows consumers to access the raw string representation - (e.g. to store it in a database) but, thanks to Rust's borrow checker, - they can't modify it. + (e.g. to store it in a database) but, thanks to Rust's borrow checker, they + can't modify it. -- Stress the importance of evaluating _the entire API surface_ exposed by a newtype - to determine if invariants are indeed bullet-proof.\ - It is crucial to consider all possible interactions, including trait implementations, - that may allow users to bypass the invariants. For example, if the `Username` - type implements the `DerefMut` trait, users can modify the underlying string - directly, bypassing the validation checks in `new`. +- Stress the importance of evaluating _the entire API surface_ exposed by a + newtype to determine if invariants are indeed bullet-proof.\ + It is crucial to consider all possible interactions, including trait + implementations, that may allow users to bypass the invariants. For example, + if the `Username` type implements the `DerefMut` trait, users can modify the + underlying string directly, bypassing the validation checks in `new`. - Type-level invariants have second-order benefits.\ - The input is validated once, at the boundary, and the rest of the program can rely - on the invariants being upheld. We can avoid redundant validation and + The input is validated once, at the boundary, and the rest of the program can + rely on the invariants being upheld. We can avoid redundant validation and "defensive programming" checks throughout the program, reducing noise and improving performance.