Ko

A language for programming recursive circuits

Ko
2. Language
2.2. Type system
2.2. Type system

The type system utilized by Ko is a “common denominator" of industry-wide protocol type systems, like Protocol Buffers , GraphQL , Apache Thrift and others, together with one additional type, called a “variety”, which corresponds to closures in other programming languages.

The type notations shown in this chapter are used by the compiler to report to the programmer (e.g. in the context of error messages). The Ko programmer does not need to define types explicitly. They are inferred from the structure of programs and the utilized externally-implemented transformations, which introduce concrete type constraints into a program.

The value notations shown here are used both for writing these values in source code, as well as for printouts by the compiler.

Constant literals

Ko supports constant literals for integers, floating-point numbers, strings and booleans.

String literals can be escaped double-quoted, e.g. "foo\nbar" , or backquoted `verbatim string` for verbatim interpretation.

Boolean literals can be either true or false .

Integer and floating-point literals use standard conventions, e.g. -123 and 2.13e-2 respectively.

Basic types

The basic types in Ko are:

Bool, String
Int8, Int16, Int32, Int64
Uint8, Uint16, Uint32, Uint64
Float32, Float64
Values for the basic types are printed as their corresponding literals.

Sequence type

One can have a sequence type from any element type T , written as (T) , i.e. using brackets surrounding the type T . This type is similar to slices in Go, or the “repeated” type in Protocol Buffers.

A sequence type indicates that zero or more values of the element type will be present at runtime. Values for sequence types are written as a sequence of the element values, surrounded by round brackets. For instance, a value of type (String) might be ("Hello", "world") .

Optional type

One can have an optional type from any element type T , which is written as *T , i.e. using a star preceding the type T .

An optional type indicates that a value of the given element type may or may not be present at run-time. Iterated optional types, e.g. **T , cannot arise as the compiler takes care of collapsing those to *T .

Structure type

A structure type has a set of typed, named fields . For instance,

(
	A: Int64
	B: *String
	C: (Bool)
)
is a structure with three fields named A , B and C . Field A is a 64-bit integer; field B is an optional string; and field C is a sequence of booleans.

An example value for the above type would be written as

(
	A: 123
	B: "abc"
	C: (true, false)
)

Values for optional fields are omitted. E.g. the following value is also valid for the example struct type:

(
	A: 123
	C: (true, false)
)

Similarly, values for empty sequence-type fields can be omitted. E.g.

(
	A: 123
	B: "abc"
)

Varieties

A variety is analogous to a closure in other languages (like LISP). It is a first-class value that captures the name of a Ko transformation together with a list of arguments to be passed to the transformation on execution.

The type of a variety is denotated as in the following example:

github.com/kocircuit/kocircuit/strings.Join[
	String: (String)
	Delimiter: String
]
It starts with the full path of the Ko transformation being applied, followed by an argument structure which is identical to the notation for structure types, except for the use of square brackets [] , instead of round ones () .

Creating, augmenting and executing varieties is discussed in a dedicated chapter .