The rationale behind Tenet

The basic pitch from the home page is:

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

Let’s unpack that statement.

Tenet is …

This is, as is the whole pitch, very much aspirational.

… an intuitive language …

Intuition is partly based on experience, so Tenet’s syntax closely tracks Python, a widely used language that has a huge mindshare and has proven itself with beginners, hobbyists and subject matter experts.

Intuition is also partly innate, so while Tenet is internally based on functional principles, its mechanisms to manipulate data are imperative. This is intended to make it accessible to subject-matter experts who aren’t professional developers. This also works well for its intended domain, which is to manipulate the complex data structures found in production applications.

The imperative form of Python is augmented with algebraic types and type inference.

# The types of both parameters can be inferred.
def double_numbers(numbers : List[Integer]) -> List[Integer]:
    result = []
    for num in numbers:
        num *= 2
        result += [num]
    return result

# A "tuple" is like a record or struct in other languages.
type Contact := Tuple:
    index: Integer
    name: String
    address: String
    city: String
    zipcode: String

# By inference, this has the same type as Contact.
my_contact = {
    index: 5, name: "Bob", address: "1234 Main St",
    city: "Whoville", zipcode: "12345"
}

Some possible objections

Terms like tuple and union aren’t intuitive. It’s true that the terms are less familiar to most readers. However, they’re opaque names that people can learn just as they did “record,” “struct” and “class,” and they are closer to what Tenet is doing. Also, while Python treats it as a sequence, the docs note that it’s for “hetereogeneous data.” A possible way to simplify it would be to make a shorthand the principle mechanism:

type Contact := {index: Integer, name: String}
type Alternates := foo ~ Integer or bar ~ String
type List := [Elements]
type Map := [Key: Value]

Though if Tenet used that, it would still have these things, and now people don’t know what they’re called.

People are used to reference semantics. Most people started with formal training in math, so they had to unlearn algebraic semantics first. I’d be happy to add a do-nothing copy function if it helps.

… to share data between systems …

The most successful solutions to this problem have been “almost” solutions such as JSON. JSON makes it trival to share JSON because JSON itself is so simple that most languages have structures that natively implement JSON; it’s really quite an ingenious solution and it works across a broad array of systems.

Other successful solutions limit themselves to a single very popular language, and are often the de facto serialization standard for that language. This solves the problem of interoperability by not trying.

If we look at solutions that attempt both, we still see major compromises. XML, for instance, was able to describe fairly complex data across multiple systems, but it required massive investments in tooling and provided a very broad surface for attacks. Software component models, such as COM or JavaBeans, take that approach even further, defining mechanism not only for data sharing, but for object reuse and embedding. The price you pay there is that you must be heavily invested in a software platform. I don’t compare Tenet to those directly as they’re more of a software platform than a serialization standard.

Tenet’s approach differs from XML and others in two major respects. One, its data types have a solid theoretical foundation, so they’re highly expressive despite being minimal. Two, it allows your project to provide the tooling it needs and will translate it to the native environment.

… with consistent and reliable semantics.

Sophisticated solutions like XML have consistent semantics of the document object model, and component models impose those semantics.

Other approaches will try to translate data types into native types that are merely analogous to each other. For example, integers are simple enough that the semantics of them are quite similar but there are still caveats.

Unlike other data serialization languages, Tenet lets you write functions to work with Tenet types to ensure reliable semantics.

Tenet is not aiming to be a secure or audited processor, though it could target a language that provides such facilities.