<!--
  - Authors:
  -   Christian Schulte <schulte@ps.uni-sb.de>
  -
  - Copyright:
  -   Christian Schulte, 1998
  -
  - Last change:
  -   $Date: 1999/12/16 02:29:13 $ by $Author: duchier $
  -   $Revision: 1.15 $
  -
  - This file is part of Mozart, an implementation
  - of Oz 3
  -    http://www.mozart-oz.org
  -
  - See the file "LICENSE" or
  -    http://www.mozart-oz.org/LICENSE.html
  - for information on usage and redistribution
  - of this file, and for a DISCLAIMER OF ALL
  - WARRANTIES.
  -
  -->

<Chapter id="Chapter.Development">
  <Title/Application Development/

  <p>
    <ptr to="chapter.hello"> used a rather simple
    application as example. This chapter shows how to use
    functors for the modular development of larger applications.

  <section id="section.development.functors">
    <title/Functors for Modular Applications/

    <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>
      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 <<import>> section of a functor specifies its inputs as
      a list of module names. In addition, functors may also have an
      <<export>> section which is basically a
      list of feature/value pairs that describes the module computed by
      the functor.

    <p>
      As demonstrated in <ptr to="section.hello.exec"> 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.

    
  <section id="section.devel.lmf">
    <title/Example: Last Minute Flights/

    <p>
      In the following we will build a trivial flight booking
      system featuring three components: 

    <p>
      <list enum>
        <item> 
          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. 

        <item>
          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.

        <item>
          The main component of our application that manages user
          requests to the data base and sets up the application. 

      </list>

    <p>
      All components are programmed as functors.


  <section id="section.development.db">
    <title/The Data Base/

    <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 <file/DB.oz/ and its toplevel structure is
      as follows:

    <p>     
<chunk><title/DB.oz/
functor
  <chunk.ref/Export specification for DB.oz/
  <chunk.ref/Body for DB.oz/
end
</chunk>

    <p>
      The functor has no import specification, and its export
      specification is as follows:

    <p>
<chunk><title/Export specification for DB.oz/
export
   add:    Add
   get:    Get
   getAll: GetAll
   remove: Remove
</chunk>

    <p>
      The specification determines that the functor's module provides the
      features <<add>>, <<get>>, <<getAll>>, and <<remove>>, 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>
      For convenience, the export specification above may also be written
      more succinctly as follows:
<chunk><title/Export specification for DB.oz (with syntactic sugar)/
export
   Add
   Get
   GetAll
   Remove
</chunk>

    <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>
      The functor body is of less importance to us here, however, you
      can find it in <ptr to="section.code.development">. 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>
      Even though the functor does not import any module, it uses
      predefined procedures (for example, <<Dictionary.new>> 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 <def/base environment/ and is
      documented in detail in <ptr.extern to="ozdoc:base">. 

    <p>
      When a functor definition is compiled, all free variable
      identifiers must be bound by the base environment.

  <section id="section.development.form">
    <title/The Graphical Input Form/
<!--
DENYS:
the code comment below makes no sense to me.
a better explanation (intuitive) is needed.
-->
    <p>
      The functor that implements the graphical form to book flights
      has the following structure, and its definition resides in file
      <file/Form.oz/:

    <p>
<chunk><title/Form.oz/
functor
import
   Tk
export
   Book
define
   proc {Book Fs ?Get}
      %% Takes a list of flights and returns the booked flight
      %% and information on the booking user
      <chunk.ref/Implementation of Book/
   end
end

</chunk>
     

  <section id="section.development.root">
    <title/The Root Functor/

    <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 <file/LMF.oz/:

    <p>
<chunk><title/LMF.oz/
functor
import
   DB Form            % User defined
   System Application % System
define
   %% Enter some flights
   {ForAll <chunk.ref/Sample flights/ DB.add}
   %% Book until all flights sold out
   proc {Book}
      case {DB.getAll}
      of nil then
	 {System.showInfo 'All flights sold.'}
      [] Fs then
	 O={Form.book Fs}
      in
	 {System.showInfo ('Booked: '#O.key#
                           ' for: '#O.first#
                           ' '#O.last#
			   ' ('#O.email#')')}
	 {DB.remove O.key}
	 {Book}
      end
   end
   {Book}
   {Application.exit 0}
end
       
</chunk>
    

  <section id="section.development.compile" proglang=sh>
    <title/Compilation/

    <p>
      Functors also are compilation units. Each functor definition is
      compiled separately. For our example, the following sequence of
      commands  
<<<
ozc -c DB.oz -o DB.ozf
ozc -c Form.oz -o Form.ozf
ozc -c LMF.oz -o LMF.oza
>>>
     compiles our example functor definitions. If you now change the
     functor definition in, say, <file/DB.oz/ but the interface of the
     created functor remains the same, none of the other functor
     definitions need recompilation.

   <p>
     Note that we have chosen as file extensions for pickled functors
     that are not supposed to be run as applications the string
     <samp/ozf/. For the root functor of our application we chose
     <samp/oza/. 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. 

  </section>

  <section id="section.development.execution" proglang=sh>
    <title/Execution/

    <p>
      As before, we just execute the root functor of our application
      by applying the <<ozengine>> command to <<LMF.oza>>:
<<<
ozengine LMF.oza
>>>

    <p>
      The next chapter (<ptr to="chapter.mof">) explains how
      applications that consist of several functors are executed.
  </section>


<!--

  <Section id="Section.development.make" proglang=sh>
    <Title/Using <<make>> for Functor Compilation/

    
  </Section>

-->

</Chapter>

