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

Well, there are two parts to it. Here's my take on it, influenced heavily by talking to Conal about it.

The importance of nice denotational semantics is that they fully define the abstraction and make it easy to think about. In the end, all it means is that you have a simple but complete mental model for what the abstraction is supposed to be that you can manipulate in your head. Since the model is formal, there's no fuzziness and no room for implementation-defined behavior.

The description is crisp and complete. There's no room for uncertainty: any question about how the abstraction is supposed to behave can be answered by manipulating well-understood objects—plain functions or pairs in this case. It's easier to reason—even informally—about well-defined mathematical objects than about vague ideas written out in prose.

Personally, I wish all my abstractions were like that. A tall order!

The importance of continuous time in the semantics is a bit more subtle. It's one of the things that has made implementing general-purpose FRP efficiently tricky.

Why is continuous time useful? Composability.

Think about it as the difference between vector graphics and raster graphics. We can combine vector graphics from different sources at different scales without losing any information—with raster graphics, things would get blurry. We can transform vector graphics in arbitrary ways without losing information. We can manipulate parts in all sorts of different ways without losing any precision at the seams.

We only have to approximate at the very end when we render to a physical screen and we have complete control over how we approximate: things like anti-aliasing only get applied at the very end and are never baked into the actual data.

The goal with continuous time for reactive programs is to make them compose and transform just like vector graphics components. You should be able to define behaviors in different places and combine them without worrying about how their sampling rates interact. (Which is really difficult without continuous time!)

You should also be able to take an arbitrary component of your reactive program and transform it, like changing the tweening function on animations. For example, it would be great to add quadratic easing to animations in your UI without having to modify the animation code directly. With continuous time, you could just apply the easing function to the existing behavior without worrying about jerky movements or sampling.

To me, this whole idea is incredible. You'd be able to manipulate interactive components of your UI directly: the behavior of your code over time would be a completely first-class citizen. And you wouldn't have to worry about sampling issues from your system, which I've found difficult in the past. (I had a really hard time implementing drag and drop in JavaScript in part because the way mousemove events fire as the mouse is moving is inherently confusing.)

Of course, as I mentioned, it's unclear how to implement this efficiently right now. But is it fundamentally impossible? I don't think so. We've managed to make a whole bunch of seemingly absurd abstractions efficient in the past: virtual memory, garbage collection, even procedure calls. Why not arbitrary-precision numbers followed by continuous time FRP?



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

Search: