# Preserves Synit makes **extensive** use of *Preserves*, a programming-language-independent language for data. - [Preserves homepage](https://preserves.gitlab.io/) - [Preserves specification](https://preserves.gitlab.io/preserves/preserves.html) - [Preserves schema-language specification](https://preserves.gitlab.io/preserves/preserves-schema.html) - [Source code](https://gitlab.com/preserves/preserves) for many (not all) of the implementations - Implementations for [Nim](https://git.sr.ht/~ehmry/preserves-nim), [Python](https://pypi.org/project/preserves/), [Racket](https://pkgs.racket-lang.org/package/preserves), [Rust](https://docs.rs/preserves/latest/preserves/), [Squeak Smalltalk](https://squeaksource.com/Preserves.html), [TypeScript/Javascript](https://www.npmjs.com/org/preserves) The Preserves data language is in many ways comparable to JSON, XML, S-expressions, CBOR, ASN.1 BER, and so on. From the [specification document](https://preserves.gitlab.io/preserves/preserves.html): > Preserves supports *records* with user-defined *labels*, embedded *references*, and the usual > suite of atomic and compound data types, including *binary* data as a distinct type from text > strings. ## Why does Synit rely on Preserves? There are five aspects of Preserves that make it particularly relevant to Synit: - the core Preserves [data language](#grammar-of-values) has a robust *semantics*; - Preserves values may have [capability references() embedded within them; - Preserves has a [schema language](#schemas) useful for specifying protocols among actors; - a [canonical form](#canonical-form) exists for every Preserves value; and - Preserves has a [query language](#preserves-path) for extracting portions of a Preserves value. ## Grammar of values The main reason Preserves is useful for Synit is that it has *semantics*: the specification defines a language-independent *equivalence relation* over Preserves values.[^preserves-ordering-exists-too] This makes it a solid foundation for a multi-language, multi-process, potentially distributed system like Synit. [^dataspaces-need-data-with-semantics] ### Abstract syntax: Values The *abstract syntax* of Preserves values is as follows (from the specification): Value = Atom Atom = Boolean | Compound | Float | Embedded | Double | SignedInteger Compound = Record | String | Sequence | ByteString | Set | Symbol | Dictionary ### Concrete syntax Because Preserves has semantics independent of its syntax, we are free to define *syntax* appropriate for its use in different settings. Values can be automatically, *losslessly* translated from one syntax to another. The core Preserves specification defines both a *text-based*, human-readable, JSON-like syntax, that is a syntactic superset of JSON, and a completely equivalent compact *binary* syntax, crucial to the definition of [canonical form](#canonical-form) for Preserves values.[^syrup] Here are a few example values, written using the text syntax (see [the specification](https://preserves.gitlab.io/preserves/preserves.html#textual-syntax) for the grammar): Boolean : #t, #f Float : 1.0f, 10.4e3f, -100.6f Double : 1.0, 10.4e3, -100.6 Integer : 1, 0, -100 String : "Hello, world!\n" ByteString : #"bin\x00str\x00", #[YmluAHN0cgA], #x"62696e0073747200" Symbol : hello-world, |hello world|, =, !, hello?, ||, ... Record :