Have Some "Fun" Building Real-Time Web Apps

DZone 's Guide to

Have Some "Fun" Building Real-Time Web Apps

· Web Dev Zone ·
Free Resource
Learning a new language that improves productivity can be fun.  A recently open sourced programming language is actually named "Fun".  The language was created by Marcus Westin, who wanted to build real-time web applications using the same, easy process that you would for building static web pages in PHP.  It doesn't require long polling, event handling, or state synchronization.  Westin says it represents a Fun-damental shift in the way developers can build the real-time web.  

Fun maps state to the UI much like PHP - with templates and logic rendering data into HTML.  For applications that update without a refresh - PHP, Python, and Ruby don't have a very simple method for achieving this real-time state synchronization, but Fun does.  Usually a JavaScript layer that long/short-polls the server and updates the DOM during state change events is required.

Compare this PHP simple task list ...
// This is PHP code, to contrast with the Fun code below
<h1>These are your tasks matey</h1>
$myTasks = sqlQueryGetMyTasks();
for ($i = 0; $i < sizeof($myTasks); $i++) {
$task = $myTasks[$i];
$divClass = "task" . ($task->urgent ? " urgent" : "");
echo "<div class=\"$divClass\">"
. "<span class=\"title\">" . $task->title . "</span>"
...with a simple task list written in Fun
// Fun code
let user = Session.User
let myTasks = Query({ type: "task", owner: user.id })

<h1>"Hello " user.name ", these are your tasks matey:"</h1>
for (task in myTasks) {
<div class="task" + (task.urgent ? " urgent")>
<input data=task.title />
if (task.completed) {
<span class="status">"Completed!"</span>
} else {
<button clickHandler=markComplete(task)/>"Mark as completed"</button>

let markComplete = handler(task) {
task.completed = true

<h3>"Create a new task"</h3>
<input data=Local.newTaskTitle />
<button clickHandler=createNewTask />

let createNewTask = handler() {
let title = Local.newTaskTitle
Local.newTaskTitle = ""
Global.create({ owner: user.id, type: "task", title: title })
In Fun, "Hello " user.name " means "display the value of user.name here and if  user.name changes, update the UI."  So when someone edits their name, the changes are updated in real-time, keystroke by keystroke.  No code is required for networking, event handling, state sync, or DOM manipulation.  The real-time state sync works for for lists too.  

The primary role of Fun is to emit HTML.  No "echo" or "emit" is needed because any statement with a single literal value emits that value implicitly.  Fun supports XML instead of trying to handle strings with HTML.  Fun is also declarative.

Here are the components of the Fun stack.

  • Parser: The Fun grammar is written in PEG.js, a parser generator written in javascript that outputs parsers also written in javascript.

  • Compiler: The Fun compiler is written in javascript, and converts the abstract syntax trees generated by the parser into javascript code that gets run both server and client side.

  • Realtime: The generated javascript uses fin to synchronize data across browsers. Fin is a realtime key/value datastore written in javascript. Fin consists of

    • The fin API, which runs both in browsers and on servers.

    • js.io for code modularization and realtime networking

    • node.js for the web server

    • redis for persistance of data structures and pubsub of data changes

The idea behind Fun is similar to a few other technologies including Microsoft's MVVM, which is used in Silverlight.  These technologies are based on binding and they encourage the developer to modify controls by manipulating objects that represent state instead of manipulating the controls themselves.  It's a great way to approach UI development because it allows things like two-way binding, which prevents endless binding loops. 

Fun is currently in a viable project stage where some of the functionality is complete and you can play with it.  By the year's end, Fun should be production-ready.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}