Al Dente


 * This page is very much a work in progress.

Al Dente is an esoteric programming language created by Tanner Swett in 2015, inspired by the paper "Chu Spaces: A Model of Concurrency".

By example
A program consists of a set of classes. The following is an example of a class:

Abc { a; b; c; }

Like in an object-oriented language, a class is a type whose instances are objects, and the state of an object consists of the states of the object's attributes. In the  class, ,  , and   are event attributes.

An event has two possible states, unfired and fired. Initially, all events are unfired. There are no instructions or flow control; instead, the way execution works is that events spontaneously fire in an unspecified order (possibly simultaneously), subject to restrictions specified by the program. Once an event fires, it can never go back into the unfired state.

Any given  object, therefore, has eight possible states. These states can be restricted by adding restriction declarations, like so:

Abc { a; b; c; a requires b; }

The  restriction prohibits all states where   has fired but   has not. This version of, therefore, has only six possible states. Another example:

Abc { a; b; c; b excludes c; }

The  restriction prohibits those states where both   and   have fired. This means that once either  or   has fired, the other event can never fire. Again, there are six possible states. The two restrictions can, of course, be combined:

Abc { a; b; c; a requires b; b excludes c; }

Now there are only four states: that where no event has fired; that where only  has fired; that where   and   have both fired; and that where only   has fired.

(Note that we could completely prevent the event  from firing by writing  .)

Since events can fire simultaneously, there is nothing wrong with a definition like this one:

Abc { a; b; c; a requires b; b requires a; }

These restrictions prohibit any state where either  or   has fired but the other has not. However, it is still possible for both events to fire simultaneously. The restriction  is a synonym of   and   together.

Either side of a restriction declaration can be an expression built with the  and   operators. (There is no  operator, however.) For example:

Abc { a; b; c; (a and b) requires c; }

This definition prohibits any state where  and   have both fired but   has not.

Further code examples can be found at Al Dente examples.

Syntax
An Al Dente program consists of a sequence of tokens, optionally separated by whitespace. A token is a brace, a parenthesis, a semicolon, a period, or a case-sensitive sequence of English letters. A sequence of letters beginning with an uppercase letter is a class identifier; a sequence of letters beginning with a lowercase letter is a variable, unless it is one of the keywords "matches", "requires", "excludes", "and", or "or". Letter sequences must be separated by whitespace. Whitespace has no significance besides separating tokens.

The syntax, in EBNF, is:

::= [( ".")*] | "(" ")" | ("and" | "or")

The  operator takes precedence over the   operator, which takes precedence over the   operator. The  and   operators are associative.

Semantics
A program consists of a set of class definitions, each of which consists of a set of attribute declarations and restriction declarations. An attribute may be declared without a class, in which case it is an event attribute, or with a class, in which case it is an object attribute.

Each class defines a set of events; the events of a class are its event attributes, along with the disjoint union of its object attributes' events. This means that many classes will have infinitely many events. For example:

Chicago { alpha; beta; Chicago tail; }

This defines a class called, whose events are  ,  ,  ,  ,  , and so on. (Events are well-founded; an event only exists if it can be referred to using finitely many dots.)

Each class also defines a set of permissible states. Permissible states of a class are sets of events of the class; a set of events is a permissible state if and only if it is finite and it obeys all restriction declarations.

Restriction declarations fall into two categories: event restrictions and object restrictions.

An event restriction consists of a pair of expressions, made up of event attributes and the logical connectives  and , separated by  ,  , or. A  restriction states that the truth values of the expressions on either side must be equal (where the truth value of an event is true if it is in the set and false if it is not). A  restriction states that the expression on the left cannot be true while the expression on the right is false. An  restriction states that the expressions on either side must not both be true.

An object restriction consists of a pair of object attributes of the same class, separated by. This restriction states that the objects on either side must be in the same state.

Execution consists of starting in the state of an object containing no events, and repeatedly moving, in an unspecified manner, to a permissible state which is a superset of the current state. If the initial state is not permissible, undefined behavior occurs.