  Writing parallel codes is difficult and exhibits a fundamental trade-off
between abstraction and performance. The high level language abstractions
designed to simplify the complexities of parallelism make certain assumptions
that impacts performance and scalability. On the other hand lower level
languages, providing many opportunities for optimisation, require in-depth
knowledge and the programmer to consider tricky details of parallelism. An
approach is required which can bridge the gap and provide both the ease of
programming and opportunities for control and optimisation. By optionally
decorating their codes with additional type information, programmers can either
direct the compiler to make certain decisions or rely on sensible default
choices.
