product types

Product types are one of the two composite types in tasl - that means they're one of the ways that we can build "bigger" types out of smaller ones. In other contexts, they're also called structs, maps, records, tuples, vectors, or objects.

Product types correspond to the idea of "AND" or combination.

A product type is written as map from URI keys to types, using curly braces {} and right arrows ->. We call the entries in a product type components, and the two parts of each component are the key (the URI) and the value (the type). Each component of a product type has to be on its own line.

It's sometimes confusing to use the word "value" to refer to the type that a component maps to, but usually there's enough context to tell whether "value" means a type-in-a-component or an actual concrete instance-of-a-type value.

We've already seen several product types in action:

namespace s namespace ex class s:Person { ex:favoriteColor -> string ex:birthday -> dateTime }

The curly braces aren't part of the class declaration (like they would be in JavaScript, for example) - the grammar for declaring a class is just "class uri type". The curly braces define an inline product object with two components. The first component has key ex:favoriteColor and value string; the second component has key ex:birthday and value dateTime.

The value of a product type has a value for every one of its components.

unit types

An important special case of product types is the empty product type, also called the unit type.

In some ways, the unit type resembles a "null" type; in other contexts it can be used to indicate "nodes" or a raw concept of "identity". For example, here's a schema for directed graphs:

namespace ex class ex:Node {} class ex:Edge { ex:source -> * ex:Node ex:target -> * ex:Node }

Here, an instance of the schema can have many distinct elements for the class ex:Node. But each of these elements will have the same empty unit value. What this really means is that our schema describes an unlabelled directed graph: one where nodes don't have externally-accessible identity.

Unit are especially powerful when combined with coproduct types, so we'll see more examples of them in action over there.