Have you tried Opa?

Share this article

The Web is growing not only in size, but also in importance. The modern web as we know it has little to do with its early days of static pages; today, it’s anything but static. Some pages even earn the title of web applications–think Google Docs, for instance–apps that are accessed via a browser, and that start presenting serious competition to more traditional distribution models.

Development these apps is not simple. They’re inherently distributed between the client – a browser – and the server. Both are typically developed with different technologies and effort needs to be put into communication between them.

We often end up with a complex technology stack. A programming language for the server side, often with a framework on top of it, a programming language for the client side (usually JavaScript) with some libraries (jQuery, Dojo, Prototype, …), and a Database and its query language. All different technologies, with different concepts and models. Add configuration and tending to communication between them and you’ll get a picture of a fairly complex puzzle. Making all elements fit together is not an easy feat.

The goal of the new web programming platform, Opa, is to simplify this picture and to replace this complex technology stack with a single programming language. Let’s take a look at some simple Opa programs to see how it tries to make web developer’s life easier.

Hello, Opa!

Perhaps the simplest Opa program is the following:

Server.start(Server.http,
  { title: "Hello web",
    page: function() { <h1>Hello web</h1> }
  }
)

Let’s try to understand what happens here. First, Server.start is a function that starts a web server. It takes two arguments, the first one is a server configuration, including port, encryption parameters etc. – here we are just using default http settings. The second argument is the description of how the server should handle incoming requests. There are many variants possible for this second argument, here we are using a simple single-page-service variant which accepts a record with two fields: title and page.

Title is just a string with the title of this single page. Page is a function with no arguments that returns the HTML content of the page. Notice how we used an anonymous function for this field and that the last expression in a function is its return value. Also note how Opa “understands” HTML and accepts it via usual syntax.

Opa is built on modern standards so it supports HTML5, as witnessed by existing community projects using: WebGL, Canvas and SVG vector graphics. It also offers connectivity with existing services, including extensive libraries for: Facebook, Twitter, Dropbox and GitHub.

Compilation

How do we run the app? In Opa, it’s a two-step process. First, we must compile this program: (assuming we saved it in file named hello.opa)
opa hello.opa, and then we can run it with: ./hello.exe

With the growing popularity of interpreted languages one may wonder why Opa requires compilation. Apart from the usual argument that compilation allows for optimizations and better overall performance, there are at least two advantages of this approach.

The Opa compiler gathers and packs all application resources (including images and such) into one final executable (hello.exe in our case). That means that deploying it on a server requires just copying this single file and running it there. No external dependencies. No forgotten files.

Type checking

Next, Opa is a strongly, statically typed language and the compilation phase has many checks, including type-checking. That means that the compiler is able to detect a large class of programming mistakes and point them out to you, even before you run your program. This is very important and is in fact one of the crucial differences between Opa and some other web technologies, such as Node.js.

To better understand that let’s take a look at our simple program. What if we made a typo in one of the function or field names? What if we forgot one argument? What if page returned a string, not an HTML fragment? In all those situations the compiler would point out the mistake with a clear indication of the problem.

But the checks go much further than that. There are many variants possible for the second argument of the Server.start function. Opa’s type checker is strong enough to infer which variants are permissible and accept only those. I said infer, because in most situations you are not required to annotate your programs with types (as in, say, Java) and instead the compiler will perform type inference for you. Especially in bigger projects: this is a life saver.

Simple Demo

It’s hard to judge a language by how one writes “Hello world”, so let’s look at a slightly more complex, though still basic, Opa program.

database mydb { int /counter = 0; }
function action(_) {
    /mydb/counter < - /mydb/counter + 1;
    #msg = <>Hello, user number {/mydb/counter}!;
}
function page() {
    <h1 onclick={action}>Hello, world</h1>
    <div id="msg">Click the header</div>;
}
Server.start(Server.http, { ~page, title: "Hello, world" });

What does this program do? It presents a page with a “Hello, world” header, and a message saying “Click the header”. Upon clicking the header the message is replaced with “Hello, user number x”, where the x is replaced with the number of times the header was clicked since the inception of the service, i.e: it won’t be reset upon, for instance, restarting the web server.

Database

Let’s take a closer look at this program. To count the clicks it uses a database and so it starts with a declaration of a database called mydb, containing a single value of type int at path /counter. Database paths in Opa are locations for DB values and, conceptually, are somewhat similar to filesystem paths. That’s a very modest database but there are essentially no limitations on the number and complexity of paths.

As you can see in the action function, Opa tightly integrates database programming in the core language, providing convenient syntax for database reads and updates; and also querying, although that’s beyond the scope of this article. With a simple annotation one can choose the database engine that will power the application, with MongoDB being the prime choice in Opa right now.

Interactivity

Onto the page function. Interestingly, the static HTML contains an event handler, which points to a function in our program.

<h1 onclick={action}>Hello, world</h1>

where the said function does some database manipulation and DOM manipulation using special syntax:

#msg = <>Hello, user number {/mydb/counter}!;

There are two things at play here. Firstly, #id = content means: replace the content of the DOM element with id with content. Secondly the HTML fragment contains an insert, which is an easy and safe (more about that later) way to inject values into strings/HTML fragments. For instance Java’s:

System.out.println(x + " + " + y + " = " + (x+y));

would in Opa become:

println("{x} + {y} = {x+y}");

Unified client/server coding

In the snippet from the action function, the insert happens to be a read operation in the database. The interesting thing about this function is that obviously all database manipulations will have to be executed on the server, while all DOM manipulations will need to happen on the client. Not only does the Opa compiler figure out what should happen where, but it also automatically generates Javascript for the client and transparently takes care of all client-server communication.

Of course the developer can have better control over what’s happening and decide himself what should go where by means of simple function annotations. But the nice part is that moving function from client-to-server (or vice-versa) boils down to replacing the client keyword with server and the rest is handled by the compiler.

Another thing worth noting is how easy it is how easy it is to program event handlers and achieve interactivity in Opa. In fact, the language offers powerful constructions for real-time web, however that goes beyond the scope of this short article.

Security

One of the main challenges of web applications, and one to which Opa pays particular attention, is security. With constant client-server communication and the interactive nature of web apps its very challenging to make sure that sensitive information does not leak, and that users cannot do harmful things. Opa takes a twofold approach to this problem.

Apart from the client/server function annotations it provides two additional ones for the server functions: exposed and protected, which differentiate between server entry points that can be optimized for performance and those that should not be accessible, event to a compromised client.

The second security measure comes from the aforementioned type-safety of Opa. On one hand it means that (just like for some other high-level languages) buffer overflows or null pointer exceptions just cannot happen in Opa. On the other hand it offers protection against most popular security threats such as XSS attacks and code injections. This protection is possible because thanks to typing Opa knows what is an URL, what is HTML and what is a database-query (as opposed to dynamically/weakly typed languages where all of the above would just be strings) and therefore can properly sanitize all inserts.

In this short article I only had a chance to scratch the surface of what Opa has to offer, but I hope that was enough to get you interested in the language. I hope to continue with more news and tutorials about Opa in the near future. For now, if you want to know more, I suggest you visit Opa’s website, where you candownloadit, read themanual,theblog (with numerous tutorials) and a bunch of otherarticlesaboutOpa. And if you want to know more you can meet the helpful Opa community on theforum.

Adam KoprowskiAdam Koprowski
View Author

Dr. Adam Koprowski got his PhD in Computer Science at the Eindhoven University of Technology. Afterwards he joined MLstate, where he was part of the R&D team, working on the new web programming language: Opa. At the moment he holds the position of the Opa Tech Evangelist. He's a huge fan of functional programming, especially in the context of web development. In his free time he likes to run marathons (11 so far).

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week