I've been curious about LunaScript since its announcement (http://www.asana.com/luna), and I thought I'd survey here what existing tools are similar to it - in particular, actively developed/maintained software. From the blog post:
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 Web 2.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.
The main feature of interest is the reactive programming/incremental evaluation/bidirectional databinding/whatever you want to call it, but one which straddles the browser, app server, and RDBMS, generating code for each of these platforms from a single high-level program.
Update 7/10/11: see my take-aways at the bottom.
Fun, which is directly inspired by Lunascript. Learned about this from this Quora question. From the (somewhat old) introduction:
First, credit where it's due! This project is conceptually inspired from conversations with Justin Rosenstein about the language LunaScript that he's building together with Dustin Moskovitz & team at Asana, and from conversations with Misko Hevery about the HTML compiler that he's building over at Google.
Ur/Web
Most client-side JavaScript programs modify page contents imperatively, but Ur/Web is based on functional-reactive programming instead. Programs allocate data sources and then describe the page as a pure function of those data sources. When the sources change, the page changes automatically.
Links: from Philip Wadler's group
Links eases the impedance mismatch problem by providing a single language for all three tiers. The system generates code for each tier; for instance, translating some code into Javascript for the browser, some into a bytecode for the server, and some into SQL for the database.
Swift:
In the Swift approach, application code is written in the Jif language, a Java-based language that includes information security policies. The source code is automatically partitioned into JavaScript code running in the browser, and Java code running on the server. For interactive performance, code and data are placed on the client side where possible. Security-critical code is placed on the server and user interface code is placed on the client. Code placement is constrained by high-level, declarative information flow policies that strongly enforce the confidentiality and integrity of server-side information. The Swift compiler may also choose to replicate code and data across the client and server, with benefits for both security and performance.
Fun is the language that's closest in spirit to what I understood Lunascript to be. In particular, the functional reactive programming transcends the client-server and server-database divides, allowing you to create UI elements expressed directly in terms of persistent database state, and have them dynamically updated as the database state changes. From the chat example, notice how the list of messages generated by the loop is dynamically updated as messages are appended to the global set of messages (using the send button):
<div class="chat">
<input data=userInput class="messageInput"/>
<button>"Send"</button onClick=handler() {
let newMessage = new { text: userInput }
userInput.set("")
global.messages.unshift(newMessage)
}>
<div class="messages">
for (message in global.messages) {
<div class="message"> message.text </div>
}
</div>
</div>
That's pretty much a complete chat app! (Modulo some declaration lines.)
However, the project is still very early and incomplete, with the language still in flux. And I still have questions regarding how easy it is to control explicitly what's dynamically updated vs. static, what runs on the server, how much communication occurs, etc. And, of course, how scalable this approach is. The author seems to be developing this project in pockets of spare time.
I'm impressed with Ur (an ML-style programming language) and Ur/Web (the web framework for Ur). Ur has a type system featuring dependent types but does more traditional type-checking, avoiding asking the user for proof assistance. Instead, the dependent types provide a framework for metaprogramming that allows you to, say, write a CRUD app that generates views generically for any compound data type (database schema). However, while Ur/Web features client-side reactive programming, client-server/AJAX communication is explicit. For instance, in the incrementing counter example, the RPC call that updates the counter is also needed to get the updated counter value (though once the client-side src
variable has been set, the view is dynamically updated):
sequence seq
fun increment () = nextval seq
fun main () =
src <- source 0;
return <xml><body>
<dyn signal={n <- signal src; return <xml>{[n]}</xml>}/>
<button value="Update" onclick={n <- rpc (increment ()); set src n}/>
</body></xml>
Notice how this only updates the counter when you press the button, and not when others update the counter---a type of reaction shown off by the Fun chat app.
The author believes Ur/Web is ready for production use and offers consulting/support services. There are a few Ur/web users in the wild, though seemingly countable by hand.
Links is a project from Philip Wadler's group. I was surprised to find that it doesn't offer functional reactive programming of any kind, and things like DOM manipulation are imperative. For client-server communication, again we have explicit RPCs. I think of Links as somewhat similar to GWT in that it's just a single language (functional in flavor) that can generate server and client code, in particular shielding you from JavaScript. As an example of this shielding, Links offers client-side concurrent processes with explicit message-passing communication (specifically, actors). These come in handy for writing blocking code (e.g. RPCs) without causing the entire client app to block.
The following code is from their updatable autocompletion demo (source), which is an app that lists DB-backed completions for the word you're typing and can insert new completions. Starting with the UI, we have a text box, the completion list, and a form for new definitions:
<form l:onkeyup="{handler!Suggest(s)}">
Search: <input type="text" l:name="s" autocomplete="off"/>
</form>
<div id="suggestions"/>
<h3>New definition</h3>
<div id="add">
{addForm(handler)}
</div>
handler
is an actor running client-side that makes blocking RPCs on behalf of the UI:
var handler = spawn {
fun receiver(s) {
receive {
case Suggest(s) -> suggest(s); receiver(s)
case NewDef(def) ->
newDef(def);
replaceChildren(addForm(self()), getNodeById("add"));
if (s <> "") suggest(s) else (); receiver(s)
}
}
receiver("")
};
So handler!Suggest(s)
sends a Suggest
message to handler
. Notice how the NewDef
handler needs to remember to update the completion list as well (by calling suggest
, just like the Suggest
handler) to keep the completions in sync with what's in the database.
The suggest
function asks the server to query the database, then imperatively updates the DOM:
fun suggest(s) client {
replaceChildren(format(completions(s)), getNodeById("suggestions"))
}
fun completions(s) server {
if (s == "") []
else {
query [10] {
for (def <-- defsTable)
where (def.word =~ /^{s}.*/)
orderby (def.word)
[def]
}
}
}
Notice how the functions are annotated with where they should be running.
This isn't under active development.
Swift bears a lot of resemblance to GWT, but with automatic code partitioning. The idea is that you can "anchor" certain data to the server side (the motivation is for security, and the paper formulates everything as an information flow control problem), and then the partitioner constructs a control-flow graph out of the code and uses min-cut driven by a ton of static heuristics about the edge costs. It isn't really focused on the language/expressiveness, so programming in it is apparently just writing GWT where the system decides for each line of code whether it's running on the client or the server. This isn't under active development.
mobl is a similar language, and it is actively developed.
It is 3 years after you have asked this question, and I wanted to make this topic up-to-date.
There are platforms like Polymer, React.JS, AngularJS, but none of them is as similar as Meteor (see demos).
Sorry for necromancing (this is first result in Gggl)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With