HTML5 Zone is brought to you in partnership with:

Dr. Adam Koprowski got his Master Degrees in Computer Science at the Warsaw University and at the Free University of Amsterdam. He then continued to do his PhD in formal methods at the Eindhoven University of Technology. Always a vivid fan of functional programming, he then joined MLstate, where, as a part of the R&D team, he worked on the web programming language Opa. He now holds the position of the Opa Tech Evangelist. In his free time he runs marathons (11 so far). Adam has posted 1 posts at DZone. You can read more from them at their website. View Full User Profile

Introduction to Opa

05.30.2012
| 8259 views |
  • submit to reddit

Have you tried Opa? and if not, why you should

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 of 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 substantial eff ort 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 the 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.

The second advantage is...

Type checking

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 t ake 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 very basic, Opa program.

database mydb @mongo { 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 "Hello, world" header and a message saying "Click the header". Upon clicking the header the message is replaced with "Hello, user number X", wh  ere 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 (i.e. types) 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 (@mongo, here) one can choose the database engine that will power the application, with MongoDB being the prime choice in Opa at the moment.

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 identified by id with content. Secondly the HTML fragment contains an insert, which is an e asy 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 all the rest is handled by the compiler.

Another thing worth noting is how easy it is to program event handlers and achieve interactivity in Opa. In fact, the language even offers powerful constructions for real-time web. That, however, is 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 it is 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, even 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 indistinguishable strings) and therefore can properly sanitize all inputs. 

... and more 

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 can download it, read the manual, the blog (with numerous tutorials) and a bunch of other articles about Opa. And if you want to know more you can meet the helpful Opa community on the forum.

Published at DZone with permission of its author, Adam Koprowski.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags: