From 454e5518d220d47452658688810836f58c5f4e7a Mon Sep 17 00:00:00 2001 From: Sean Chen Date: Mon, 22 Aug 2022 14:16:38 -0500 Subject: [PATCH] Start proofreading the 'how salsa works' section --- book/src/how_salsa_works.md | 8 ++--- book/src/plumbing/jars_and_ingredients.md | 39 ++++++++++------------- book/src/videos.md | 4 +-- 3 files changed, 22 insertions(+), 29 deletions(-) diff --git a/book/src/how_salsa_works.md b/book/src/how_salsa_works.md index 4b3e8efc..d42b563a 100644 --- a/book/src/how_salsa_works.md +++ b/book/src/how_salsa_works.md @@ -2,8 +2,8 @@ ## Video available -To get the most complete introduction to salsa's inner works, check -out [the "How Salsa Works" video](https://youtu.be/_muY4HjSqVw). If +To get the most complete introduction to salsa's inner workings, check +out [the "How Salsa Works" video](https://youtu.be/_muY4HjSqVw). If you'd like a deeper dive, [the "Salsa in more depth" video](https://www.youtube.com/watch?v=i_IhACacPRY) digs into the details of the incremental algorithm. @@ -13,14 +13,14 @@ details of the incremental algorithm. ## Key idea The key idea of `salsa` is that you define your program as a set of -**queries**. Every query is used like function `K -> V` that maps from +**queries**. Every query is used like a function `K -> V` that maps from some key of type `K` to a value of type `V`. Queries come in two basic varieties: - **Inputs**: the base inputs to your system. You can change these whenever you like. - **Functions**: pure functions (no side effects) that transform your - inputs into other values. The results of queries is memoized to + inputs into other values. The results of queries are memoized to avoid recomputing them a lot. When you make changes to the inputs, we'll figure out (fairly intelligently) when we can re-use these memoized values and when we have to recompute them. diff --git a/book/src/plumbing/jars_and_ingredients.md b/book/src/plumbing/jars_and_ingredients.md index e7564c04..1ea9f0a5 100644 --- a/book/src/plumbing/jars_and_ingredients.md +++ b/book/src/plumbing/jars_and_ingredients.md @@ -2,7 +2,7 @@ {{#include ../caveat.md}} -This page covers how data is organized in salsa and how links between salsa items (e.g., dependency tracking) works. +This page covers how data is organized in salsa and how links between salsa items (e.g., dependency tracking) work. ## Salsa items and ingredients @@ -32,7 +32,7 @@ Each salsa item needs certain bits of data at runtime to operate. These bits of data are called **ingredients**. Most salsa items generate a single ingredient, but sometimes they make more than one. For example, a tracked function generates a [`FunctionIngredient`]. -A tracked struct however generates several ingredients, one for the struct itself (a [`TrackedStructIngredient`], +A tracked struct, however, generates several ingredients, one for the struct itself (a [`TrackedStructIngredient`], and one [`FunctionIngredient`] for each value field. [`FunctionIngredient`]: https://github.com/salsa-rs/salsa/blob/becaade31e6ebc58cd0505fc1ee4b8df1f39f7de/components/salsa-2022/src/function.rs#L42 @@ -50,13 +50,6 @@ or whether the function must be executed. [`TrackedStruct::new_struct`]: https://github.com/salsa-rs/salsa/blob/becaade31e6ebc58cd0505fc1ee4b8df1f39f7de/components/salsa-2022/src/tracked_struct.rs#L76 [`TrackedFunction::fetch`]: https://github.com/salsa-rs/salsa/blob/becaade31e6ebc58cd0505fc1ee4b8df1f39f7de/components/salsa-2022/src/function/fetch.rs#L15 -### Ingredient interfaces are not stable or subject to semver - -Interfaces are not meant to be directly used by salsa users. -The salsa macros generate code that invokes the ingredients. -The APIs may change in arbitrary ways across salsa versions, -as the macros are kept in sync. - ### The `Ingredient` trait Each ingredient implements the [`Ingredient`] trait, which defines generic operations supported by any kind of ingredient. @@ -65,8 +58,8 @@ For example, the method `maybe_changed_after` can be used to check whether some [`Ingredient`]: https://github.com/salsa-rs/salsa/blob/becaade31e6ebc58cd0505fc1ee4b8df1f39f7de/components/salsa-2022/src/ingredient.rs#L15 [`maybe_changed_after`]: https://github.com/salsa-rs/salsa/blob/becaade31e6ebc58cd0505fc1ee4b8df1f39f7de/components/salsa-2022/src/ingredient.rs#L21-L22 -We'll see below that each database `DB` is able to take an `IngredientIndex` and use that to get a `&dyn Ingredient` for the corresponding ingredient. -This allows the database to perform generic operations on a numbered ingredient without knowing exactly what the type of that ingredient is. +We'll see below that each database `DB` is able to take an `IngredientIndex` and use that to get an `&dyn Ingredient` for the corresponding ingredient. +This allows the database to perform generic operations on an indexed ingredient without knowing exactly what the type of that ingredient is. ### Jars are a collection of ingredients @@ -91,13 +84,12 @@ struct Jar( ) ``` -The `IngredientsFor` trait is used to define the ingredients needed by some salsa item, such as the tracked function `foo` -or the tracked struct `MyInput`. -Each salsa item defines a type `I`, so that `::Ingredient` gives the ingredients needed by `I`. +The `IngredientsFor` trait is used to define the ingredients needed by some salsa item, such as the tracked function `foo` or the tracked struct `MyInput`. +Each salsa item defines a type `I` so that `::Ingredient` gives the ingredients needed by `I`. -### Database is a tuple of jars +### A database is a tuple of jars -Salsa's database storage ultimately boils down to a tuple of jar structs, +salsa's database storage ultimately boils down to a tuple of jar structs where each jar struct (as we just saw) itself contains the ingredients for the salsa items within that jar. The database can thus be thought of as a list of ingredients, @@ -107,7 +99,7 @@ The reason for this 2-level hierarchy is that it permits separate compilation an The crate that lists the jars doens't have to know the contents of the jar to embed the jar struct in the database. And some of the types that appear in the jar may be private to another struct. -### The HasJars trait and the Jars type +### The `HasJars` trait and the `Jars` type Each salsa database implements the `HasJars` trait, generated by the `salsa::db` procedural macro. @@ -167,15 +159,16 @@ We can then do things like ask, "did this input change since revision R?" by * using the ingredient index to find the route and get a `&dyn Ingredient` * and then invoking the `maybe_changed_since` method on that trait object. -### HasJarsDyn +### `HasJarsDyn` There is one catch in the above setup. -We need the database to be dyn-safe, and we also need to be able to define the database trait and so forth without knowing the final database type to enable separate compilation. +We need the database to be dyn-safe [what does this mean?], and we also need to be able to define the database trait without knowing the final database type to enable separate compilation. Traits like `Ingredient` require knowing the full `DB` type. If we had one function ingredient directly invoke a method on `Ingredient`, that would imply that it has to be fully generic and only instantiated at the final crate, when the full database type is available. -We solve this via the `HasJarsDyn` trait. The `HasJarsDyn` trait exports method that combine the "find ingredient, invoking method" steps into one method: +We solve this via the `HasJarsDyn` trait. The `HasJarsDyn` trait exports a method that combines the "find ingredient, invoking method" steps into one method: +[Perhaps this code snippet should only preview the HasJarsDyn method that is being referred to] ```rust,ignore {{#include ../../../components/salsa-2022/src/storage.rs:HasJarsDyn}} ``` @@ -205,13 +198,13 @@ The implementation of this method is defined by the `#[salsa::db]` macro; it sim {{#include ../../../components/salsa-2022-macros/src/db.rs:create_jars}} ``` -This implementation for `create_jar` is geneated by the `#[salsa::jar]` macro, and simply walks over the representative type for each salsa item and ask *it* to create its ingredients +This implementation for `create_jar` is geneated by the `#[salsa::jar]` macro, and simply walks over the representative type for each salsa item and asks *it* to create its ingredients ```rust,ignore {{#include ../../../components/salsa-2022-macros/src/jar.rs:create_jar}} ``` The code to create the ingredients for any particular item is generated by their associated macros (e.g., `#[salsa::tracked]`, `#[salsa::input]`), but it always follows a particular structure. -To create an ingredient, we first invoke `Routes::push` which creates the routes to that ingredient and assigns it an `IngredientIndex`. -We can then invoke (e.g.) `FunctionIngredient::new` to create the structure. +To create an ingredient, we first invoke `Routes::push`, which creates the routes to that ingredient and assigns it an `IngredientIndex`. +We can then invoke (e.g.) [Missing an example here] `FunctionIngredient::new` to create the structure. The *routes* to an ingredient are defined as closures that, given the `DB::Jars`, can find the data for a particular ingredient. diff --git a/book/src/videos.md b/book/src/videos.md index aa4159fb..9e6bd009 100644 --- a/book/src/videos.md +++ b/book/src/videos.md @@ -1,12 +1,12 @@ # Videos -There are currently two videos about Salsa available, but they describe an older version of Salsa and so they are rather outdated: +There are currently two videos about salsa available, but they describe an older version of salsa and so they are rather outdated: - [How Salsa Works](https://youtu.be/_muY4HjSqVw), which gives a high-level introduction to the key concepts involved and shows how to use salsa; - [Salsa In More Depth](https://www.youtube.com/watch?v=i_IhACacPRY), which digs into the incremental algorithm and explains -- at a - high-level -- how Salsa is implemented. + high-level -- how salsa is implemented. > If you're in China, watch videos on [How Salsa Works](https://www.bilibili.com/video/BV1Df4y1A7t3/), [Salsa In More Depth](https://www.bilibili.com/video/BV1AM4y1G7E4/).