Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

we're actually in the process of changing the name :)

EDIT: re FRP, you might find this Lambda The Ultimate post insightful: http://lambda-the-ultimate.org/node/4900

FRP has issues with openness and isn't real great at dealing with collections. It also forces you to express things kind of unnaturally (e.g. instead of "click this and increment x", you say "the counter is the count of all click events"). There are other methods of managing time, like Glitch[1] and Bloom[2] that seem more promising :)

[1]: http://lambda-the-ultimate.org/node/4910 [2]: http://boom.cs.berkeley.edu/



"It also forces you to express things kind of unnaturally (e.g. instead of 'click this and increment x', you say 'the counter is the count of all click events')"

I suppose it's personal preference, but I actually think that the latter of the two statements is much more understandable. This is why I like functional programming in general; a single value can be expressed as a declarative transformation of other pieces of data, making it clear how the value is derived. Using the imperative model, it's up to variable names and documentation to make it clear what 'x' is. It's like looking at one of those pictures that contains multiple shapes simultaneously; suddenly you see the one you haven't been seeing, and then you wonder how you didn't see it all along.


Explicitly manipulating events as a stream has performance problems; mainly time leaks. Another issue is that it makes debugging really difficult, as you've now converted much of your control flow (that you could step through) into data flow (that you cannot), while there is very little progress on building good data flow debuggers.

Finally, events are often manipulated in very tricky ways. Take the problem of implementing a drag adapter: you have to remember to capture the mouse on the down event and release your capture on the up event, but then you also need to capture widget and mouse positions on the down event so you can compute deltas that avoid sampling resolution problems on the move events. Rx always gets these two points wrong, which is very annoying, but they have to fudge it otherwise event stream processing can't win in elegance.


I haven't done any serious FRP, but thinking about your example of the drag adapter, wouldn't it be possible to do something like the following?

  - Declare a stream consisting of the composite of two stream: a mouse down and a mouse up
  - Map over the mouse down portion, transforming into an (x, y) coordinate
  - Map over the mouse up portion, transforming into an (x, y) coordinate
  - Produce a tuple of the two values
  - Use the resulting signal that determines what to do with the drag
In Bacon.js, I think it would look something like this (haven't tested it):

  var makeCoordinate = function(v) { return {x: v.clientX, y: v.clientY}; }
  var mergeStreams = function(v1, v2) { return {down: makeCoordinate(v1), up: makeCoordinate(v2)}; };

  var $html = $('html');
  var mousedownStream = $html.asEventStream('mousedown');
  var mouseupStream = $html.asEventStream('mouseup');
  var dragStream = mousedownStream.flatMap(function() {
    // Ensure that we only sample a single mousedown/mouseup pair.
    return Bacon.zipWith([mousedownStream, mouseupStream], mergeStreams).
        takeUntil(mouseupStream);
  };
I don't mean to be pedantic - your point is well taken. This was definitely a mental exercise to write, and I have no experience debugging (though I imagine it would be difficult).

EDIT: For this particular example I actually made it more complicated than it needs to be. Example JS Fiddle here: http://jsfiddle.net/w6mCK/


Compare with the control flow heavy managed time [1] version:

  on widget.Mouse.Down:
  | var pw = widget.position
  | var pm = widget.Mouse.Position
  after:
  | widget.Mouse.Capture()
  | widget.position = pw + (widget.Mouse.Position - pm)
  | on widget.Mouse.Up:
  | | widget.position = widget.position # freeze widget position
  | | break                             # stop the after block so capture/dragging stops
[1] http://research.microsoft.com/pubs/211297/managedtime.pdf


Well, I'm not a fan of the "use folds over time" concept either. FRP is too complex, but there's some great ideas there.

Would you say Aurora and these other languages are "reactive"? Or do you have a better term for it?

BTW: I'm reading "Toward a better programming" right now :)


Our current design takes a lot of ideas from Functional Relational Programming (http://shaffner.us/cs/papers/tarpit.pdf) and Bloom (http://bloom-lang.net/) as well as building on the ideas from Light Table.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: