Ur/Web is a domain-specific language for programming web applications backed by SQL databases. It is (strongly) statically typed (like ML and Haskell) and purely functional (like Haskell). Ur is the base language, and the web-specific features of Ur/Web (mostly) come only in the form of special rules for parsing and optimization. The Ur core looks a lot like Standard ML, with a few Haskell-isms added, and kinder, gentler versions added of many features from dependently typed languages like the logic behind Coq. The type system is much more expressive than in ML and Haskell, such that well-typed web applications cannot "go wrong," not just in handling single HTTP requests, but across their entire lifetimes of interacting with HTTP clients. Beyond that, Ur is unusual in using ideas from dependent typing to enable very effective metaprogramming, or programming with explicit analysis of type structure. Many common web application components can be built by Ur/Web functions that operate on types, where it seems impossible to achieve similar code re-use in more established statically typed languages.

The page you are currently reading is a part of the demo included with the Ur/Web sources and supporting files available from GitHub. The following steps will build a local instance of the demo if you're lucky (and running a Debian-based Linux OS, which actually tend to have Ur/Web packages built in these days). If you're not lucky, you can consult the beginning of the manual for more detailed instructions.

Install System Dependencies

sudo apt install build-essential \
  emacs-goodies-el \
  libgmp-dev \
  libssl-dev \
  libpq-dev \
  libsqlite3-dev \
  libicu-dev \
  mlton \
  sqlite3

Build and Install the Ur/Web Framework

./configure
make
sudo make install

Compile the Demo the Easy Way

$ urweb -dbms sqlite -db /path_to_db.sqlite -demo /Demo -noEmacs demo

The -dbms sqlite flag indicates that instead of using the default database management system (PostgreSQL), we wish to use SQLite (usually unsuited for production). The -db flag allows us to specify the file-system path to our SQLite database. The -demo /Demo parameter indicates that we want to build a demo application that expects its URIs to begin with /Demo, while the -noEmacs parameter disables invocation of Emacs to syntax-highlight source files for HTML rendering. The final argument demo gives the path to a directory housing Ur/Web source files (.ur, .urp, .urs, etc.).

The following files are created during the compilation process:

Initialize the Database

When we compiled the demo in the last step, a demo.sql file was created for us, which contains all the information required to create a database compatible with the demo web app. The command below will provision our SQLite database. To see an example of where a database table is defined in source code, check out demo/crud1.ur. Also of interest is the file demo.urp, which contains a database directive with the PostgreSQL database that the demo web server will try to connect to if database information isn't provided as command-line arguments when the application is compiled.

$ sqlite3 /path/to/database/file <demo/demo.sql

Boot the App
Executing the binary generated above (demo/demo.exe) with no arguments will start a single-threaded server listening on port 8080. (To answer the usual first question: the .exe prefix has nothing to do with Windows and does not mean that you compiled for the wrong OS!) Pass the flag -h to see which options are available on such freshly built binaries.

$ demo/demo.exe
Database connection initialized.
Listening on port 8080....
Test out http://localhost:8080/Demo/Demo/main, which should consist of links to the individual demos after booting the app.

Serve the Static Content with a Reverse Proxy

The -demo version also generates some HTML in a subdirectory out of the demo directory (e.g. index.html). It is easy to set Apache up to serve these HTML files and to proxy out to the Ur/Web web server for dynamic page requests. This configuration works for me, where DIR is the location of an Ur/Web source distribution. (You may also need to enable the proxy module with a command like a2enmod proxy_http.)

Alias /demo/ "DIR/demo/out/"

ProxyPass /Demo/ http://localhost:8080/Demo/
ProxyPassReverse /Demo/ http://localhost:8080/Demo/

Compile Individually

These project files can also be built separately. For example, you could run

$ urweb demo/hello
to build the "Hello World" demo application. Doing so will invite Ur/Web to seek out the various demo/hello.* files and, from them, build a binary demo/hello.exe. The URL to access the resulting app will be http://localhost:8080/Hello/main.

This File

One of the files in the demo directory is named prose, a file describing the different demo pieces with HTML. Some lines of prose have the form foo.urp, naming particular project files (with the extension .urp) in that directory. These make up the different pages of the tutorial.

Finally, the Demos!

The rest of the demo focuses on introducing Ur/Web programming, one feature at a time. Follow the links in the lefthand frame to visit the applications, commentary, and syntax-highlighted source code. (An Emacs mode is behind the syntax highlighting.) I recommend visiting the applications in the order listed, since that is the order in which new concepts are introduced.