Escher A language for connecting technologies using pure metaphors

Interpretations of circuits

A circuit in Escher is a generic data abstraction much like a structure is in JavaScript or Go. When thinking and programming in Escher, circuits will have a meaning dependent on context and/or content. A circuit interpretation will usually utilize a subset of the representational freedoms of a circuit, and will have an intuitive graphical representation.

Here we introduce four basic circuit interpretations—or specializations, if you will—that will also serve us as a vocabulary when discussing Escher in following chapters.

Series

Circuit gate names, recall, can be integers or strings. If a circuit has no links and the gate names are the integers 0, 1, …, K (for some integer K), we call the circuit a series. Series are equivalent to arrays and/or slices in other programming languages, like C and Go. Gate names are slice indices; gate values are slice element values.

For instance, the circuit

Singer {
	0 "Dolly"
	1 "Rebecca"
	2 "Parton"
}
is analogous (in meaning) to the Go slice:
var Singer = []interface{}{
	"Dolly",
	"Rebecca",
	"Parton",
}

Since series will be frequently input by the programmer, as explained in the syntax section, we have dedicated a shorthand syntax for series circuits that omits the gate names:

Singer {
	"Dolly"
	"Rebecca"
	"Parton"
}

Indices

More generally than series, when a circuit has no links we call it an index and we view it as a map from integers and/or strings to anything else. In this respect an index is akin in purpose to structures, dictionaries, hash tables and maps in other languages.

The gate values of index circuits are analogously called children and they can be of primitive types (integers, floats, etc.) as well as recursively they can be other circuits or indices.

Tree {
	Trunk {
		Branches {
			"Johnny"
			"Katie"
		}
	}
	Root {
		Tentacles {
			"Grandpa"
			"Grandma"
		}
	}
}

Such recursive structures of indices, or just indices for short, serve the same purpose as file-systems, namespaces, trees and others: To organize their internal and leaf values in a hierarchical manner, so that each node (internal or leaf) is identifiable by a unique path which we shall call address of a value relative to a given index.

For instance, the address of "Grandma" relative to the index Tree would be

{
	Root
	Tentacles
	1
}
(Note that addresses are represented by series circuits.)

Directives

Directives are a key building block of circuit programs (described next and in following sections). A directive is a pair of a string-valued verb and a target address. Directives are represented as a single circuit, wherein the empty-string gate holds the verb, while the number gates hold the components of the address. For instance,

{
	"" "*"
	0 Root
	1 Tentacles
	2 1
}

This circuit holds the verb value "*" and the address whose components are Root, Tentacles and 1, in that order. There are only two types of verbs, signified by the verb values "*" and "@", whose meaning is explained in later sections. We call these verbs materialize and recall, respectively, while their single-characters values, "*" and "@", are a design choice of expediency.

Due to the ubiquitous use of directives in circuit programs, directives can be written using the dedicated syntactic sugar:

*Root.Tentacles.1

Programs

Programs are circuits that describe executable systems. Their meaning and use is explained in a dedicated section. Here we describe their circuit structure.

The gates of program circuits ultimately represent independently executing services, which are interconnected according to the link pattern of the circuit.

Gate values designate the processing logic—i.e. they codify the service type—while gate names are used solely as identifiers, needed in the description of the circuit links.

Gate values can be of any kind: integer, float, complex, string or circuit. Often gate values will be directive circuits, in which case they can be written using the abbreviated syntax described earlier.

Circuit links are allowed only between gate names, defined within the circuit or the empty-string gate name.

The empty-string gate name represents an implicit “enclosing” or “parent” circuit. In particular, program circuits are not allowed to define a gate with the empty-string name.

Links whose endpoints are connected to the same gate name are allowed, as long as they connect into different valve names.

Here is an example of a valid program circuit:

{
	tkr *time.Ticker
	sum *math.Sum
	interval 1e9

	tkr:Duration = interval:
	tkr: = sum:Sum

	sum:X = :Phase
	sum:Y = *Show
}

And the corresponding symbolism: