Tuesday, February 2nd, 2010

LunaScript: A new language and platform to take your Web 2.0 apps to the moon?

Category: Announcements, Framework

A Googler and a Facebooker were in a pub discussing the complexities of building out a rich modern Web application. There are a ton of dependencies, and you need to be proficient in multiple languages and tools (JavaScript, HTML, CSS, SQL/NoSQL, backend languages, build tools, etc).

Well, they may not have been in a pub…. but a deadly duo did get together to try to solve this problem.

Dustin Moskovitz (Facebook co-founder and former CTO) and former-Googler/Facebooker Justin Rosenstein decided to try something different when they started to implement a Collaborative Information Manager tool at their new startup Asana. They have created a new high level language that is part JavaScript, part Protocol Buffers. The language is LunaScript.

What was their motivation?

All of us on the Asana team have deep backgrounds writing rich web applications at companies like Google and Facebook. We’ve been continually frustrated by how long it takes to write software, and by a nagging feeling that in some deep sense we’ve been writing the same code over and over. Even when using the latest and greatest frameworks and disciplines, writing fast, highly interacting web applications involves a lot of accidental complexity:

First you need server code to figure out what data the browser needs. Hopefully you have an ORM layer, but you still need to carefully structure your code to minimize your backend dispatches, and you need to carefully keep that in sync with your front-end code lest you don’t fetch enough data or hurt performance by fetching too much. If it’s a Web 2.0-style app, you re-implement a ton of that server-side code in JavaScript, once for creating the page and then again as controller code for keeping it up to date and consistent. And when the user changes something, you bottle that up — typically in a custom over-the-wire format — and send it as an XHR to the server. The server has to de-serialize it into different data structures in a different language, notify the persistence store, figure out what other clients care about the change, and send them a notification over your Comet pipe, which is handled by yet more JavaScript controller code. Offline support? More code.

This is not a one-off task: it’s rote work that adds complexity to every feature that you build in every application. By the time that you are done with all this, the important and novel parts of your application are only around 10% of your code. We wondered whether we could build a programming system in which we just wrote that 10% — the essential complexity — and a compiler handled the other 90%.

And this lead them to their solution:

Inspired by incremental computing, we’re building Lunascript as a simple way to write modern web applications. Lunascript has a syntax and easy of use reminiscent of JavaScript, but a powerful pure-functional lazily-evaluated semantics historically confined to academic languages.

A Lunascript application specifes a data model and a function from the model to the view or user interface, annotated with handler functions from user inputs to model mutations. From this the Lunascript compiler produces a functioning Web2.0 application — the client-side JavaScript, the server-side SQL, and everything in between — complete with real-time bidirectional data synchronization. There’s no need to write separate code to help the server figure out which values need to be sent to the client: the server can do this by simulating the UI. Because a LunaScript application only specifies how the UI should look given the current data (rather than how the UI should be updated as changes happen) it’s impossible to write a UI that loads correctly but does not stay correct as changes are made.

“What does it look like?” I hear you cry. Time for a hello world, and since Comet is in the mix, that means a chat server:


  1. // Some of our currently implemented syntax isn't quite this clean, but it's
  2. // fairly close and this is the direction we're going.
  4. class World {
  5.   // "1." serves the same purpose as "= 1" does in Google protocol buffer syntax.
  6.   1. ChatMessage[] messages;
  7. };
  9. class ChatMessage {
  10.   1. User user;
  11.   2. string text;
  12. };
  14. class Session {
  15.   1. User user;
  16.   2. String new_comment;
  17. };
  19. return fn(world, browser, session) {
  20.   var renderMessage = fn(message) {
  21.     // Most style information omitted to improve readability.
  22.     var bubble_style = { background: '#b7e0ff', padding: 7, ... };
  24.     return <div>   // XML literals are first-class primitives.
  25.       <img src=message.user.small_pic_url />
  26.       <div style=bubble_style>
  27.         <b> message.user.name, ': ' </b>
  28.         <div> message.text </div>
  29.       </div>
  30.     </div>;
  31.   };
  33.   var postMessage = fn() {
  34.     // Only handler functions can request data mutations.
  35.     messages += ChatMessage {
  36.       user: session.user,
  37.       text: session.new_comment
  38.     };
  39.     session.new_comment := '';
  40.   };
  42.   return <table>
  43.     <tr><td>
  44.       messages.map(renderMessage)
  45.     </td></tr>
  46.     <tr><td>
  47.       <img src=(session.user.small_pic_url) />
  48.       <div>
  49.         <input data=session.user.name /> <b>' (your nickname)'</b>
  50.         <form onsubmit=postMessage>
  51.           <input data=session.new_comment hasFocus=true />
  52.         </form>
  53.       </div>
  54.     </td></tr>
  55.   </table>;
  56. };

You will notice the protobufferness at the top, and the fn of less characters, and E4X-like.

To learn more, let’s listen in to Dustin as he gives us a walk through the world of LunaScript:

I talked to the guys and asked a few questions which they answered….. what questions do you have for them though? Are you excited about what a higher level abstraction could give you? Or do you like to be close to the metal?

Posted by Dion Almaer at 9:46 am

2.8 rating from 84 votes


Comments feed TrackBack URI

That sounds so brilliant! Thanks for the reference I’ll be definitely researching more and more about Lunascript!

Comment by stoimen — February 2, 2010

…the server can do this by simulating the UI…

What kind of impact will this have on server performance, I wonder?

Comment by barryvan — February 2, 2010

It can’t be called an xml literal if it isn’t valid xml….

Comment by TNO — February 2, 2010

Interesting, what serverside technologies is this built on / does it support?

Comment by munick — February 2, 2010

Video seems so sweet, simple and powerfull, i would like to play with it…

Comment by Siedrix — February 2, 2010

Now give it millions and millions of dollars of support and slow but steady developer uptake, a lot of revisions and a custom ide, tons for advertising and marketing, and 10 years from now, we’ll have reinvented html+javascript!

the *ustins are good intentioned but this is an incremental step to nowhere , very slowly.

Comment by functionform — February 2, 2010

Oh great, a new framework with its own syntax.
I can hardly contain myself.

Can we all help guess together the documentation in wikis and blogs, and watch many many flashvideos about how great it is?
Can we, can we, please?

Comment by MatsSvensson — February 2, 2010

Very nice. I like the shorter function declaration, although a no-arg function should be able to elide the “()” too. Explicitly declaring the bits of the class to be serialized in the language itself is a wonderful addition. Great stuff.

Comment by slightlyoff — February 2, 2010

There’s a typo in the code, the comment on line 25 should read:
// XML literals are first-class primitives!!!!!11111

Comment by okonomiyaki3000 — February 2, 2010

All of that and still return markup in code?

Comment by BenoitMarchant — February 2, 2010

Very impressive. As a web developer moving data between tiers I find myself repeating the same operations in each tier on the same dataset. This is a step in the right direction, I’m glad someone is thinking. Good stuff Asana.

Comment by jepsen — February 3, 2010

if(markupInCode === maintenanceNightmare) {
reduce('work load', 10);
increase('productivity', 10);
increase('maintenance debt', 100);
} else if (seperatedMarkup) {
increase('work load', 20);
reduce('productivity', 10);
increase('maintenance debt', 10);

Otherwise, looks and sounds great! =)

Comment by BenGerrissen — February 4, 2010

I’m sorry but I don’t get it… they only thing I can see here is, as Siedrix said above, reinvention of Javascript+HTML

Comment by auspex — February 4, 2010

@auspex, the syntax isn’t the innovation, the deep integration between backend+frontend allowing DRY idiom is. As stated in the post, right now we have to repeat the same code on both backend and frontend. Lunascript adresses that.

Comment by BenGerrissen — February 4, 2010

@BenGerrissen: Javascript addresses that too. Run your Javascript code on the client and on the server. Done.

Comment by trav1m — February 5, 2010

@trav1m …yeah it does sound rather like what Jaxer is meant to achieve.

I also wonder how it compares to this:

Comment by blueskiwi — February 8, 2010

This is very insteresting and I am always amazed about different methods of cross site scraping especially to get data for cell phone spy software.

Comment by CiscoConsulting — October 21, 2010

Leave a comment

You must be logged in to post a comment.