Escher A language for connecting technologies using pure metaphors

Programs and materialization

Materialization is the process of creating and executing a system of interconnected reflexes, wherein the system is specified by a circuit called a program.

Materialization takes as input an index (of circuit programs and other reflex materializers) and a circuit program to materialize. The result of materialization is the creation and execution of the system of reflexes described by the circuit program, as well as a residual value.

Circuit programming

A program circuit describes a system of interconnected reflexes.

Each circuit gate corresponds to a reflex. The gate value describes the type of reflex that is to be materialized. While the gate name is merely an identifier, unique to the program circuit, used mainly to enable the specification of the reflex-to-reflex links. The relation between gate values and materialized reflexes is explained later.

In a valid program circuit, a gate whose name is the empty string must not be defined. The empty-string gate is reserved for the super gate, which (detailed later) designates an “enclosing” circuit.

The circuit program's links connect pairs of reflex-valve endpoints. Links are allowed either between two gates defined within the circuit, or between a defined gate and the super gate.

Links connected to the super gate are endpoints whose eventual connection to a reflex is defered to the enclosing circuit.

Circuit programs that have no links to the super gate are called closed circuits, as they describe complete materializable systems on their own.

On the other hand, circuit programs that have links to the super gate can only be materialized as reflexes within higher-level enclosing circuits.

Gate value interpretation

Circuit programs recognize the following types of gate values:

Noun reflexes

Gate values in the first group (integer, float, complex, string or a non-directive circuit) will result in the materialization of a “noun” reflex, whose noun value is the gate value.

A noun reflex is a generic built-in reflex type which, after materialization, emits its corresponding gate value to each one of its connected valves. If no valves are connected, the noun reflex leaves the gate value as its residue. Otherwise, it leaves no residue.

Expanding directives

When the gate value is a directive, materialization proceeds as follows:

Circuit residue

As pointed out in the section on reflexes, every reflex can leave a residue value as a result of being materialized, or the Go value nil which indicates leaving no residue.

Circuit programs are no different than reflexes (in fact they describe higher-order reflexes themselves) in that they leave a residue value as well.

The residue of materializing a circuit program is the same circuit, wherein each gate value is replaced by the residue of materializing that gate. Gate corresponding to reflexes that leave no residue are not present in the residue circuit.

If no gates leave any residue, the circuit program itself leaves no residue.

Example with an illustration

Consider, for instance, the following index:

{
	Database {
		cache Cache
		left Shard
		right Shard
		link Link

		cache:Web = :Web
		left:Cache = cache:Left
		right:Cache = cache:Right
		left:Backup = link:Left
		right:Backup = link:Right
		link: = :Backup
	}
	App {
		web Web
		left Database
		right Database
		backup Backup

		left:Web = web:Left
		right:Web = web:Right
		left:Backup = backup:Left
		right:Backup = backup:Right
	}
	Web …
	Cache …
	Shard …
	Link …
}

Here App and Database are program circuits and their symbolic representation is shown below. Whereas assume that Web, Cache, Shard and Link (whose definition is not given in this listing) are reflex materializers.

If we materialize the program circuit App with respect to the index given above (i.e. directive addresses will resolve with respect to that index), we are going to get the following residue:
{
	web WebResidue
	bkp BackupResidue
	db1 {
		shard1 Shard1Residue
		shard2 Shard2Residue
		cache CacheResidue
		link LinkResidue

		cache:Web = :Web
		left:Cache = cache:Left
		right:Cache = cache:Right
		left:Backup = link:Left
		right:Backup = link:Right
		link: = :Backup
	}
	db2 {
		shard1 Shard1Residue
		shard2 Shard2Residue
		cache CacheResidue
		link LinkResidue

		cache:Web = :Web
		left:Cache = cache:Left
		right:Cache = cache:Right
		left:Backup = link:Left
		right:Backup = link:Right
		link: = :Backup
	}
	left:Web = web:Left
	right:Web = web:Right
	left:Backup = backup:Left
	right:Backup = backup:Right
}

Where WebResidue, BackupResidue, Shard1Residue, etc. are merely placeholders here for whatever the actual residue values of the respetive reflexes are. Visually the program residue could be represented as:

The actual executed system of interconnected reflexes which results from the materialization can be visualized like so:

This illustration does not correspond to a circuit data structure anywhere in the runtime. It is merely an illustration of the executed reflexes and their runtime connections.

Three ways to invoke materialization

One can materialize (i.e. execute) a program circuit given an index from three different places: from Go, from another program circuit (i.e. from Escher) and from the POSIX shell.

Materializing from Go

Package be provides the materialization method:

func MaterializeSystem(program interface{}, index, barrier Circuit) (residue interface{})

Argument program contains the program circuit, of Go type Circuit, that is to be materialized. Incidentally, the value of program can be any value recognized as a gate value in a circuit program as described earlier. Often one will pass a directive circuit as program.

Argument index holds the materialization index, relative to which directive addresses are interpreted.

The last argument, barrier, is to be set to nil.

The function returns the residue of the materialization process.

Materializing from Escher

One can recursively materialize circuits programs from within other circuit programs. This is accomplished using the built-in reflex escher.Materialize which is described in the materialization faculty section.

Materializing from POSIX

The Escher executable, which is explained in detail in the runtime section, will materialize a directive from the command-line:

% escher -src /src/app *app.Main