Virtualizing Real-World Objects in Functional Reactive Programming
We begin with a functional reactive programming (FRP) model in which every program is viewed as a signal function that converts a stream of input values into a stream of output values. We observe that objects in the real world -- such as a keyboard or sound card -- can be thought of as signal functions as well. This leads us to a different approach to I/O -- instead of treating real-world objects as being external to the program, we expand the sphere of influence of program execution to include them. We call this "virtualizing real-world objects", and we explore how even virtual objects, such as GUI widgets, and non-local effects, such as are needed for debugging and random number generation, can be handled in the same way.
Our methodology may at first seem naive -- one may ask how we prevent a virtualized device from being copied, thus potentially introducing non-determinism as one part of a program competes for the same resource as another. To solve this problem, we introduce the idea of a resource type that assures that a virtualized object is not duplicated and that I/O and non-local effects are safe. Resource types also provide a deeper level of transparency: by inspecting the type, one can see exactly what resources are being used. We use arrows, type classes, associated types, and type families to implement our ideas in Haskell, and the result is a safe, effective, and transparent approach to stream-based I/O.