11

I have been experimenting with creating a Functional Reactive Programming framework for Scala. One thing at the moment I am confused about is how current implementations have dealt with representing behaviours at the top level. To explain what I mean I'll give an example. Say I have a JPanel and I want to do this:

 JPanel panel = new Panel()
 panel.setBackground(new Behaviour(time => Color.red))

Although the color is static here we want the panel background to update when the value of the Behaviour updates. The way I have done it so far is to essentially create a discretized Behaviour using Events (accessible via a changes function on Behaviours). This is basically just an event source that occurs whenever the Behaviour changes. Using this the implementation of setBackground here would be:

def setBackground(color : Behaviour[Color]) {
  super.setBackground(color.now)
  color.changes.each(change => super.setBackground(change))
}

This feels kind of messy. Does anyone have any suggestions of whether this is a bad approach or not? I have been looking at Elliott's Push-Pull FRP today and it feels like I might be going in the right direction but getting lost somewhere.

EDIT: If no one has a definite clear cut solution then ideas/thoughts would be great!

Conal
  • 18,206
  • 2
  • 34
  • 40
seadowg
  • 4,033
  • 6
  • 32
  • 43
  • 5
    I'm willing to add some bounty to a question that asks a translation of the paper to Scala. – ziggystar Oct 14 '11 at 17:46
  • @ziggystar I agree that would be amazing. One of main problems with researching FRP is having to crawl through unfamiliar Haskell syntax. Would that be correct to ask for on Stack Overflow though? – seadowg Oct 14 '11 at 17:47
  • Maybe the only point against it is that questions should be reasonably scoped. Thus answers should not get too lengthy. But I think the question itself is ok for SO. But translating the paper on a reasonable level takes some time. I'd more suspect it to be posted on a blog. – ziggystar Oct 14 '11 at 17:52
  • You might get your answer here: http://stackoverflow.com/questions/5095728/whats-the-status-of-scala-react – Szabolcs Berecz Oct 14 '11 at 21:23
  • @Szabolcs the problem there is that Scala.react isn't really FRP. Thanks for the link anyway though. – seadowg Oct 14 '11 at 22:46
  • @Conal Sorry for the misspelling :S – seadowg Oct 17 '11 at 18:09

1 Answers1

6

Two things:

  1. In Conal Elliott's original vision, behaviors are continuous in time, so they don't come with a function changes that indicates when they change.

    The behavior that returns the current clock time would be the prime example of a continuous behavior. It doesn't support a changes function, unless you specify a time step ("it generates a 'change' event every nanosecond"). But the point of "continuous" is the lack of a time step.

    In my view, this means that behaviors in Conal's sense don't support incremental updates at all. In my reactive-banana library, I have introduced a new data type Discrete that is some kind of hybrid between behaviors and events. See the documentation of the module Reactive.Banana.Incremental for more details on the rationale.

  2. You are probably annoyed by having wrap each and every GUI function like setBackground to make it work with behaviors instead of plain values. This is were higher-order functions really shine: the wrapper is always the same, you can express it as a higher order function; here a Haskell version:

    set' :: Property a -> Behavior a -> IO ()
    set' property behavior = do
         set property (now behavior)
         each (\a -> set property a) (changes behavior)          
    
    each f event = reactimate (fmap f event) -- helper definition
    
    example = set' background red
    

    Of course, this relies a lot on Haskell's syntax and may not be as pleasant in Scala, where some functions are written before their first argument.

Heinrich Apfelmus
  • 11,039
  • 1
  • 35
  • 66
  • I had though about a `set` like function and yes it isn't quite as nice in Scala (mainly due to the fact the `background` property and others are generally not available from outside the class). However it looks like its the best way to do it. Also, just to confirm that the Behaviours in my implementation are actually continuous. The `changes` function returns an EventSource that listens for changes to the Behaviour (its more of a utility than anything). What is the `reactimate` function here out of interest (and is `changes` referring to my `changes`)? – seadowg Oct 15 '11 at 11:36
  • @Oetzi: Well, the behavior that returns the current clock time would be the prime example of a continuous behavior. You can't really write a `changes` function for it, because it changes "all the time". – Heinrich Apfelmus Oct 15 '11 at 18:14
  • @Oetzi: The `reactimate` function is part your `.each` function; the latter decomposes into an `fmap` and a `reactimate` part. The `changes` functions are supposed to be the same. – Heinrich Apfelmus Oct 15 '11 at 18:18
  • I understand that technically the `changes` function isn't accurate. However how would you represent the color behaviour here is what I'm asking. Would you use a Discrete instead of a Behaviour? – seadowg Oct 16 '11 at 16:08
  • @Oetzi: Yes, I would use the `Discrete` type. Then again, there's also the option of trying to implement Behaviors in a way that uses a `changes` function internally for efficiency but does not export it; this would avoid the unfortunate duplication of functionality by the `Discrete` type. Or you can make `Behavior` discrete by default, but that complicates the semantics a bit (no more continuous `Behavior a = Time -> a`). It's up to you and your taste, I'd say. – Heinrich Apfelmus Oct 16 '11 at 20:31
  • The first way is how I currently do it. Thanks for all the thoughts! – seadowg Oct 16 '11 at 20:33