Types

Types are definitions created to serialize data into structured forms. Types are used for managing communication between components, components can only connect and communicate with each other only if their type matches. Each component receives data stream described as a specific type, then component decodes it, process it and sends out data stream.

Types are defined based on ANTLR g4 format.

Possible Types

  • Atomic types: Int32, Int64, Bool, String, Bytes, Float, Double, UInt32, UInt64. String and Bytes are further categorized into variable size atomic and the rest are const size atomic.

  • Lists: Denoted by [], they represent an arbitrary, finite number of elements of the same type: [Int32]

  • Tuples: Represent an ordered collection of elements with static length and types. The syntax is similar to Python tuple: (Bool, String, a), (), (UInt64,), ...

  • Records (aka Structs): Like tuples, but unordered and with named fields: {name : String, age : UInt32, score : (UInt64, UInt64)}

  • Unions: Unordered collections of different types that represent elements that might be of any of the given types. E.g. Int32 | Int64; Bool | String; Image.BGR | Image.BGRA | Image.GRAY | Image.RGB | Image.RGBA

  • Named types: Any type can be given a name starting with an uppercase letter. The on-wire representation of a named type is the same as that of its base type, but the two are not directly compatible, though they can be converted amongst each other. E.g Person := {name : String, age : UInt32, score : (UInt64, UInt64)}, this is the named type Person that has their age, name and score for a competition It is possible to introduce a named type without content, i.e. with a single possible value, e.g. type Nothing := () which represents an empty tuple.

Basic named type definition

// DetectedClass is a type with named field 'id' and 'confidence' 
DetectedClass := {
    id: UInt64,
    confidence: Double
}

Named types can include other named types

// VideoFrame is image with timestamp given as Unix Epoch
VideoFrame := {
    image: Image,
    timestamp: UInt64
}

The language also supports type variables, similar to generics in Python or templates in C++. A type variable is an arbitrary name starting with lower case (to distinguish from types). They denote any single type and are scoped within a single component's definition. That is, the same variable refers to the same type everywhere within one component but not across two different components. E.g. a, b, myType

Named types can include generics

Point<t0> := {
    x:t0,
    y:t0
}

Type with a namespace

pipelogic.BoundingBox := {
    class: DetectedClass,
    rectangle: Rectangle<Double>,
    angle: Double
}

Empty named types can be used to represent an enum

// Creates types without content Image.BGR, Image.RGB, ...
Image.BGR := () 
Image.RGB := ()
Image.GRAY := ()
Image.RGBA := ()
Image.BGRA := ()

More complex named types definition

Image := {
    width: UInt64,
    height: UInt64,
    // format can be BGR, BGRA, ...
    format: Image.BGR | Image.BGRA | Image.GRAY | Image.RGB | Image.RGBA,
    data: Bytes
}

Next Steps:

Was this page helpful?