Flapjax – weaselhat http://www.weaselhat.com Thu, 27 Jan 2022 18:16:06 +0000 en-US hourly 1 https://wordpress.org/?v=6.3.2 Flapjax on PL Perspectives http://www.weaselhat.com/2019/12/03/flapjax-on-pl-perspectives/ http://www.weaselhat.com/2019/12/03/flapjax-on-pl-perspectives/#respond Tue, 03 Dec 2019 13:23:27 +0000 http://www.weaselhat.com/?p=768 Shriram Krishnamurthi, Arjun Guha, Leo Meyerovich, and I wrote a post about Flapjax on PL Perspectives, the SIGPLAN blog. (Thanks to Mike Hicks for helping us edit the post!)

Flapjax won the OOPSLA MIP award for 2009 (though the SIGPLAN website isn’t yet up to date). Our blog post is about the slightly unconventional way we worked: most of the Flapjax work happened in 2006 and 2007, but we didn’t even try to write the paper until several years later (Leo and I were in grad school). Rather than recapitulate those ideas, go read the post!

]]>
http://www.weaselhat.com/2019/12/03/flapjax-on-pl-perspectives/feed/ 0
Flapjax: A Programming Language for Ajax Applications http://www.weaselhat.com/2009/08/13/flapjax-2/ http://www.weaselhat.com/2009/08/13/flapjax-2/#comments Thu, 13 Aug 2009 16:00:29 +0000 http://www.weaselhat.com/?p=122 I am immensely pleased to report that our paper on Flapjax was accepted to OOPSLA 2009.

This paper presents Flapjax, a language designed for contemporary Web applications. These applications communicate with servers and have rich, interactive interfaces. Flapjax provides two key features that simplify writing these applications. First, it provides event streams, a uniform abstraction for communication within a program as well as with external Web services. Second, the language itself is reactive: it automatically tracks data dependencies and propagates updates along those data?ows. This allows developers to write reactive interfaces in a declarative and compositional style.

Flapjax is built on top of JavaScript. It runs on unmodi?ed browsers and readily interoperates with existing JavaScript code. It is usable as either a programming language (that is compiled to JavaScript) or as a JavaScript library, and is designed for both uses. This paper presents the language, its design decisions, and illustrative examples drawn from several working Flapjax applications.

The real heroes of this story are my co-authors. Leo, Arjun, and Greg were there for the initial, heroic-effort-based implementation. Jacob and Aleks wrote incredible applications with our dog food. Shriram, of course, saw the whole thing through. Very few of my contributions remain: the original compiler is gone (thank goodness); my thesis work is discussed briefly in How many DOMs? on page 15. Here’s to a great team and a great experience (and a great language)!

]]>
http://www.weaselhat.com/2009/08/13/flapjax-2/feed/ 1
Flapjax TR http://www.weaselhat.com/2009/04/15/flapjax-tr/ http://www.weaselhat.com/2009/04/15/flapjax-tr/#respond Wed, 15 Apr 2009 14:44:25 +0000 http://www.weaselhat.com/?p=82 After much hard work (by more productive people), there is a technical report describing Flapjax. Check it out!

]]>
http://www.weaselhat.com/2009/04/15/flapjax-tr/feed/ 0
Debounce and other callback combinators http://www.weaselhat.com/2009/03/25/callback-combinators/ http://www.weaselhat.com/2009/03/25/callback-combinators/#comments Wed, 25 Mar 2009 15:27:48 +0000 http://www.weaselhat.com/?p=77 It is serendipitous that I noticed a blog post about a callback combinator while adding a few drops to the Flapjax bucket.

Flapjax is nothing more than a coherent set of callback combinators. The key insight to this set of callback combinators is the “Event” abstraction — a Node in FJ’s implementation. Once callbacks are Nodes, you get two things:

  1. a handle that allows you to multiply operate on a single (time-varying) data source, and
  2. a whole host of useful abstractions for manipulating handles: mergeE, calmE, switchE, etc.

The last I saw the implementations of Resume and Continue, they were built using this idea. The more I think about it, the more the FJ-language seems like the wrong approach: the FJ-library is an awesome abstraction, in theory and practice.

]]>
http://www.weaselhat.com/2009/03/25/callback-combinators/feed/ 2
C# GC Leaks http://www.weaselhat.com/2007/11/17/c-gc-leaks/ http://www.weaselhat.com/2007/11/17/c-gc-leaks/#comments Sat, 17 Nov 2007 16:18:02 +0000 http://www.weaselhat.com/2007/11/17/c-gc-leaks/ Reading this experience report from the DARPA challenge via Slashdot, I wondered: if event registration caused object retention, how can we deal with these memory issues in Flapjax?

Worrying about memory leaks in JavaScript is a losing battle — the browsers have different collectors. But given functional reactive programming in other settings (e.g., Java/C#), how can we solve this kind of problem? We looked at deletion briefly, but never had time to address the issue in detail. The complexity in our case is that the event registration encodes the entire application — how do you decide that a certain code path is dead? It may be helpful to view a functional-reactive program as a super-graph of data producing, splitting, merging, and consuming nodes; the application state is the subgraph induced by the active nodes reaching the consumers. Then there’s a certain static overhead for the program, plus the dynamic overhead of its active components.

Most of the Flapjax code I’ve written has been for the user interface, so binding and unbinding isn’t much of an issue: if the interface changes temporarily (e.g., tabs), the older behavior is usually recoverable and shouldn’t be collected. When working with more complex models with longer lived state, a deletion policy is more important. Shriram has been working on larger Flapjax applications with application logic as well as presentation — I wonder if he’s run into serious GC issues.

]]>
http://www.weaselhat.com/2007/11/17/c-gc-leaks/feed/ 5
Lifting in Flapjax http://www.weaselhat.com/2007/08/11/lifting-in-flapjax/ http://www.weaselhat.com/2007/08/11/lifting-in-flapjax/#comments Sun, 12 Aug 2007 00:22:04 +0000 http://www.weaselhat.com/2007/08/11/lifting-in-flapjax/ In the Flapjax programming language, ‘lifting’ is the automatic conversion of operations on ordinary values into operations on time-varying values. Lifting gets its name from an explicit operation used with Flapjax-as-a-library; we use the transform method call or the lift_{b,e} functions. To better understand lifting, we’ll walk through a simple implementation of the Flapjax library.

I consider the (excellent) Flapjax tutorial prerequisite reading, so it will be hard to follow along if you’re not vaguely familiar with Flapjax.

The following code is all working JavaScript (in Firefox, at least), so feel free to follow along.

We’ll define a few functions and classes:

  1. timer_e, the simplest event stream
  2. Event, the class defining event streams
  3. showStream, a way to show event streams on the page
  4. lift_e, our focus, a way to apply standard operations to event streams
  5. hold_e, a lead in to behaviors
  6. Behavior, event streams that continuously have a value
  7. lift_b, lift_e extended to Behavior

It really will help to follow along, typing in the code: it helped me when I wrote all of this back in March! I could post the collated code from this, but I don’t see the point: it’s all here. If you’d like to see it, just ask away.

Our first event stream: timer_e

We’ll jump right in and define timer_e. timer_e is a timer that fires events at a given interval. JavaScript veterans will ask: how does timer_e differ from window.setInterval? The DOM API function window.setInterval registers a callback: it takes a function and an interval i, and calls the function every i milliseconds. timer_e takes an interval i and returns an event stream; every i milliseconds a new value (the time in milliseconds since the Epoch) will come down the event stream.

The key difference is that window.setInterval doesn’t return anything: you give it a callback, your callback gets called. timer_e gives you a handle to a value that encapsulates the timer itself. This is useful because the timer can be passed around as a value, allowing you to abstract out that part of your program.

function timer_e(millis) {
  var e = new Event();
  window.setInterval(
    function () { e.newValue(new Date().getTime()); },
    millis);
  return e;
}

Every time the interval — a repeated timer — triggers, the current milliseconds-since-epoch will be sent as a new value on the event stream.

The core event-stream structure: Event

We can make this more concrete by defining Event.

function Event() {
  this.listeners = [];
  this.newValue = function (v) {
    for (var i = 0;i < this.listeners.length;i++) {
      this.listeners[i](v);
    }
  };
  return this;
}

That is, an event stream is just a callback manager, support structure for the observer pattern. Callbacks can be registered on an event stream by running e.listeners.push(...);. To send a new value on the event stream, you can call newValue to notify the listeners. This is how timer_e hooked setInterval up to the Event class: every time the interval called its callback, an event’s newValue method is called with the time since the epoch. (As an aside, Event is called Node in Flapjax, since it represents a node in the callback graph.)

Output: showStream

A function like timer_e is a constructor for integer-valued event streams; that is, Event objects with integer values. For event streams to be useful, we also need a deconstructor for event streams. Since JavaScript runs in browsers, it makes sense to have event stream deconstructors that affect the HTML page through the DOM. In Flapjax, insertDomE is a deconstructor for events with printable values (e.g., strings and numbers, not objects and lists). Given a hook into the HTML page — a unique id, for example — and an event stream, insertDomE will update the HTML page with new values as they appear on the stream.

We’ll write our own, simple version of insertDomE. We’ll call it showStream, since it will do just that: it’ll just write each value out to the DOM.

function showStream(e) {
  e.listeners.push(function (v) {
    var log = document.getElementById('log');
    log.insertBefore(document.createElement('br'), log.firstChild);
    log.insertBefore(document.createTextNode(v), log.firstChild);
  });
}

If you’re running the code, the code below assumes that there’s an HTML block tag (div, say) with id “log” in the document. Alternatively,you could use FireBug and its console.log feature. (It’s a must for JavaScript, anyway.) In this simple example, I just dump out every new value without removing any of the old ones. If you’re following along, why not change the code as an exercise?

If we go ahead and run it, it’ll spit out the time in milliseconds since the epoch once every 100 milliseconds:

var t = timer_e(100);
showStream(t);

You’ll need to run that code in a function called from body.onload, since showStream will only work once the whole page is loaded.

Lifting

The above is enough to see the beginning of a functional reactive system, even though all we’re doing is playing with callbacks. The real payoff of functional reactivity is the ability to manipulate and combine event streams using ordinary operations. The process of applying a standard operator (like + on numbers) is called lifting, and it’s what you came here for.

function lift_e(f, e) {
  var lifted = new Event();
  e.listeners.push(function (v) { lifted.newValue(f(v)); });
  return lifted;
}

What is the type of this function? The first argument is a function. The second is an event e. The function listens to the event that its passed, and returns a new event. For every value v that appears on e, the new, f(v) appears on the stream of the new, ‘lifted’ event. Note that this definition of lift_e can’t use time-varying functions (i.e., function-valued event streams) or functions with more than one argument. This is to clarify the core idea of lifting; in Flapjax, lifting works for time-varying functions of arbitrary arity. If you’re following along, try it as an exercise — it’s not too difficult, but it’s not trivial. If you do it without looking at what Flapjax does and reimplementing it, I’d be curious to see what you, dear reader, come up with.

In any case, let’s see this in action! We’ll run a lifted function. (This example is ‘lifted’ from the Flapjax website’s second “time” demo.)

var t = timer_e(100);
var t2 = lift_e(function (v) { return Math.floor(v / 1000); }, t);
showStream(t2);

If you’ve been following along, you’ll notice a problem. Redundant values keep getting spit out! The setInterval call in timer_e regularly sends events down the stream, and the lift_e call will happen every time an event occurs. The division and truncation occur ten times a second (or so) with the same result!

Avoiding redundant events: hold_e and Behavior

How can we avoid these redundant events? We need a function to ‘hold onto’ the last value and not propagate identical values. This is quickly and easily written:

function hold_e(e) {
  var held = new Event();
  var valueNow;

  e.listeners.push(function (v) {
    if (v !== valueNow) {
      valueNow = v;
      held.newValue(v);
    }
  });

  return held;
}

We keep the last value seen in valueNow, only propagating new values. (We should probably use a more robust version of equality than === and !==, but that’s irrelevant in this tutorial, where we’ll only use integer-valued events.) If we change the last example to:

var t = timer_e(100);
var t2 = lift_e(function (v) { return Math.floor(v / 1000); }, t);
var t3 = hold_e(t2);
showStream(t3);

Success! Only one message per second appears in the log. In Flapjax, this isn’t exactly the way hold_e is defined. In fact, this definition has a small problem that doesn’t come up with timer_e, but can with other event sources. What happens in lift_e and showStream if no value has come along on a held stream yet?

The first observation is that we have in valueNow a ‘current’ value, a way to track the most recent value sent on an event stream. In fact, even though we don’t give it an initial value syntactically, valueNow has one — undefined! If we turn valueNow into a member variable of a class, rather than a scope variable in a closure, we could use it in functions in place of a default value. The Flapjax solution is to create a subtype of Event, called Behavior. (Actually, it’s to create a subtype of Node called Behaviour. Oy.) Defining this new class isn’t difficult, but it does showcase JavaScript’s funniness.

function Behavior(e, init) {
  Event.call(this); // call ’super’ constructor
  this.valueNow = init;

  var _this = this; // capture this, so we can reference it in a closure
  e.listeners.push(function (v) {
    if (v !== _this.valueNow) {
      _this.valueNow = v;
      _this.newValue(v);
    }
  });

  return this;
}

To paraphrase, a Behavior is an Event with an additional member valueNow; it only propagates events that are different from this value. Basically, we’ve woven together hold_e and Event.

To demonstrate the new form of propagation:

var t = timer_e(100);
var t2 = lift_e(function (v) { return Math.floor(v / 1000); }, t);
var b = new Behavior(t2, 0);
showStream(b);

Our (trusty?) old lift_e will work on this structure: it is an event, after all! But we still don’t do anything with valueNow. Fortunately, we can reuse lift_e in writing a new lifting form for Behavior:

function lift_b(f, b) {
  return new Behavior(lift_e(f, b), f(b.valueNow));
}

Note the subtype-punning with the nested lift_e. Readers familiar with functional-programming will see that we’ve simply threaded the lifting through the new (underlying) datatype.

Using lift_b, we can extend our old example cleanly:

var t = timer_e(100);
var t2 = lift_e(function (v) { return Math.floor(v / 1000); }, t);
var b = new Behavior(t2, 0);
var b2 = lift_b(function (v) { return v % 10; }, b);
showStream(b2);

But we can also show that valueNow is propagated correctly:

var e = new Event();
var b = new Behavior(e, 0);
var b2 = lift_b(function (v) { return v + 1; }, b);
assert(b2.valueNow == 1) // even though no events have been sent

If we so chose, we could extend showStream to work with valueNow. If you’re following along, try it as an exercise! (I love saying that, particularly since I don’t have to do it!)

Now that we have a solid understanding of lifting, we can finally understand what the difference is between just using Flapjax and using the Flapjax language, via the compiler. Using Flapjax as a language, you have to manually lift operations on Flapjax’s time-varying values. When you use compiled Flapjax, this lifting happens automatically. How? Stay tuned!

]]>
http://www.weaselhat.com/2007/08/11/lifting-in-flapjax/feed/ 6
Flapjax Templates http://www.weaselhat.com/2006/10/25/flapjax-templates/ http://www.weaselhat.com/2006/10/25/flapjax-templates/#comments Wed, 25 Oct 2006 18:40:31 +0000 http://www.weaselhat.com/2006/10/25/flapjax-templates/ The response to the template language in Flapjax has been mixed, to say the least. The most common complaint is that they mix content with style. True — this can be done with our templates. But nothing stops a developer from putting CSS in the HTML directly. Nothing except good sense, that is.

In response to a recent post on our discussion group for Flapjax, I wrote about this briefly:

…the only compiler specific syntax is the templates: curly-bang — {!, !} and triple-stick — |||. But these are parsed out of HTML PCDATA and attribute nodes, so a JavaScript/Flapjax programmer needn’t consider them. We introduced the syntax as a way to reduce the clutter of “insertDomB” and “insertValueB” calls. For example, the template language is:

It's been {! currentSeconds ||| (loading...) !} seconds since the beginning of 1970, and it's all been downhill.

while we must write the following without it:


It's been (loading...) seconds ... .

This can become a huge mess, so the templates simplify it. We wouldn't want to encourage doing all of your computation in the display layer! I'd compare it to Smarty or JSP -- while you can include complex computations in the tags, it's meant only to ease the interface between models in code and presentations on screen.

I think that soundly characterizes the template language. Shriram wants that in the tutorial, so that'll show up there eventually. (Some people take classes during the semester, but the Flapjax team has much more important things to do. Or so we're told.) But it would be a big mistake to see Flapjax as providing just that -- the functional reactivity is the interesting bit.


Tonight we're presenting the language to the undergraduates in the DUG; there's an exciting contest announcement coming up, as well. Who has time for midterms?

]]>
http://www.weaselhat.com/2006/10/25/flapjax-templates/feed/ 9
Flapjax http://www.weaselhat.com/2006/10/12/flapjax/ http://www.weaselhat.com/2006/10/12/flapjax/#comments Fri, 13 Oct 2006 02:40:41 +0000 http://www.weaselhat.com/2006/10/12/flapjax/ Since I got back from Israel, I’ve been working on a top secret project: a programming language for the Web. Well, for the Web 4.0 — we gave 3.0 a miss. The language is Flapjax. As you’ll note on the homepage linked above and on the Flapjax development blog, it’s multifaceted. I’ll mention the salient major features here.

The main feature is functional reactivity, found in flapjax.js. Functional reactive programming (FRP) has been around for a while in the Haskell community. The PhD lead on our project, Greg Cooper, wrote FrTime (read Father Time), which embeds FRP in Scheme.

To learn more about FRP, you might as well walk through our tutorial. It’s a callbackless world in which values vary over time and whole expressions are appropriately re-evaluated. For example, the text in a textbox can be computed with over time — no need to register callbacks for onfocus, onblur, onthis, or onthat.

In essence, FRP is a monad. But in practice, this means that FRP is a driver/callback manipulator and CPS-ed code. In FrTime, CPS-ing isn’t done directly, but instead all of the language’s primitives (+, cons, etc.) are lifted. In Flapjax, either the programmer does it manually or the compiler (my work) translates the code to CPS. There are arguments in either direction — the compiler’s aggressiveness can make it hard to use.

While on the topic of the compiler, we also introduced a templating language for in-lining Javascript/Flapjax in HTML elements and attributes. More on this and it’s utility later.

But the Web 4.0 has to subsume all of Web 2.0. Which is where the -jax morpheme comes in. Given a functionally reactive language, we can deal with values from a server — via AJAX — as they vary over time, without having to fight with request scheduling and callback handling, and so on. In a few dozen lines (and with a Flash proxy, written by Aleks Bromfield, to get around Javascript’s outmoded security model) you can hook up, say, Google Maps and Yahoo! Local. Seriously, we did that: Yaggle. So that’s pretty cool.

If AJAX without the callback mess wasn’t enough, we also wrote a generalized object store. It’s accessed via AJAX (really AJAJ, since we use JSON extensively), and was built to allow quick and easy sharing. We don’t have a demo as cool as Yaggle yet, but it’s certainly in the works.

So that’s it. Future blogging topics are: the templating syntax, compiler internals, client API internals, basic howtos. The whole project was immensely fun. Shriram got me on board by asking me what would happen if PL people actually got together and wrote something for real — that is, fully implemented an idea and sent it out at the world in a language the world can use. We both chuckled for a moment, thinking how funny it would be to actually apply PL. And then he pointed out that there’s nothing funny about that at all.


A quick addendum: Flapjax is an experiment. Shriram will kill me for saying this, but the truth has to get out: Flapjax is a functional programming language. You can’t write loops, you can’t write if — you can use fold and map and expression-if (also called ternary if: test ? consequent : alternate). Can the world handle it? We promise, fame, riches, glory, callback elimination — the stuff of dreams! …but at what cost? All hyperbole, of course. You can write loops and if statements and so on, but we require a separation of the functional, declarative Flapjax language and the procedural, imperative world of Javascript. The real question is: do programmers know the difference?

]]>
http://www.weaselhat.com/2006/10/12/flapjax/feed/ 2