Type and Structs
One of the common questions for CUE is
how to generate the matching types in a given language.
We will introduce the ideas and complexities with type generation
while also showing concrete examples of
hof gen -T variations.
Types are central to the languages we program in.
hof enables us to specify the shape and rules for
our types in CUE and then generate them in one or more languages.
The schemas and generators for types are the foundation
for many other generators and are important to understand.
More has been written and discussed at the following links. Keep these handy as you read through.
CUE is a great language for defining types and their validations, but how do we turn them into the structs, classes, and other language specific representations?
Right now, and generally, the answer is
Right new because CUE does not have this capability.
Generally because CUE cannot capture
the variety and nuances between languages.
What are these complications?
- OOP vs structural typing, how do you express inheriance or embedding?
- CUE’s types often look like a Venn Diagram with a languages types
- Native validation will be faster, will also need to be generated.
- Casing preferences per language
- Public, private, and protected visibilty
- Default values, when and where they are setup
It would be a burden to put this all on CUE developers to figure out and maintain. By using text interpolation, we can generate types without modifying CUE. Note, CUE does intend to support some language targets, but there is no timeline for when this will happen yet or what it will look like.
If we want to have a single-source of truth, we need two things
- An abstract representation, DSLs are a natural fit
- Mappings to our target languages and technologies
CUE happens to be a good language and model for writing and validating both the represenation and mappings.
We believe that using a DSL, rather than native CUE expressions,
is the better option. There are many things which we cannot
express directly in CUE types and constraints, and using
attributes requires the tool to understand these.
So in order to provide maximal flexibility to experiment
without needing to modify
hof, we use DSLs.
Fortunatedly, CUE makes it easy to create and validate DSLs,
it’s just a perspective of CUE values afterall.
Another hard question is “is there a single type schema or DSL to rule them all?” Probably not, though one might be able to capture the majority of cases. As defined, the type DSLs and schemas can be extended or specialized, like any CUE value. This will give the community a way to combine and specialize them as needed.
A Type Schema
hof, we are building some resuable data model schemas.
This subsection will show you a simplified version for demonstration.
- example types used
Let’s use a blogging site as our example.
cue eval types.cue schema.cue --out yaml to see it’s final form
Now we have to implement the above schema in our target languages and technologies.
We will run all of the following with
hof gen types.cue schema.cue -T ...
Output will be put into the
We can start with a single template and file for all types.
hof gen types.cue schema.cue -T types.go
hof gen ... -T "types.go;out/types.go" to write to file