This file is indexed.

/usr/share/mozart/doc/apptut/node3.html is in mozart-doc 1.4.0-8ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

1
2
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>2 Application Development</TITLE><LINK href="ozdoc.css" rel="stylesheet" type="text/css"></HEAD><BODY><TABLE align="center" border="0" cellpadding="6" cellspacing="6" class="nav"><TR bgcolor="#DDDDDD"><TD><A href="node2.html#chapter.hello">&lt;&lt; Prev</A></TD><TD><A href="node1.html">- Up -</A></TD><TD><A href="node4.html#chapter.modman">Next &gt;&gt;</A></TD></TR></TABLE><DIV id="chapter.development"><H1><A name="chapter.development">2 Application Development</A></H1><P> <A href="node2.html#chapter.hello">Chapter&nbsp;1</A> used a rather simple application as example. This chapter shows how to use functors for the modular development of larger applications. </P><DIV id="section.development.functors"><H2><A name="section.development.functors">2.1 Functors for Modular Applications</A></H2><P> Principles of good software engineering suggest that larger applications should be designed and assembled from a collection of smaller modules. In Oz, this decomposition can be realized in terms of several functor definitions. </P><P> The primary purpose of a functor is to compute a module: It takes modules as input and computes a new module as output. As we have seen already, the <CODE><SPAN class="keyword">import</SPAN></CODE> section of a functor specifies its inputs as a list of module names. In addition, functors may also have an <CODE><SPAN class="keyword">export</SPAN></CODE> section which is basically a list of feature/value pairs that describes the module computed by the functor. </P><P> As demonstrated in <A href="node2.html#section.hello.exec">Section&nbsp;1.5</A> an application is run by executing the root functor. In our particular example, the root functor was rather simple in that it only imported system modules. However, larger applications will typically import modules computed by other application functors. </P></DIV><DIV id="section.devel.lmf"><H2><A name="section.devel.lmf">2.2 Example: Last Minute Flights</A></H2><P> In the following we will build a trivial flight booking system featuring three components: </P><P> </P><OL type="1"><LI><P>A data base server: It maintains a data base that contains available flights, where each flight has a unique id by which it can be identified. At first, the data base is not even persistent, but as we incrementally refine and improve our application, the data base evolves into a persistent and distributed data base server. </P></LI><LI><P>A graphical flight booking form, where a travel-minded user can choose a flight, enter her name, her E-mail address and so on. Later we will show how to build a web-based interface serving the same purpose. </P></LI><LI><P>The main component of our application that manages user requests to the data base and sets up the application. </P></LI></OL><P> </P><P> All components are programmed as functors. </P></DIV><DIV id="section.development.db"><H2><A name="section.development.db">2.3 The Data Base</A></H2><P> Let us start with the data base, which is the most straightforward part of our application. The data will be held in a dictionary that uses integers as keys, and arbitrary data structures as entries. The functor definition resides in file <CODE>DB.oz</CODE> and its toplevel structure is as follows: </P><P> </P><DL><DT><SPAN class="chunktitle"><SPAN class="chunkborder">&lt;</SPAN><A name="label10">DB.oz</A><SPAN class="chunkborder">&gt;=</SPAN></SPAN></DT><DD class="code"><CODE><SPAN class="keyword">functor</SPAN>&nbsp;<BR>&nbsp;&nbsp;</CODE><SPAN class="chunktitle"><SPAN class="chunkborder">&lt;</SPAN><A href="node3.html#label11">Export specification for DB.oz</A><SPAN class="chunkborder">&gt;</SPAN></SPAN><CODE>&nbsp;<BR>&nbsp;&nbsp;</CODE><SPAN class="chunktitle"><SPAN class="chunkborder">&lt;</SPAN><A href="node24.html#label72">Body for DB.oz</A><SPAN class="chunkborder">&gt;</SPAN></SPAN><CODE>&nbsp;<BR><SPAN class="keyword">end</SPAN></CODE></DD></DL><P> </P><P> The functor has no import specification, and its export specification is as follows: </P><P></P><DL><DT><SPAN class="chunktitle"><SPAN class="chunkborder">&lt;</SPAN><A name="label11">Export specification for DB.oz</A><SPAN class="chunkborder">&gt;=</SPAN></SPAN></DT><DD class="code"><CODE><SPAN class="keyword">export</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;add:&nbsp;&nbsp;&nbsp;&nbsp;Add<BR>&nbsp;&nbsp;&nbsp;get:&nbsp;&nbsp;&nbsp;&nbsp;Get<BR>&nbsp;&nbsp;&nbsp;getAll:&nbsp;GetAll<BR>&nbsp;&nbsp;&nbsp;remove:&nbsp;Remove</CODE></DD></DL><P> </P><P> The specification determines that the functor's module provides the features <CODE>add</CODE>, <CODE>get</CODE>, <CODE>getAll</CODE>, and <CODE>remove</CODE>, where the value of each feature is given by the variable after the following colon. The values of these variables are then computed by the functor's body. </P><P> For convenience, the export specification above may also be written more succinctly as follows: </P><DL><DT><SPAN class="chunktitle"><SPAN class="chunkborder">&lt;</SPAN><A name="label12">Export specification for DB.oz (with syntactic sugar)</A><SPAN class="chunkborder">&gt;=</SPAN></SPAN></DT><DD class="code"><CODE><SPAN class="keyword">export</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;Add<BR>&nbsp;&nbsp;&nbsp;Get<BR>&nbsp;&nbsp;&nbsp;GetAll<BR>&nbsp;&nbsp;&nbsp;Remove</CODE></DD></DL><P> </P><P> The shortcut to just use a variable identifier starting with a capital letter, defines both the variable identifier as well as the feature. The feature is the variable identifier with its first character changed to lowercase. </P><P> The functor body is of less importance to us here, however, you can find it in <A href="node24.html#section.code.development">Section&nbsp;A.1</A>. One advantage of modular program development is that during the design of an application one may concentrate first on finding the right interfaces, and only then provide corresponding implementations. </P><P> Even though the functor does not import any module, it uses predefined procedures (for example, <CODE>Dictionary<SPAN class="keyword">.</SPAN>new</CODE> to create a new dictionary). The compiler provides a set of variable identifiers, that refer to the basic operations on all primitive Oz data types. This set of identifiers is known as the <EM>base environment</EM> and is documented in detail in <A href="../base/index.html">``The Oz Base Environment''</A>. </P><P> When a functor definition is compiled, all free variable identifiers must be bound by the base environment. </P></DIV><DIV id="section.development.form"><H2><A name="section.development.form">2.4 The Graphical Input Form</A></H2><P> The functor that implements the graphical form to book flights has the following structure, and its definition resides in file <CODE>Form.oz</CODE>: </P><P></P><DL><DT><SPAN class="chunktitle"><SPAN class="chunkborder">&lt;</SPAN><A name="label13">Form.oz</A><SPAN class="chunkborder">&gt;=</SPAN></SPAN></DT><DD class="code"><CODE><SPAN class="keyword">functor</SPAN>&nbsp;<BR><SPAN class="keyword">import</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;Tk<BR><SPAN class="keyword">export</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;Book<BR><SPAN class="keyword">define</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">proc</SPAN><SPAN class="variablename">&nbsp;</SPAN>{<SPAN class="functionname">Book</SPAN>&nbsp;Fs&nbsp;?Get}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%%&nbsp;<SPAN class="comment">Takes&nbsp;a&nbsp;list&nbsp;of&nbsp;flights&nbsp;and&nbsp;returns&nbsp;the&nbsp;booked&nbsp;flight<BR></SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%%&nbsp;<SPAN class="comment">and&nbsp;information&nbsp;on&nbsp;the&nbsp;booking&nbsp;user<BR></SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</CODE><SPAN class="chunktitle"><SPAN class="chunkborder">&lt;</SPAN><A href="node24.html#label73">Implementation of Book</A><SPAN class="chunkborder">&gt;</SPAN></SPAN><CODE>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR><SPAN class="keyword">end</SPAN>&nbsp;<BR></CODE></DD></DL><P> </P></DIV><DIV id="section.development.root"><H2><A name="section.development.root">2.5 The Root Functor</A></H2><P> The root functor for our last minute flights application uses the previously defined functors that maintain the data base and that provide the user form. The root functor's definition resides in file <CODE>LMF.oz</CODE>: </P><P></P><DL><DT><SPAN class="chunktitle"><SPAN class="chunkborder">&lt;</SPAN><A name="label14">LMF.oz</A><SPAN class="chunkborder">&gt;=</SPAN></SPAN></DT><DD class="code"><CODE><SPAN class="keyword">functor</SPAN>&nbsp;<BR><SPAN class="keyword">import</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;DB&nbsp;Form&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;<SPAN class="comment">User&nbsp;defined<BR></SPAN>&nbsp;&nbsp;&nbsp;System&nbsp;Application&nbsp;%&nbsp;<SPAN class="comment">System<BR></SPAN><SPAN class="keyword">define</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;%%&nbsp;<SPAN class="comment">Enter&nbsp;some&nbsp;flights<BR></SPAN>&nbsp;&nbsp;&nbsp;{ForAll&nbsp;</CODE><SPAN class="chunktitle"><SPAN class="chunkborder">&lt;</SPAN><A href="node24.html#label74">Sample flights</A><SPAN class="chunkborder">&gt;</SPAN></SPAN><CODE>&nbsp;DB<SPAN class="keyword">.</SPAN>add}<BR>&nbsp;&nbsp;&nbsp;%%&nbsp;<SPAN class="comment">Book&nbsp;until&nbsp;all&nbsp;flights&nbsp;sold&nbsp;out<BR></SPAN>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">proc</SPAN><SPAN class="variablename">&nbsp;</SPAN>{<SPAN class="functionname">Book</SPAN>}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">case</SPAN>&nbsp;{DB<SPAN class="keyword">.</SPAN>getAll}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">of</SPAN>&nbsp;nil&nbsp;<SPAN class="keyword">then</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{System<SPAN class="keyword">.</SPAN>showInfo&nbsp;<SPAN class="string">'All&nbsp;flights&nbsp;sold.'</SPAN>}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">[]</SPAN>&nbsp;Fs&nbsp;<SPAN class="keyword">then</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;O={Form<SPAN class="keyword">.</SPAN>book&nbsp;Fs}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">in</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{System<SPAN class="keyword">.</SPAN>showInfo&nbsp;(<SPAN class="string">'Booked:&nbsp;'</SPAN><SPAN class="keyword">#</SPAN>O<SPAN class="keyword">.</SPAN>key<SPAN class="keyword">#</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="string">'&nbsp;for:&nbsp;'</SPAN><SPAN class="keyword">#</SPAN>O<SPAN class="keyword">.</SPAN>first<SPAN class="keyword">#</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="string">'&nbsp;'</SPAN><SPAN class="keyword">#</SPAN>O<SPAN class="keyword">.</SPAN>last<SPAN class="keyword">#</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="string">'&nbsp;('</SPAN><SPAN class="keyword">#</SPAN>O<SPAN class="keyword">.</SPAN>email<SPAN class="keyword">#</SPAN><SPAN class="string">')'</SPAN>)}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{DB<SPAN class="keyword">.</SPAN>remove&nbsp;O<SPAN class="keyword">.</SPAN>key}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{Book}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;{Book}<BR>&nbsp;&nbsp;&nbsp;{Application<SPAN class="keyword">.</SPAN>exit&nbsp;0}<BR><SPAN class="keyword">end</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</CODE></DD></DL><P> </P></DIV><DIV id="section.development.compile"><H2><A name="section.development.compile">2.6 Compilation</A></H2><P> Functors also are compilation units. Each functor definition is compiled separately. For our example, the following sequence of commands </P><BLOCKQUOTE class="code"><CODE>ozc&nbsp;-c&nbsp;DB.oz&nbsp;-o&nbsp;DB.ozf<BR>ozc&nbsp;-c&nbsp;Form.oz&nbsp;-o&nbsp;Form.ozf<BR>ozc&nbsp;-c&nbsp;LMF.oz&nbsp;-o&nbsp;LMF.oza</CODE></BLOCKQUOTE><P> compiles our example functor definitions. If you now change the functor definition in, say, <CODE>DB.oz</CODE> but the interface of the created functor remains the same, none of the other functor definitions need recompilation. </P><P> Note that we have chosen as file extensions for pickled functors that are not supposed to be run as applications the string <CODE>ozf</CODE>. For the root functor of our application we chose <CODE>oza</CODE>. This is completely transparent as it comes to the semantics of our program, it is just a convention that makes it easier to tell apart which pickled functors are root functors of applications. </P></DIV><DIV id="section.development.execution"><H2><A name="section.development.execution">2.7 Execution</A></H2><P> As before, we just execute the root functor of our application by applying the <CODE>ozengine</CODE> command to <CODE>LMF.oza</CODE>: </P><BLOCKQUOTE class="code"><CODE>ozengine&nbsp;LMF.oza</CODE></BLOCKQUOTE><P> </P><P> The next chapter (<A href="node6.html#chapter.mof">Chapter&nbsp;5</A>) explains how applications that consist of several functors are executed. </P></DIV></DIV><TABLE align="center" border="0" cellpadding="6" cellspacing="6" class="nav"><TR bgcolor="#DDDDDD"><TD><A href="node2.html#chapter.hello">&lt;&lt; Prev</A></TD><TD><A href="node1.html">- Up -</A></TD><TD><A href="node4.html#chapter.modman">Next &gt;&gt;</A></TD></TR></TABLE><HR><ADDRESS><A href="http://www.ps.uni-sb.de/~duchier/">Denys&nbsp;Duchier</A>, <A href="http://www.ps.uni-sb.de/~kornstae/">Leif&nbsp;Kornstaedt</A> and&nbsp;<A href="http://www.ps.uni-sb.de/~schulte/">Christian&nbsp;Schulte</A><BR><SPAN class="version">Version 1.4.0 (20110908185330)</SPAN></ADDRESS></BODY></HTML>