Sequences, streams, and segments

What kind of thing is a movie? Or a song? Or a trajectory from point A to point B? If you’re a computer programmer/programmee, you might say that such things are sequences of values (frames, audio samples, or spatial locations). I’d suggest that these discrete sequences are representations of something more essential, namely a flow of continuously time-varying values. Continuous models, whether in time or space, are often more compact, precise, adaptive, and composable than their discrete counterparts.

Functional programming offers great support for sequences of variable length. Lazy functional programming adds infinite sequences, often called streams, which allows for more elegant and modular programming.

Functional programming also has functions as first class values, and when the function’s domain is (conceptually) continuous, we get a continuous counterpart to infinite streams.

Streams, sequences, and functions are three corners of a square. Streams are discrete and infinite, sequences are discrete and finite, and functions-on-reals are continuous and infinite. The missing corner is continuous and finite, and that corner is the topic of this post.

infinitefinite
discreteStream Sequence
continuousFunction ???

You can download the code for this post.

Edits:

  • 2008-12-01: Added Segment.hs link.
  • 2008-12-01: Added Monoid instance for function segments.
  • 2008-12-01: Renamed constructor “DF” to “FS” (for “function segment”)
  • 2008-12-05: Tweaked the inequality in mappend on (t :-># a).

Continue reading ‘Sequences, streams, and segments’ »

Early inspirations and new directions in functional reactive programming

In 1989, I was a grad student nearing completion at Carnegie Mellon. Kavi Arya gave a talk on “functional animation”, using lazy lists. I was awe-struck with the elegance and power of that simple idea, and I’ve been hooked on functional animation ever since.

At the end of Kavi’s talk, John Reynolds offered a remark, roughly as follows:

You can think of sequences as functions from the natural numbers. Have you thought about functions from the reals instead? Doing so might help with the awkwardness with interpolation.

I knew at once I’d heard a wonderful idea, so I went back to my office, wrote it down, and promised myself that I wouldn’t think about Kavi’s work and John’s insight until my dissertation was done. Otherwise, I might never have finished. A year or so later, at Sun Microsystems, I started working on functional animation, which then grew into functional reactive programming (FRP).

In the dozens of variations on FRP I’ve played with over the last 15 years, John’s refinement of Kavi’s idea has always been the heart of the matter for me.

Lately, I’ve been rethinking FRP yet again, and I’m very excited about where it’s leading me.

The semantic model of FRP has been based on behaviors of infinite duration and, mostly on absolute time. Recently I realized that some problems of non-modular interaction could be elegantly addressed by switching to finite duration and relative time, and by adopting a co-monadic approach.

Upcoming post will explore these ideas.

Simplifying semantics with type class morphisms

When I first started playing with functional reactivity in Fran and its predecessors, I didn’t realize that much of the functionality of events and reactive behaviors could be packaged via standard type classes. Then Conor McBride & Ross Paterson introduced us to applicative functors, and I remembered using that pattern to reduce all of the lifting operators in Fran to just two, which correspond to pure and (< *>) in the Applicative class. So, in working on a new library for functional reactive programming (FRP), I thought I’d modernize the interface to use standard type classes as much as possible.

While spelling out a precise (denotational) semantics for the FRP instances of these classes, I noticed a lovely recurring pattern:

The meaning of each method corresponds to the same method for the meaning.

In this post, I’ll give some examples of this principle and muse a bit over its usefulness. For more details, see the paper Simply efficient functional reactivity. Another post will start exploring type class morphisms and type composition, and ask questions I’m wondering about.

Continue reading ‘Simplifying semantics with type class morphisms’ »

Simply efficient functional reactivity

I submitted a paper Simply efficient functional reactivity to ICFP 2008.

Abstract:

Functional reactive programming (FRP) has simple and powerful semantics, but has resisted efficient implementation. In particular, most past implementations have used demand-driven sampling, which accommodates FRP’s continuous time semantics and fits well with the nature of functional programming. Consequently, values are wastefully recomputed even when inputs don’t change, and reaction latency can be as high as the sampling period.

This paper presents a way to implement FRP that combines data- and demand-driven evaluation, in which values are recomputed only when necessary, and reactions are nearly instantaneous. The implementation is rooted in a new simple formulation of FRP and its semantics and so is easy to understand and reason about.

On the road to efficiency and simplicity, we’ll meet some old friends (monoids, functors, applicative functors, monads, morphisms, and improving values) and make some new friends (functional future values, reactive normal form, and concurrent “unambiguous choice”).

Pairs, sums, and reactivity

I’ve been noodling over a difference between behaviors (functions of time) and events (sequences of time/value pairs). A product of behaviors is isomorphic to a behavior of products, but a product of events is isomorphic to an event of sums.

Ba × Bb ≅ Ba × b

Ea × Eb ≅ Ea + b

A similar property has been noted for Fudgets-like stream processors.

Behaviors (or "reactive values") and events are inter-related. In particular, we can make a behavior from an initial value and an event, using the stepper function. If we want to use stepper with a pair value, we’d have to use a pair-valued event. However, it’s often more convenient and efficient to work with pair of separate change events, or (using the event pair/sum isomorphism) a sum-valued event.

This post plays with another perspective on sum types for events and stream processors. It can also apply to bots.

Continue reading ‘Pairs, sums, and reactivity’ »

Applicative bots

In Functional reactive partner dancing, I mentioned that (a) the partially applied leading and following types have boilerplate Applicative instances, and (b) the leading type corresponds to varying (reactive) values. Today I realized that those boilerplate instances are not very useful, and that they do not correspond to the Applicative instance of Reactive. In this post, I give a useful Applicative instance that does correspond to the Reactive instance. The instance definition is expressed in terms of the pair editor bot shown at the end of the “dancing” post, which seems to have a variety of applications.

The Applicative instance has one awkward aspect that suggests a tweak to the formulation of leading. I give simplified versions of pair editing and Applicative for the revised type. This change is in version 0.1 of the Bot libary.

Edit 2008-02-15: added FRP tags; prose tweak.

Continue reading ‘Applicative bots’ »

Functional reactive partner dancing