dan.doel at gmail.com
Mon Jun 18 16:10:03 EDT 2007
On Monday 18 June 2007, Jon Harrop wrote:
> On Monday 18 June 2007 05:39:21 Derek Elkins wrote:
> > Not directed at Michael Richter specifically:
> > I don't normally say this stuff, but this discussion has drifted onto
> > topics that have nothing to do with Haskell. I personally would like
> > the parts unrelated to Haskell to be carried on off the list.
> I don't normally drag threads back on topic, but functional reactive GUIs
> seem to be pioneered by Haskell programmers. Can anyone explain what this
> idea is all about?
I'm certainly no expert on FRP, having only read a few papers and never really
used such a framework, so take what I say with a grain of salt.
However, it seems to me that the main idea behind it is that you should build
your GUI (or your robot controller, or whatever) by specifying relationships
between various elements, rather than thinking about events and imperative
happenings in your program.
For instance, say you want to have a button and a label, and have the label
display how many times the button's been clicked. In an average imperative
toolkit these days, you might do that something like:
gui = do b <- newButton
l <- newLabel
addClickCallback (updateLabel l) b
updateLabel l = do x <- getValue l
setValue (x+1) l
So, you have all your individual GUI components, and you install callbacks for
the events you want to know about, and mutate the state of the components
Now in FRP, you'd instead want to (in some sense) specify the relationship
between the label and the button, rather than writing some low-level
event-based code that results in such a relationship (I suppose it's a bit
like the difference between using triggers and referrential integrity
constriants in a relational database). However, when you do this, you want to
move away from the view of GUI components as imperative objects with hidden
state and such. So you instead think of them, abstractly, as functions
Time -> Value, or as streams of Values, or something like that. For the
example above, you might have:
type Label = Time -> Int
type Button = Time -> Maybe ()
Where a label has a value at any time, and at any time, a button is either
being clicked (Just ()) or it isn't (Nothing).
Now, your FRP toolkit should provide you with combinators so that you can do
label = count button
Where count takes a stream of pulses and produces a stream of values
corresponding to a running count of the number of pulses. Or, I suppose in
the robot world, you might have something that tracks your velocity, and
you'd be able to write:
position = integral velocity
The point being that it's much easier to figure out and write down the
relationships you want between various components in your program, and build
them compositionally out of various combinators, than it is to write
imperative, event-driven code and polling and whatnot.
At least, that's the impression I got when I read about it. I could be off. I
hope that illuminates things a bit, and isn't too vague.
More information about the Haskell-Cafe