Consider a popular web page. It doesn’t matter which, as long as it’s dynamically constructed. When the server wants to send you that page, there are – loosely – two approaches. The easy one is to open the template and start sending stuff down to the client; when you get to a hole, fetch that thing from the backend and proceed. Each hole is filled sequentially and the latency is fairly high. The harder way is to fire off requests for all the backend stuff you’re gonna need, and build it all into a page when it all arrives, which gets you lower latency and potentially decreased server load. Of course, if your template is written as a pure function over state defined by the backend, then a compiler can take care of generating code using the latter technique. And then, everything is beautiful.
Consider a site that has to keep some aggregates, its inputs combined, sliced and diced in various ways. You can write a batch process that grabs all the new stuff and rebuilds the aggregates, if you can parallelize hard enough and live with the delays. Or you can take an event based approach, so upon the arrival of any update the event processor takes care of twiddling all the things that depend on the event, if you’re willing to accept something rather tricky to debug and almost impossible to recover from if it goes wrong and breaks your precious production data. Of course, if you define your aggregates, your application state in general, as a pure function over user requests, then you can have a compiler that keeps those aggregates current by incremental updates when user requests come in. And then, everything is beautiful.
At the intersection of those three vectors is where I think the shining future of web development is to be found. Templates written as pure functions over the state, state written as pure functions over the input, and incremental computing techniques used to keep the state current and the UI current as inputs are provided.