Functional Reactive Programming: Difference between revisions

From HaskellWiki
(→‎Introduction: Netwire 4 is now on HackageDB.)
(→‎Introduction: Removed Netwire-specific parts, replaced by generic introduction.)
Line 4: Line 4:
== Introduction ==
== Introduction ==
   
   
FRP is about domain-specific languages that capture the notion of
The original formulation of Functional Reactive Programming can be found in the ICFP 97 paper [http://conal.net/papers/icfp97/ Functional Reactive Animation] by Conal Elliott and Paul Hudak.
time-varying values. Let's take Netwire 4 as an example. You can install it either from HackageDB,


    cabal install netwire
=== Behaviors ===


or by grabbing the latest source code via darcs:
Traditionally a widget-based user interface is created by a series of imperative actions.  First an action is invoked to create an edit widget, then additional actions can be invoked to read its current content, set it to a specific value or to assign an event callback for when the content changes.  This is tedious and error-prone.


    darcs get http://darcs.ertes.de/netwire/
A better way to represent an edit widget's content is a time-varying value, called a ''behavior''.  The basic idea is that a time-varying value can be represented as a function of time:
    cd netwire
    cabal install


Imagine you have a simple GUI label that displays the number of seconds
<haskell>
passed since program start.  In an event-based model this is actually
newtype Behavior a =
quite a complicated task.  You would have to create a label and update
    Behavior {
it all the time using some form of timer/idle event.  In Netwire you
      at :: Time -> a
write:
     }
     myLabel = time


Now let's say you want to have the same GUI, but the time should start
myName :: Behavior Text
at 10 and pass twice as fast, so you actually want to display twice the
number of seconds passed plus 10:
    myLabel = 10 + 2*time


Imagine you want to display the string "yes" in a label:
myName `at` yesterday
</haskell>
    myLabel = "yes"


Now let's say you want to display "yes", when the space key is held down
This is only a theoretical model, because a time-varying value can represent something impure as well like the content of an edit widget, the current value of a database entry as well as the system clock's current time.  Using this model the current content of an edit widget would be a regular first class value:
and "no" otherwise:
    myLabel = "yes" . keyDown Space <|> "no"


You want to display time while pressed and "Press space" while not:
<haskell>
myEditWidget :: Behavior Text
    myLabel = fmap show time . keyDown Space <|> "Press space"
</haskell>


You want to display "yes" every other second and "no" otherwise:
In most frameworks there is an applicative interface for behaviors, such that you can combine them easily:
    myLabel = "yes" . holdFor 1 (periodically 2) <|> "no"


Imagine doing that with event-based code.
<haskell>
   
liftA2 (<>) myEdit1 myEdit2
Summary: FRP is about handling time-varying values like they were
</haskell>
regular values.
 
The result is a time-varying value that represents the concatenation of <hask>myEdit1</hask> and <hask>myEdit2</hask>This could be the value of a third widget, a label, to display the concatenation. The following is a hypothetical example:
 
<haskell>
do edit1 <- editWidget
  edit2 <- editWidget
  label <- label (liftA2 (<>) edit1 edit2)
  {- ... -}
</haskell>
 
Without behaviors you would have to write event callback ''actions'' for the edit widgets to ''update'' the label's content. With behaviors you can express this relationship declaratively.
 
=== Events ===
 
''To do''


== Libraries ==
== Libraries ==

Revision as of 16:50, 12 November 2013

Functional Reactive Programming (FRP) integrates time flow and compositional events into functional programming. This provides an elegant way to express computation in domains such as interactive animations, robotics, computer vision, user interfaces, and simulation.


Introduction

The original formulation of Functional Reactive Programming can be found in the ICFP 97 paper Functional Reactive Animation by Conal Elliott and Paul Hudak.

Behaviors

Traditionally a widget-based user interface is created by a series of imperative actions. First an action is invoked to create an edit widget, then additional actions can be invoked to read its current content, set it to a specific value or to assign an event callback for when the content changes. This is tedious and error-prone.

A better way to represent an edit widget's content is a time-varying value, called a behavior. The basic idea is that a time-varying value can be represented as a function of time:

newtype Behavior a =
    Behavior {
      at :: Time -> a
    }

myName :: Behavior Text

myName `at` yesterday

This is only a theoretical model, because a time-varying value can represent something impure as well like the content of an edit widget, the current value of a database entry as well as the system clock's current time. Using this model the current content of an edit widget would be a regular first class value:

myEditWidget :: Behavior Text

In most frameworks there is an applicative interface for behaviors, such that you can combine them easily:

liftA2 (<>) myEdit1 myEdit2

The result is a time-varying value that represents the concatenation of myEdit1 and myEdit2. This could be the value of a third widget, a label, to display the concatenation. The following is a hypothetical example:

do edit1 <- editWidget
   edit2 <- editWidget
   label <- label (liftA2 (<>) edit1 edit2)
   {- ... -}

Without behaviors you would have to write event callback actions for the edit widgets to update the label's content. With behaviors you can express this relationship declaratively.

Events

To do

Libraries


Publications and talks


Blog posts


People