# Descript v0.2 ## Specification > *This specification is slightly outdated. It was mostly written* > *before the implementation, and it hasn't been fully updated since.* > *In particular, injections (primitive types and injected applications) > *aren't included in the specification (although technically they could > *be considered input/output records.)* ```descript A[a: E] | B[b: F] : C A | B | D => C | D ``` Programs consist of values and reducers. A value is a union (set) of parts. A value can't have 2 primitives which are equal, or 2 records which share the same head. > Because of the above, a typical implementation represents a value as a > map of "heads" to "properties", where a primitives is its own head and > has no properties. This representation is efficient and easy to use, > because primitives and record heads are treated similarly. A part is a primitive or a record. A primitive is a string, number, image, etc.. A record has a (head) symbol and a map of symbols to values (properties - each entry is a property). A symbol is an identifier used for reference - symbols can be checked for equality. If 2 records have the same head symbol, they belong to the same type, and they must have the same property keys. > An implementation can allow any datum to be a symbol. A typical > implementation restricts a symbol in a record to a literal (is a > special type of string). Typically some special record, such as > vectors, can have maps with number keys. > Usually the symbols in the head of a value are `TitleCamelCase` > literals, while the symbols in the maps are `lowerCamelCase` literals. A reducer has an input value and an output value. An input value is a union of input parts. An input part is a primitive or input record. An input record is a symbol (head) and a map of symbols to *optional* input values (properties). An input record's head must equal an already-defined record's head. > Alternatively, an implementation of input records can simply be a > symbol and a map of symbols to (not optional) input values. Then, > instead of requiring input records with equal heads to have the same > property keys, an input record needs to have a subset of the property > keys of a regular record with the same head. > An implementation can prevent input values in top-level input records > from themselves containing input records, and force top-level input > records to contain non-optional properties. An output value is a union (set) of output parts. An output part is a property path, primitive, or output record. A property path is list of path elements. A path element is a symbol corresponding to a record's head (head reference) and another symbol corresponding to a property key in that record (key reference). An output record is a symbol (head) and a map of symbols to output values (properties). A reducer affects a value if its input value matches the value. An input value matches a regular value if its parts match the regular value's parts. An input primitive matches an equal regular primitive. An input record matches a regular record if it has the same head (and thus, the property keys should be equal) and its property values match the regular value's property values. A value reduces if there's reducer defined which will affect it. The value reduces into the reducer's output value applied to the value. An output value applied to another value is its parts applied to the other value. A primitive applied to any value is the primitive itself. A record applied to a value has the same head and property keys, and the property values are also applied to that value. A property path `ab It could be a record or atom, depending on implementation.