2.2. Types

A reasonable description of a type is that it is a mathematical set of objects. For example, the type int is an approximation to the mathematical set \(\mathbb{Z}\), although there may be technological limitations on what values an object of type int can take.

Suppose, however, that an algorithm \(p(n_{\text{POT}})\) is configured to operate on an integer \(n_{\text{POT}}\) that corresponds to the number of protons on target. In such a case, specifying the function \(p\) as \(p: \mathbb{Z} \rightarrow R\) (where \(R\) is an arbitrary return type) is too permissive. In a framework context, not all data of type int (the equivalent to \(\mathbb{Z}\)) are suitable for processing by the algorithm \(p\).

In this document, the type therefore refers to a mathematical set that includes more than just the programming language’s type T; it can also include various labels that identify which kind of T is desired. When necessary, the type required to specify a data product will be expressed as \(\mathtt{T} \wedge L\), where the first set in typewriter style (e.g. \(\mathtt{T}\)) refers to the programming language’s type and the second set in math style (e.g. \(L\)) represents a label associated with the data.

2.2.1. Representing void and NoneType

In HEP, it is common to encounter C++ functions like:

void f(int);
double g();

where the function either returns nothing (i.e. void) or it accepts no argument. Python supports similar behavior for its functions and methods, but using the keyword None instead of void.

The mathematical set that is used to represent C++’s void and Python’s NoneType is the set \(\one\), which contains only one element [1]. The above functions are thus represented in function notation as:

\[ \begin{align}\begin{aligned}f&: \mathbb{Z} \rightarrow \one\ , \text{ and}\\g&: \one \rightarrow \mathbb{R}\ .\end{aligned}\end{align} \]

This notation will be used as we discuss the operators required by Phlex’s higher-order functions.

The single element of the set \(\one\) can also be used to represent the value nullptr for C++ pointers (see Section 2.2.2).

2.2.2. Representing optional types

It is occasionally necessary to represent a “nullable” or “optional” type \(\text{Opt}(T)\), whose objects either contain a value type \(T\) or are null. Mathematically, this is represented by the coproduct \(T \sqcup \one\), where a null or disengaged object of type \(\text{Opt}(T)\) has a value equal to the single element of the set \(\one\).

Table 2.1 gives examples of programming types in various languages that can be mathematically represented by \(\text{Opt}(T)\). Although Phlex does not support algorithms written in Haskell, an example of the use of Maybe T is given as an illustration of how \(\text{Opt}(T)\) is supported outside of C++ and Python.

Table 2.1 Optional types in Haskell, Python, and C++. Due to Python’s dynamic nature, a given name (e.g. k) can be bound to any value, thus emulating an optional type.

Language

Type \(T\)

Type \(\text{Opt}(T)\)

Engaged value

Disengaged value

Haskell

Int

m :: Maybe Int

m = Just 6

m = Nothing

Python

int

See caption

k = 5

k = None

C++

int

std::optional<int> i;

i = 4;

i = std::nullopt;

int const* j;

j = new int{4};

j = nullptr;

Footnotes