Tenet language

Tenet is an intuitive language to share data between systems with consistent and reliable semantics.


Right now the source is on gitlab.


This is a tech demo at the moment, so these examples let you see how the compiler works step by step. When Tenet has a working compiler, the site will be refocused on the target audience.

CodeMirror didn't run; is Javascript enabled?


Tenet lets you define complex types using tuples, unions, enums, lists, sets, maps, strings and integers. Read more.

type Category :=
    #raw_material          |  ;; | splits up parts of a union
    work_in_progress ~ Int |  ;; #enums and complex parts may be mixed.
    #finished_good         |
    #service_inventory     |
    #transportation        |
    future ~ Str;

type Inventory := (       ;; This is a record type.
    sku: Str,
    item_name: Str,
    alt_names: [Str],     ;; Represents a list of names
    category: Category,
    vendor: Str,
    inventory_count: Int,
    base_price: Int

;; This will be accepted as a member of Category.

let cat = #finished_good;

;; This will be accepted as a member of Inventory.

let inv = (
    sku: "AZAZ1234",
    item_name: "Box",
    alt_names: [],        ;; Empty lists have a well-defined implicit type.
    category: #raw_material,
    vendor: "Boxes, Inc.",
    inventory_count: 500,
    base_price: 12

;; Note the empty set. This works in Tenet, but can't be exported as some languages can't declare containers with an
;; empty type. Tenet prohibits exporting such a value to avoid requiring a type change to add a new language. We can
;; make it exportable by annotating the type.

let inv_exportable : Inventory := inv;


Unlike most serialization languages, Tenet is fully programmable, so you can define complex behavior along with types, but it has very predictable and simple semantics.

func inventory_summary(inventory: [Inventory]) {
    ;; Construct an empty map.
    summary := {:};
    for entry in inventory {
        ;; Extract the fields we're interested in.
        (category, vendor) := entry;
        ;; Tenet supports complex keys in maps.
        key := (category:, vendor:);
        ;; Count the items found, by defaulting to 0.
        if key not in summary {
            summary[key] := 0
        summary[key] += 1
    ;; Returns the combined map.
    return summary

More examples

There are some more examples.


How does it work?

To compile to different languages, you first need to simplify everything down to a common micro-language, and then rewrite that into the target languages.

Different languages only have a few things in common we can largely depend on, such as user-defined functions, local variables, etc. Even things like for-loops aren’t available in all languages.

The underlying principle used here is the same as any compiler: take a tree and repeatedly modify it.

As you perform those modifications, you simplify the problem slightly. For instance, Tenet is faux-mutable, so one step is “delensing” which means converting a.b := c into a := !!set_slot(a, "b", c).

The last tree will be the target language’s syntax, and then that can be written out as text.