Another angle on functional future values

An earlier post introduced functional future values, which are values that cannot be known until the future, but can be manipulated in the present. That post presented a simple denotational semantics of future values as time/value pairs. With a little care in the definition of Time (using the Max monoid), the instances of Functor, Applicative, Monad are all derived automatically.

A follow-up post gave an implementation of Future values via multi threading. Unfortunately, that implementation did not necessarily satisfy the semantics, because it allowed the nondeterminism of thread scheduling to leak through. Although the implementation is usually correct, I wasn’t satisfied.

After a while, I hit upon an idea that really tickled me. My original simple semantics could indeed serve as a correct and workable implementation if I used a subtler form of time that could reveal partial information. Implementing this subtler form of time turned out to be quite tricky, and was my original motivation for the unamb operator described in the paper Push-pull functional reactive programming and the post Functional concurrency with unambiguous choice.

It took me several days of doodling, pacing outside, and talking to myself before the idea for unamb broke through. Like many of my favorite ideas, it’s simple and obvious in retrospect: to remove the ambiguity of nondeterministic choice (as in the amb operator), restrict its use to values that are equal when non-bottom. Whenever we have two different methods of answering the same question (or possibly failing), we can use unamb to try them both. Failures (errors or non-termination) are no problem in this context. A more powerful variation on unamb is the least upper bound operator lub, as described in Merging partial values.

I’ve been having trouble with the unamb implementation. When two (compatible) computations race, the loser gets killed so as to free up cycles that are no longer needed. My first few implementations, however, did not recursively terminate other threads spawned in service of abandoned computations (from nested use of unamb). I raised this problem in Smarter termination for thread racing, which suggested some better definitions. In the course of several helpful reader comments, some problems with my definitions were addressed, particularly in regard to blocking and unblocking exceptions. None of these definitions so far has done the trick reliably, and now it looks like there is a bug in the GHC run-time system. I hope the bug (if there is one) will be fixed soon, because I’m seeing more & more how unamb and lub can make functional programming even more modular (just as laziness does, as explained by John Hughes in Why Functional Programming Matters).

I started playing with future values and unambiguous choice as a way to implement Reactive, a library for functional reactive programming (FRP). (See Reactive values from the future and Push-pull functional reactive programming.) Over the last few days, I’ve given some thought to ways to implement future values without unambiguous choice. This post describes one such alternative.

Edits:

Continue reading ‘Another angle on functional future values’ »

Prettier functions for wrapping and wrapping

The post Semantic editor combinators gave an example of a pattern that comes up a lot for me in Haskell programming. I want to apply functions inside of a newtype without cumbersome unwrapping and wrapping of the representation insides.

While chatting with Daniel Peebles in #haskell today, the realization hit me that these “higher-order wrappers” can not only make other code pretty, but can themselves be expressed more beautifully and clearly, using two of the combinators given in that post.

Continue reading ‘Prettier functions for wrapping and wrapping’ »

Semantic editor combinators

While working on Eros, I encountered a function programming pattern I hadn’t known. I was struck by the simplicity and power of this pattern, and I wondered why I hadn’t run into it before. I call this idea “semantic editor combinators”, because it’s a composable way to create transformations on rich values. I’m writing this post in order to share this simple idea, which is perhaps “almost obvious”, but not quite, due to two interfering habits:

  • thinking of function composition as binary instead of unary, and
  • seeing the functions first and second as about arrows, and therefore esoteric.

What I enjoy most about these (semantic) editor combinators is that their use is type-directed and so doesn’t require much imagination. When I have the type of a complex value, and I want to edit some piece buried inside, I just read off the path in the containing type, on the way to the buried value.

I started writing this post last year and put it aside. Recent threads on the Reactive mailing list (including a dandy explanation by Peter Verswyvelen) and on David Sankel’s blog reminded me of my unfinished post, so I picked it up again.

Edits:

  • 2008-11-29: added type of v6 example. Tweaked inO2 alignment.

Continue reading ‘Semantic editor combinators’ »

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”).

Blending continuity into reactive values

This post continues from “Reactive values from the future” and “Reactive normal form”.

Fran/FRP reactive behaviors could change continuously, while reactive values change only discretely. The Reactive library keeps continuity orthogonal to reactivity. To combine continuity and reactivity, simply compose reactivity with a non-reactive type of functions of time.

Continue reading ‘Blending continuity into reactive values’ »

Paper draft: “Applicative Data-Driven Computation”

I would love to get comments on a short (4.5 page) paper draft called “Applicative Data-Driven Computation” (Haskell wiki page), which describes a very simple approach to data-driven (push-based) computation and its application to GUI programming. There’s a “Talk page” link for discussion.

I’m also very interested in suggestions and (better yet) collaboration on other applications of data-driven computation beyond GUIs, say push-based internet apps.

Software releases: TypeCompose, Phooey, GuiTV

Three related software releases. I am very interested in comments and contributions.

TypeCompose provides some classes & instances for forms of type composition. It also includes a very simple implementation of data-driven computation. I factored it out of a new implementation of Phooey. Phooey is a library for functional user interfaces. Highlights in this 0.3 release:

  • Uses new TypeCompose package, which includes a simple implementation of data-driven computation.
  • New Applicative functor interface.
  • Eliminated the catch-all Phooey.hs module. Now import any one of Graphics.UI.Phooey.{Monad ,Applicative,Arrow}.
  • Phooey.Monad has two different styles of output widgets, made by owidget and owidget’. The latter is used to implement Phooey.Applicative.
  • Self- and mutually-recursive widgets now work again in Phooey.Monad. They wedge in Phooey.Arrow and Phooey.Applicative.

Phooey is also used in GuiTV, a library for composable interfaces and “tangible values”. I’ve also just updated GuiTV to 0.3, to sync with Phooey 1.0.