edit new section for typos and better wording
This commit is contained in:
parent
921d37dbd5
commit
6d5f43d77d
1 changed files with 21 additions and 16 deletions
|
|
@ -184,22 +184,27 @@
|
|||
//! provide a safe interface on top.
|
||||
//!
|
||||
//! There are a couple of linked disadvantages to using this model. The core issue is a lack
|
||||
//! of generality. This is an issue first because it means hat each individual type that
|
||||
//! implements such an interface does so on its own. Each individual developer must themselves
|
||||
//! think through all the guarantees needed to ensure the API they present is sound. This puts
|
||||
//! a greater burden on each developer, rather than allowing building a shared understanding of the
|
||||
//! problem space, encoded into a shared interface to solve it. In addition, and the key issue that
|
||||
//! drove Rust towards another solution, is that each individual object must assume it is on its
|
||||
//! own in ensuring that its data does not become *moved* or otherwise invalidated. Since there is
|
||||
//! no shared contract between values of different types, an object cannot assume that others
|
||||
//! interacting with it will be a good citizen with its data. Because of this, *composition* of
|
||||
//! address-sensitive types requires at least a level of pointer indirection (and, practically, a
|
||||
//! heap allocation) each time a new object is added to the mix. This is particularly a problem
|
||||
//! when one considers the implications of composing together the [`Future`]s which will eventaully
|
||||
//! make up an asynchronous task (including address-sensitive `async fn` state machines).
|
||||
//! It is plausible that there could be many layers of [`Future`]s composed together, including
|
||||
//! multiple layers of `async fn`s handling different parts of a task, and it was deemed
|
||||
//! unacceptable to force indirection and allocation for each layer of composition in this case.
|
||||
//! of generality. This is an issue because it means that each individual type that implements
|
||||
//! such an interface does so on its own. Each developer implementing such a type must themselves
|
||||
//! think through all the guarantees needed to ensure the API they present is sound. We would
|
||||
//! rather build a shared understanding of the problem space and encode that understanding into a
|
||||
//! shared interface to solve it which everyone helps validate.
|
||||
//!
|
||||
//! In addition, and the key issue that drove Rust towards developing another solution, is that
|
||||
//! in this model, each individual object must assume it is *on its own* to ensure that its data
|
||||
//! does not become *moved* or otherwise invalidated. Since there is no shared contract between
|
||||
//! values of different types, an object cannot assume that others interacting with it will
|
||||
//! properly respect the invariants around interacting with its data and must therefore protect
|
||||
//! it from everyone. Because of this, *composition* of address-sensitive types requires at least
|
||||
//! a level of pointer indirection each time a new object is added to the mix (and, practically, a
|
||||
//! heap allocation).
|
||||
//!
|
||||
//! This is particularly a problem when one considers, for exapmle, the implications of composing
|
||||
//! together the [`Future`]s which will eventaully make up an asynchronous task (including
|
||||
//! address-sensitive `async fn` state machines). It is plausible that there could be many layers
|
||||
//! of [`Future`]s composed together, including multiple layers of `async fn`s handling different
|
||||
//! parts of a task. It was deemed unacceptable to force indirection and allocation for each layer
|
||||
//! of composition in this case.
|
||||
//!
|
||||
//! [`Pin<Ptr>`] is an implementation of the third option. It allows us to solve the issues
|
||||
//! discussed with the second option by building a *shared contractual language* around the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue