Flexible typing
Types defines constraints on the values used in the program. It can apply to data, functions, agents... Let's work by example again.
Data typing: to define what the data can be.
type IntPair = (Int, Int)
type People = [] of Person
type Person = Man | Woman
type Triple(x) = (x, x, x)
type Pos3D = Triple(Int)
type Anything = ?
Function typing: to define what are the input/output of functions
type StringManip = function(String) -> String
type Predicate = function(?) -> Bool
type Selector(x) = function([] of x) -> ([] of x)
Actors typing: to define which messages it can receive
...
Mixing them all together: if you want more complex stuff
type Extractor(x) = function(Predicate(x)) -> (function([] of x) -> x)
type MaybeDoubleExtractor(x) = Pair(Extractor(x)) | Nothing
...