1Branded Values
2==============
3A branded value is an "API value" that carries around its name (called a brand)
4and its documentation as metadata. Functions, modules, and data constructors
5can be branded. These are the components from which library APIs are built.
6
7This is a feature that's found in a less general form in many dynamically
8typed programming languages. It's common for functions and modules
9to carry their name and a docstring as metadata.
10
11Statically typed languages use a mixture of 'structural' and 'nominal'
12equivalence rules for determining type equivalence. In Curv, types are
13values, and Curv has a more general notion of "value equivalence".
14Branded values are compared for equivalence by comparing their brands,
15which means they use nominal equivalence. Unbranded values are compared
16using structural equivalence.
17
18Curv provides a uniform mechanism for defining branded values, and for
19abstracting over them.
20 * In the simplest case, a branded definition 'def B = <function or module>'
21   defines a branded value whose brand is the identifier "B"
22   (and binds it to B in the local environment).
23 * If a branded module "M" has a branded member "f",
24   then f's value has the brand "M.f".
25 * A branded "constructor function" returns a branded value,
26   whose brand (a "call brand") has the form of a function call:
27   the function's brand, followed by the argument values.
28 * There are expressions for constructing anonymous functions, constructor
29   functions, and modules. These anonymous (unbranded) values can then be
30   given a brand. You can also rebrand an already branded value.
31
32A brand is effectively a constructor expression: it's an expression that
33when evaluated in the appropriate environment, reconstructs the original value.
34
35A branded value is printed as its brand. You can use the brand as a pattern
36to match a branded value and bind argument values in a call brand.
37This is a form of data abstraction: the representation of the value is
38hidden behind the expression used to construct the value.
39
40Shapes will become branded values (using the Algebraic Data Abstraction
41feature). All of the standard shape constructors and shape operators
42will become branded data constructors. The brand of a Shape will be a
43tree of operations, like an OpenSCAD CSG tree. The ability to introspect
44this operation tree will have multiple applications.
45
46Branded Values
47--------------
48A branded value has a brand, which has the form of a constructor
49expression. When evaluated in an appropriate environment, the brand
50reconstructs the original value. Branded values are printed as their brands.
51Equality depends on the brand (two brands can't be equal unless their brands
52are equal). Brands are used for pattern matching.
53
54A brand is:
55  <brand> ::= <identifier>              -- name brand
56            | <brand> <argvalue>        -- call brand
57            | <brand> . <identifier>    -- field brand
58
59Two ontologies of branded values: need to align this with Data Type theory.
60* A branded value is an atom, a function, or a module.
61  An atom is much like a symbol, in that the brand constitutes the entire
62  identity of the value.
63* A branded value is a function, module or data constructor.
64
65A branded value abstractly consists of a brand and a payload.
66The payload for an atom is the unit value. Otherwise the payload is an
67anonymous function or module.
68
69Referential transparency. The mechanisms for constructing branded values
70do not violate referential transparency.
71
72There is an equivalence relation, x === y.
73In general x===y means substitutional equivalence: that x can be substituted
74for y in any context without changing the meaning of the program. For branded
75values, x===y is true if the brand and the payload are equivalent. For POD data,
76equivalence is equality, except that 0 and -0 are not equivalent. For functions,
77equivalence means same parse tree, and nonlocal bindings are equivalent.
78
79Modules and records are distinct. Only modules can be branded.
80* A module is a set of mutually recursive definitions. Dependencies between
81  definitions are preserved in the value, which is relevant when a module is
82  printed or rebranded. Editing a module member would entail editing the
83  source code then re-evaluating it and any dependent members.
84  Module members may be branded. Module equivalence is code equivalence (like
85  functions): same parse tree, equivalent nonlocal bindings.
86* A record is a map from symbols to values. An individual record field can be
87  updated without affecting other fields.
88
89Syntax
90------
91As a simplification, I'll say that the unit value is `{}`.
92This unifies atoms with modules, reducing the amount of primitive syntax.
93
94A branded definition is:
95    def <id> = <bexpr>
96where <bexpr> computes a module or function. This can be preceeded by a
97docstring, which becomes part of the metadata of a branded value.
98This is legal anywhere a definition is legal, including a let phrase
99and a REPL command.
100
101A *.curv source file in a directory module yields a branded definition
102if the contents of the source file are:
103    <explicit-bexpr>
104optionally preceded by a docstring. An explicit-bexpr is
105    branded <bexpr>
106The 'branded' keyword can be omitted if <bexpr> is a function literal
107or a non-empty module literal.
108
109An anonymous module literal is what used to be called a scoped record literal.
110It may contain branded definitions. Any definition can be preceded by a
111docstring.
112
113An anonymous constructor function is constructed using
114    <param> -> <explict-bexpr>
115There is no docstring before <explicit-bexpr> in this case.
116Calling an anonymous constructor function is the same as calling a regular
117function. The behaviour is different when you print the function, and when
118you bind it using a branded definition.
119
120A general requirement is that you can construct anonymous modules and
121anonymous constructor functions using combinators, then bind them
122using branded definitions.
123
124Implementation
125--------------
126It is more efficient to construct a function or module with a brand
127than it is to rebrand an existing anonymous function or module. So we
128try to use the former strategy when possible.
129* eval_branded() takes a brand argument. It defaults to calling eval(), then
130  rebranding the result. It is overridden by Function_Expr, Module_Expr
131  and Call_Expr, which use the brand to construct a function or module value.
132
133A Brand contains a helpstring and a label.
134A Label is
135    def Label = {
136        data T = name Symbol | call Function (List Value) | dot T Symbol
137    }
138    factorial = match [
139        0 -> 1,
140        n -> n * factorial (n - 1)
141    ]
142