|
| 1 | +<html> |
| 2 | +<head> |
| 3 | +<title>Ur/Web Tutorial</title> |
| 4 | +<style> |
| 5 | +.code { |
| 6 | + background: #d0d0d0; |
| 7 | +} |
| 8 | +</style> |
| 9 | +</head> |
| 10 | +<body> |
| 11 | +<img src="urheader.png" alt="Ur/Web Tutorial"/></br> |
| 12 | +<hr width="99%"/> |
| 13 | +<h1>Ur/Web Tutorial</h1> |
| 14 | +<h2>Gian Perrone - April 2011</h2> |
| 15 | +<p> |
| 16 | +This is an introductory tutorial designed to get you started constructing applications in <a href="http://www.impredicative.com/ur">Ur/Web</a>, a modern, functional language for constructing web applications. This tutorial takes the form of an example application, and a guide explaining the steps of construction. |
| 17 | +</p> |
| 18 | +<h2>The Application</h2> |
| 19 | +<p>We're going to construct a very simple blog system. It doesn't aim to be particularly functional, rather, we aim only to construct something that will demonstrate enough of the features (and ultimate value) of Ur/Web. This system is known as 'UrBlog'. |
| 20 | + |
| 21 | +<h2>Installing Ur/Web</h2> |
| 22 | +<p>You're going to require a working installation of Ur/Web before you can actually run the examples. This is basically a matter of downloading Ur/Web, building, and then installing. There can be some subtleties in the build process, however. The actual installation process is outside the scope of this tutorial, so if you don't have a working installation already, you should read the <a href="http://www.impredicative.com/ur/">Ur/Web site</a>, particularly the <em>Reference Manual</em>, which should probably be your first port of call when any confusion arises. |
| 23 | +</p> |
| 24 | + |
| 25 | +<h2>Prerequisites</h2> |
| 26 | +<p>If you've never touched a functional programming language, particularly a strongly typed language such as ML or Haskell, you're probably not going to be able to follow this tutorial. I would recommend learning something about one (or both) of those languages first, and then returning to Ur/Web.</p> |
| 27 | + |
| 28 | +<h2>Step 1</h2> |
| 29 | + |
| 30 | +<p>We're going to create a directory <span class="code">urblog</span> for our project, and in it we will create three (empty) files: |
| 31 | + |
| 32 | +<pre class="code"> |
| 33 | +urblog/ |
| 34 | + urblog.urp |
| 35 | + urblog.urs |
| 36 | + urblog.ur |
| 37 | +</pre> |
| 38 | + |
| 39 | +Now, to add some content to these files!</p> |
| 40 | + |
| 41 | +<h3>urblog.urp</h3> |
| 42 | + |
| 43 | +<p> |
| 44 | +A <span class="code">.urp</span> file describes the files to be included within our project. In this case, we just want to ensure that our main source file <span class="code">urblog.ur</span> and its signature definition file <span class="code">urblog.urs</span> are included: |
| 45 | + |
| 46 | +<pre class="code"> |
| 47 | +urblog |
| 48 | +</pre> |
| 49 | + |
| 50 | +No file extensions are necesary here -- the use of a filename prefix such as this one causes the inclusion of the appropriate .ur and .urs files.</p> |
| 51 | + |
| 52 | +<h3>urblog.urs</h3> |
| 53 | + |
| 54 | +<p> |
| 55 | +A <span class="code">.urs</span> file is a <em>signature definition</em> that describes what artifacts of our implementation will be visible to the outside world: |
| 56 | + |
| 57 | +<pre class="code"> |
| 58 | +val main : unit -> transaction page |
| 59 | +</pre> |
| 60 | + |
| 61 | +We start by defining only a single function <span class="code">main</span> that will be visible. It takes as input values of type <span class="code">unit</span> and returns a value of type <span class="code">transaction page</span>. We'll describe what exactly that means a little later.</p> |
| 62 | + |
| 63 | +<h3>urblog.ur</h3> |
| 64 | +<p> |
| 65 | +The <span class="code">.ur</span> file holds actual implementation code. According to the signature we provided in <span class="code">urblog.urs</span>, we are obligated to provide a function called <span class="code">main</span>, so let's go ahead and do that: |
| 66 | + |
| 67 | +<pre class="code"> |
| 68 | +fun main () = return <xml> |
| 69 | + <head> |
| 70 | + <title>UrBlog</title> |
| 71 | + </head> |
| 72 | + |
| 73 | + <body> |
| 74 | + <h1>UrBlog</h1> |
| 75 | + </body> |
| 76 | +</xml> |
| 77 | +</pre> |
| 78 | + |
| 79 | +If you're used to working in a programming language that treats HTML and XML as strings, then this might look a little surprising. Within Ur/Web, XML fragments such as these are first-class values (in exactly the same way as integers, strings or booleans might be). The use of <span class="code">return</span> takes us back to the use of the type <span class="code">transaction page</span> earlier. The XML fragment has the type <span class="code">page</span>, and <span class="code">return</span> makes this expression part of a transaction, which is a monad in the style of the Haskell IO monad. |
| 80 | + |
| 81 | +</p> |
| 82 | + |
| 83 | +<h2>Putting it all together</h2> |
| 84 | + |
| 85 | +<p>OK, so we've got our source files. You can compile it all by running: |
| 86 | + |
| 87 | +<pre class="code"> |
| 88 | +urweb urblog |
| 89 | +</pre> |
| 90 | + |
| 91 | +from inside the urblog directory. This should result in a binary called <span class="code">urblog.exe</span>.</p> |
| 92 | +<p>If your system is anything like mine, you can run this binary using a command like <span>./urblog.exe</span>, which results in output such as: |
| 93 | + |
| 94 | +<pre class="code"> |
| 95 | +urblog # ./urblog.exe |
| 96 | +Database connection initialized. |
| 97 | +Listening on port 8080.... |
| 98 | +Database connection initialized. |
| 99 | +Database connection initialized. |
| 100 | +</pre> |
| 101 | + |
| 102 | +Marvelous! Now, the stand-alone webserver associated with your application is now listening for connections on port 8080. The exact URL is munged slightly by Ur/Web, such that your application name with the first letter upper-cased is the first URI component, followed by the name of any function that is visible outside the module (i.e. any function that is included in the <span class="code">urblog.urs</span> file). Putting it all together, we can access our application's main function at this URL:</p> |
| 103 | +<p><a href="http://localhost:8080/Urblog/main">http://localhost:8080/Urblog/main</a></p> |
| 104 | +<p>(Note: This is a localhost URL. You must have the server running on your local machine, and have appropriate firewall/connection settings to permit you to make a connection to your local machine on port 8080).</p> |
| 105 | +<p>If all of that worked, you should see a not-particularly-exciting web application featuring the word 'UrBlog' on a blank page. If it didn't work, you might have done something wrong, or there could be something wrong with your configuration. Now might be a good time to join the #urweb IRC channel on Freenode.</p> |
| 106 | +</body> |
| 107 | +</html> |
0 commit comments