From 125e1e14161669f83ea0accdc2b9aad6817899ee Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Fri, 11 Feb 2022 23:56:11 +0100 Subject: [PATCH] More manual --- src/guide/preserves.md | 49 ++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/guide/preserves.md b/src/guide/preserves.md index c2cbf32..09ece06 100644 --- a/src/guide/preserves.md +++ b/src/guide/preserves.md @@ -27,7 +27,7 @@ document](https://preserves.gitlab.io/preserves/preserves.html): There are four aspects of Preserves that make it particularly relevant to Synit: - - the core Preserves [data language](#grammar-of-values) has a robust *semantics*; + - the core Preserves [data language](#grammar-of-values) has a robust semantics; - a [canonical form](#canonical-form) exists for every Preserves value; - Preserves values may have [capability references](#capabilities) embedded within them; and - Preserves has a [schema language](#schemas) useful for specifying protocols among actors. @@ -39,10 +39,10 @@ Preserves has programming-language-independent *semantics*: the specification de solid foundation for a multi-language, multi-process, potentially distributed system like Synit. [^dataspaces-need-data-with-semantics] -### Abstract syntax: Values +### Values and Types -The *abstract syntax* of Preserves values includes a few basic atomic types, plus sequence, -set, dictionary, and record compound types. From the specification: +Preserves values come in various *types*: a few basic atomic types, plus sequence, set, +dictionary, and record compound types. From the specification: Value = Atom Atom = Boolean | Compound | Float @@ -157,7 +157,7 @@ specification](https://preserves.gitlab.io/preserves/preserves-schema.html): > successfully serialized. Instead of taking host-language data structure definitions as primary, in the way that systems -like [serde](https://serde.rs/) do, Preserves schemas take *the shape of the serialized data* +like [Serde](https://serde.rs/) do, Preserves schemas take *the shape of the serialized data* as primary. To see the difference, let's look at an example. @@ -167,9 +167,9 @@ To see the difference, let's look at an example. Systems like [Serde](https://serde.rs/) concentrate on defining (de)serializers for host-language type definitions. -Serde starts from definitions like the following[^this-example-from-mdbook]. It generates -(de)serialization code for various different *data languages* (such as JSON, XML, CBOR, etc.) -in a single *programming language*: Rust. +Serde starts from definitions like the following.[^this-example-from-mdbook] It generates +(de)serialization code for various different *data* languages (such as JSON, XML, CBOR, etc.) +in a single *programming* language: Rust. ```rust pub struct BookOutline { @@ -186,9 +186,9 @@ pub struct Chapter { } ``` -The (de)serializers are able to produce and understand values such as the following JSON -document, converting them to and from in-memory representations. The focus is on Rust: -interpreting the produced documents from other languages is out-of-scope for Serde. +The (de)serializers are able to convert between in-memory and serialized representations such +as the following JSON document. The focus is on Rust: interpreting the produced documents from +other languages is out-of-scope for Serde. ```json { @@ -211,14 +211,12 @@ interpreting the produced documents from other languages is out-of-scope for Ser } ``` -By contrast, Preserves schemas focus on Preserves values[^including-json] only. +By contrast, Preserves schemas map a single *data* language to and from multiple *programming* +languages. Each specific programming language has its own schema compiler, which generates type +definitions and (de)serialization code for that language from a language-independent grammar. -Each Preserves schema compiler generates type definitions and (de)serialization code for a -single *programming language* able to understand common *data*. The grammar of the data itself -is language-independent. - -For example, a Preserves schema able to parse values compatible with those produced by Serde -for the type definitions above is the following: +For example, a schema able to parse values compatible with those produced by Serde for the type +definitions above is the following: ```preserves version 1 . @@ -237,8 +235,8 @@ Chapter = { } . ``` -Using the Rust schema compiler, we see types such as the following, which are *similar to* but -not the *same* as the original Rust types above: +Using the Rust schema compiler, we see types such as the following, which are similar to but +not the same as the original Rust types above: ```rust pub struct BookOutline { @@ -300,8 +298,8 @@ BookItem = Chapter / =separator / @partTitle string . Chapter = . ``` -The schema compilers produce **exactly the same** type definitions for this variation. -The differences are in the (de)serialization code only. +The schema compilers produce **exactly the same type definitions**[^well-almost-exactly] for +this variation. The differences are in the (de)serialization code only. Here's the Preserves value equivalent to the example above, expressed using the Preserves-native schema: @@ -314,8 +312,6 @@ Here's the Preserves value equivalent to the example above, expressed using the ]> ``` -## Preserves Path - --- #### Notes @@ -347,8 +343,9 @@ Here's the Preserves value equivalent to the example above, expressed using the [preprocess the manual's source code](https://git.syndicate-lang.org/synit/synit/src/branch/main/manual/mdbook-ditaa). -[^including-json]: Including JSON values, of course! - [^lose-compatibility]: By doing so, we lose compatibility with the Serde structures, but the point is to show the kinds of schemas available to us once we move away from strict compatibility with existing data formats. + +[^well-almost-exactly]: Well, almost exactly the same. The only difference is in the Rust + types, which use tuple-style instead of record-style structs for chapters and part titles.