Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.

Channels ▼

Open Source

Language of the Month: Opa

Opa is a new Web programming language. It delivers innovation to Web programming in three main areas:

  • Web programming is typically very fragmented. The database, client code, and server code are all driven by different technologies, which introduces complexity and the need for communication among different elements of the application. Opa eliminates these difficulties by providing a uniform and coherent platform for every part of the application.
  • Opa provides a common runtime for all the components of the application. The Web server, the database, your application, and its resources all live together in a single executable. Deployment is as simple as executing the file. Cloud deployment is as simple as executing it on many machines at once.
  • Opa brings increased safety to Web development thanks to its use of static analysis and static typing techniques.

The ideas behind Opa go back 10 years or more, but development gained real speed four years ago with the founding of MLstate in Paris. Opa was its principal product.

Work on the new language was triggered by frustration with existing tools for Web development. Even relatively simple apps were composed of a bunch of separate components that had to be harnessed to work together, sometimes against their will. Want to develop a desktop application? Choose your language and you are on your way. Want to write a Web app? You'll have to configure a Web server and a DBMS, master a database query language, select a client-side language, and choose a server-side language, plus probably a Web framework on top of all that. Then you'll have to set up lots of boring boiler-plate for client-server communication with JSON or XML.

Developers seem to accept this multitude of technologies as inherent to Web programming. But it doesn't have to be. What if you could create all the components of your application with one coherent package? That's what Opa is all about. Opa stands for "One Pot Application." It flattens the technology stack needed to develop for the Web.

Hello Opa

This is probably the simplest application that you can write in Opa:

server = Server.one_page_server("Hello", ( -> <>Hello Web</>))

This program is the Web equivalent of the traditional "Hello world" program. It creates a Web service with a single, static Web-page titled "Hello" and with "Hello Web" as its content. Let's take a look at the code in more detail.

server is a keyword that marks the entry point of the application — an HTTP server, as Opa programs are Web applications. It's like main in Java or C, only an Opa program may consist of more than one server — if it is listening on different ports, for instance.

Server.one_page_server is a function that constructs a particular, simple type of server, which consists of a single page. It takes two arguments: the title of the page and its body. The first argument is a single string. The second is more interesting. It's a function (with no arguments) that returns an xhtml, which is Opa's type for, well, XHTML. Indeed, if we take a look at Opa's API documentation we see:

Server.one_page_server : string, ( -> xhtml) -> service

In our call to this function, we pass -> <>Hello Web</> for the argument. There are two things to notice here.

First, the arrow is used to construct anonymous functions, the general syntax being arg1, arg2, … -> exp. In our example, there are no arguments; hence, nothing before the arrow.

The second is the syntax for XHTML. The empty tags <>...</> serve as delimiters for the markup. (We could have written something like: <span>Hello Web</>; the name in the closing tag is optional.)

I mentioned that the goal of Opa was to replace a complex technology stack with a single language — so what is XHTML doing here? It turns out that Opa does not replace (X)HTML or CSS. Instead, it incorporates them into the language. They are regular datatypes that can be manipulated easily within Opa.

It would be possible to build an abstraction layer on top of those presentation technologies, and in a sense, Opa provides such a layer in the form of numerous widgets. But in the end, Web pages are built using (X)HTML and CSS. A Web language should make it possible to work with them easily.

Let's continue with our "Hello Web" example. After saving the code to a file, hello_web.opa in this case, we compile it with:

opa hello_web.opa

Compilation results in a single executable: hello_web.exe. This executable contains:

  • All the resources used by the application, including images, external stylesheets, and so on
  • JavaScript for client-side code (automatically generated by Opa)
  • Code for all the client-server communication (Ajax & Comet, generated by the compiler)
  • Database queries (automatically generated by Opa)
  • An HTTP server
  • A DBMS

In other words, the executable contains all that is needed to run the application. Copy it to the server, execute it, and your Web application is up and running. Want to deploy the application in the cloud? Use the opa-cloud tool.

Opa's Type System

Opa incorporates a strong static type system. It is based on the notion of a record (product types), and on sums (union types). Together, these types form the basis for algebraic types. Almost every type in Opa is built using algebraic types, except for primitives such as string, int, and float. Even css and xhtml are constructed using algebraic types. For instance, Opa's boolean type is a choice between true or false:

type bool = {true : void} / {false : void}

The type declaration can be abbreviated as:

type bool = {true} / {false}

This is roughly equivalent to an enumeration type, but we can add more complex records and recursive types. Here is the concise definition of a binary tree:

type bin_tree('a) =
  / {leaf}
  / {left:bin_tree('a)  value:'a  right:bin_tree('a) }

The 'a in this code is a type-parameter that can be instantiated with any other type, resulting in a binary tree over elements of that type.

Opa is a higher-order language, so the types of record labels can be functions. As a result, records can also be used as interfaces. Consider this (simplified) signature for a function that creates a button. The arguments are its content and the function that should be executed when the button is clicked. The function returns a button; that is, a record allowing interaction with the button (in this case, changing its title and disabling it).

mk_button(title : xhtml, on_click : -> void) :
  { set_title : xhtml -> void; disable : -> void }

A common criticism of statically typed languages is the overhead required by writing types. Type inference ensures that this is almost never required in Opa.

Database Integration

I said earlier that Opa eliminates the need for a multitude of technologies. SQL is one of them. Declaring persistent data is as simple as declaring a variable:

db /revenue : intmap(float) // mapping year -> revenue

The only difference is that in such declarations, stating the type explicitly is required. This is how we perform reads:

this_year_revenue = /revenue[2011]

Updates look like this:

/revenue[2011] <- /revenue[2011] + 999.99

In this example, /revenue is a path, which is used to organize data in a hierarchical way — much like files in a file system. The leaves in this database tree can be arbitrary Opa types (with the exception of functional types), giving rise to further levels in the hierarchy. Think of records having other records as their fields, and so on.

At this time, all of this works with Opa's internal database. A future release is expected to offer interoperability with MongoDB and CouchDB.

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.