Have you tried Opa?

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.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://www.deathshadow.com deathshadow

    Is there a static download or PDF of the manual? I’m always game for trying new languages, but the train wreck of web based docs (that crashes on my laptop and chews on CPU like crazy on the desktop) isn’t exactly conducive to figuring out how to use it.

    Though if the markup of doc.opalang.org is typical of what Opa makes, I’m rejecting it outright already as being as bad if not worse than most WYSIWYGS. Seriously that site is a poster child of everything wrong with “let’s just throw more javascript at it for nothing”, as well as “what do you mean this span doesn’t need fifteen classes?”

    • anonymous

      There is a pdf version of the manual on the download page:
      http://opalang.org/get.xmlt

    • http://adam-koprowski.net Adam Koprowski

      There is a very preliminary PDF version of the manual (see for instance the button at: http://opalang.org/resources.xmlt). Unfortunately a lot of formatting is plain wrong for now. Please drop a link at the forum: http://forum.opalang.org/#1_37 as the more people are interested in an offline version the faster it will come to be :).

      As for docs being typical; I don’t think so, Opa is a programming language so what you make with it is completely up to you. Most JS is Opa runtime. HTML markup & its classes. However, I’m not sure I fully get your complains about the docs app: can you be more specific about the problem?

      • http://www.deathshadow.com deathshadow

        >> can you be more specific about the problem?
        The docs pages are 3.2 megabytes to deliver 10k of plaintext per page; 90% of that is javascript garbage inlined in the markup which is why it sends my laptop off to never never land burying the needle on CPU use. The main website for it is similarly afflicted with well over half the ‘markup’ being inlined scripting… to the point of it being 40k of markup to deliver 2.6k of plaintext and a dozen content images.

        … on pages where neither of them appear to do anything that even warrants the presence of javascript!

      • boen_robot

        He’s mostly complaining about the generated code itself… like for example

        That’s one ugly piece of code…

        As for the CPU hoggishness… on some browsers (for me, that’s most noticeably Firefox), the docs are choppy when scrolling and loading, which is probably in part due to the large number of ids and classes.

        In addition, I’d like to say that, although the idea is interesting… It seems like Opa is trying too hard to be smart… I don’t like it when my tools try to be smart for the sake of being smart. It makes them unpredictable and unreadable… I need to have the ability to shoot myself in the foot when I know what I’m doing, even if I don’t use it often, and I need to be able to differentiate between one kind of language construct and another at a glance… and it doesn’t seem like Opa delivers on this, and what’s worse – it seems that’s intentionally so.

  • http://markscott.co.nz Mark

    So it’s a Windows Server solution? How come the word Windows doesn’t appear at all in this article?

    • Anonymous

      Doesn’t mention Windows Server in the article because it is not a Window Server solution…Doesn’t mention a sever in the docs…if you can even get the docs to work…

    • http://www.deathshadow.com deathshadow

      Much like the lack of links to the actual website for this anywhere in the article, it fails to mention that it’s also cross platform; assuming you can get this scripted train wreck of idiocy to even load:

      http://opalang.org/get.xmlt

      … you’ll see it’s available for Windows, Linux and OSX… in x64 only. Kind of odd they don’t even provide 32 bit binaries, but at least they provide the source so you can build your own.

      Tried it out a bit, and it’s a disaster… Never seen so much scripting nonsense appended to simple flat pages of content. SOMEBODY needs to go back and learn how HTML and CSS work, and to back away from the scripting.

    • http://adam-koprowski.net Adam Koprowski

      Why do you think it’s a Windows Server solution? Opa is multiplatform and works on Linux, Mac OS & Windows (with a Beta for FreeBSD).

    • Chris

      Where did you see Windows Server? I’ve been looking on their site and they have a Mac OS and Linux version and are working on a Windows port. I can’t find Windows Server anywhere.

  • http://niteodesign.com Blake Petersen

    Wow, this looks pretty rad! Thanks for the intro!

  • Dave Porter

    Thanks for the article…
    I headed over to their website (odd you did not provide a link?) & had a quick browse through the docs.
    But I’m confused about deployment ? I see very little info mentioned!
    Do you have to use their ‘DotCloud’?
    Dave

    • http://adam-koprowski.net Adam Koprowski

      No, you don’t have to use DotCloud. Opa produces stand-alone executables that can be run on any server you like.
      As for the link, indeed my bad; there should be links at the end of the article, trying to fix it now.

    • http://www.stauffer.com Jacob Pitassi

      Opa is deployed simply by compiling and running the compiled program. When its server starts it opens up on port 8080 or what ever port you declare in Server.start. Running the compiled Opa program is like starting Apache, except the Opa program has all the code/images stored within it and not in a separate folder. As far as I can understand.

  • http://www.catmedia.us Werner Keil

    I came across Opa via a blog about new languages like Ceylon and othert. Unlike e.g. CURL also hyped for RCP and Cloud-based use cases it is Open Source which is a good thing.

    The article on how to write a small sample unit converter app was especially nice, but unfortunately the sources won’t work after I actually downloaded and installed it on a 64-bit Windows 7 machine.
    The “hello.opa” example compiles, but the URL won’t work. Could be a proxy issue, but what worries me most is, that calling the “hello.exe” in the _build folder I get a silly error message “The version of this executable is not compatible with your version of Windows…” Any idea how to fix that, or when you may improve Opa?

    Thanks,
    Werner

  • Graham B

    I don’t normally reply to be snarky, but assuming your project homepage is written in Opa…

    …holy hell. Polluting the global namespace with over 2700 – yes, more than 2700 – indecipherable functions? I’ll pass, thanks.