Definition of the Canonical



Is there a definition of the Canonical type (concept)?
In practice, it allows for reducing the number of transformations: from MxN to M+N (M to the canonical, N from it).
In theory, it could contain fields that are the least upper bound (sum) of types mapped to it, and/or the greatest lower bound (intersection) of types it is mapped to. Or such, it would help as a guideline.




I assume you checked c3ShowType(Canonical)? Is there a specific question you have?



I do not have a specific problem/question, it is just that I haven’t found a concise explanation of what is, and what is not, meant by ‘canonical’ in the context of Type System. So far, I have seen various uses of it, e.g., for dependency inversion. No pressure, I will write here once I understand it better.



A canonical should be thought of as a declaration of the format of data which an application will accept. Defining a new Canonical type is like saying: “if you give me data that looks like this, i’ll know what to do with it.”

In some sense, it defines the “edge” of the application, also if you think of the entire application as a single function, then I could write this function as:

function([canonical], [userInput]) => [Behavior]

In other words, a c3 application is just a function that takes data in canonical format and user inputs and returns behaviors like “render a page” and “calculate some aggregation”



Thanks. So multiple types (outside the application) can be mapped onto (transformed into) a canonical type, and the canonical type can be mapped to multiple types (inside the application), I gather.



Exactly. Whatever happens outside the platform is sort of not c3’s business, and you can map as many external data sources to a single canonical as you want using whatever technologies you prefer.

A single canonical can map to any number of types inside c3.
Any number of canonicals can map to a single type in c3.
A single canonical can have 2 transformations to the same c3 type (using the conditional annotation)
A canonical can also map to another canonical (for backwards compatibility, etc.) which presumably then maps to one or several types

If 2 transformations create a c3 type with the same ID then the union of the outputs is persisted in c3 (if both transformations try to set the value of the same field then whichever transformation happens last wins)