An embedded system is a smaller computer that is embedded in some larger system to solve a particular task, and often does so under memory and timing constraints. Embedded systems can be found everywhere---from high-performance computing machines all the way down to low-power devices like mobiles and tablets. Amongst such embedded devices, heterogeneous computing represents an interesting development, because these systems can outperform traditional ones by incorporating specialized processing capabilities to handle particular tasks.
This performance comes at a cost of increased complexity, as programmers need to account for differences in each unit's programming practises and capabilities. These issues are further aggravated by the fact that embedded systems are predominantly developed with low-level languages like C and Assembler. While these are good for extracting maximum performance from a system, they provide little to no abstractions for easing development, and will inadvertently end up tying their code to whatever computing element it is supposed to run on.
In general, writing software for heterogeneous systems demands that we generalise functionality and abstract away from particular architectures. On the other hand, performance relies on the ability to tailor designs and configurations to a particular environment. While the desire for performance seems to go against the above desire for modular and generic programs, we note that such optimisations should primarily be considered late in development; a strong focus on performance during the initial development of a system is a kind of premature optimisation.
We therefore argue that the development of embedded heterogeneous systems can benefit from ideas in functional programming, since it provides the abstractions and modularity necessary to quickly build software in a modular manner without having to worry about implementation details. In particular, functional languages have:
- Functions that are higher-order and thus allow us to abstract over entire algorithms, not just values.
- Functions that are free from side effects, which is great when reasoning about a program's behaviour.
- Lazy evaluation, which avoids needless or intermediate values.
- A rich type system that allow us to write generic functions constrained only by the functionality they require.
These attributes allow us to delay many of a system's design choices until later stages of development, and promotes re-usable and modular programs. Then, once a satisfying design has been reached, we could use a compiler to turn its functions into optimized programs in, for example, C.
In response to challenges of heterogeneous systems, and the potential benefits of functional programming, we have construct a functional language that is specifically designed for the implementation digital signal processing algorithms way with predictable performance. The language allow users write to programs in a generic and compositional way, which in turn enable us to quickly explore different designs.