<!--
  - Authors:
  -   Christian Schulte <schulte@ps.uni-sb.de>
  -
  - Copyright:
  -   Christian Schulte, 1998
  -
  - Last change:
  -   $Date: 2000-10-02 13:56:00 +0200 (Mon, 02 Oct 2000) $ by $Author: schulte $
  -   $Revision: 13208 $
  -
  - 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.Module">
    <Title/Module Managers: <<Module>>/

    <p>
      Module managers grant access to modules identified by
      urls. Examples and more information on module managers can be
      found in <ptr.extern to="ozdoc:apptut">.

    <Section id="Section.Module.Basic">
      <Title/Basics/

      <p>
        A module manager maintains a <def/module table/, that maps
        urls to modules. To be more precise, the table maps a url to a
        module or to a future for a module (this is explained later).

      <p>
        A module manager supports the following operations:
        <list>
          <entry><def/link/
          <item>
            Linking takes a url ?{U} as input and returns a module
            ?{M} or a future ?{F} for a module. 
          <p>
            We say that ?{M} or ?{F} is <def/linked from ?{U}/. Most
            of the time we will not distinguish between ?{M} and
            ?{F}.
          <p>
            Depending on whether the module
            table already contains an entry for ?{M}, the following
            happens: 
            <list enum>
              <item>
                If the module table already contains an entry ?{M} for
                the url ?{U}, linking just returns ?{M}.
              <item>
                If no entry for ?{U} is available, a new future ?{F}
                is created and stored under ?{U} in the module
                table. ?{F} is returned.
              <p>
                As soon as the value for the future ?{F} is requested,
                a new thread is created that <def/installs/ a module
                from the url ?{U}. This is called <def/dynamic
                linking/ or <def/linking on demand/.
              <p>
                If under the url ?{U} a pickled functor is stored, the
                module is computed by first loading the functor ?{G}.
                Then ?{G} is <def/applied/ with respect to
                the url ?{U} (this is explained later) which yields a
                module to which the future ?{F} is bound. This also
                explains why it is okay to not make a distinction
                between module and future for a module, since the
                distinction does not has any consequences as it comes
                to module access.
              <p>
                If the url ?{U} refers to a system module (see
                also <ptr.extern to="ozdoc:apptut"
                key="chapter.modman">) the system module is returned.
              <p>
                The url ?{U} can also refer to a native functor, this
                is described in detail in <ptr.extern to="ozdoc:apptut"
                key="part.foreign.extensions">. 
            </list>
          <entry><def/apply/
          <item>
            Application takes a functor ?{F} and a <def/base url/
            ?{U} and returns a module ?{M}.
          <p>
            First the import urls of ?{F} are resolved with
            respect to the base url ?{U}. Then the resolved urls are
            used for linking. The returned modules are called
            <def/argument modules/. Then the body of the functor is
            applied to the argument modules.
          <entry><def/enter/
          <item>
            Entering takes a url ?{U} and a module ?{M} as input.
          <p>
            The module ?{M} is added to the module table under
            ?{U}. If the module table already contains an entry for
            ?{U}, an exception is raised.
        </list> 
       
      <P> 
        A module manager is implemented as an instance of the class
        <<Module.manager>>. The class provides methods to link and
        apply functors and to enter modules into the
        module manager's module table.

    </Section>

    <Section id="Section.Modules.Names">
      <Title/Module Names and URLs/

      <P>
        As has been explained above, each module is refered to by a
        url ?{U}, some of which are Oz specific in that they refer to 
        system modules. We just say that the module <Em/has the url/
        ?{U}.  

      <P>
        A <Em/module name/ is a shortcut for a module url. The mapping
        of module names to full urls is explained in detail in
        <ptr.extern to="ozdoc:apptut" key="chapter.modman">.

    </Section>

    <Section id="Section.Modules.Link">
      <Title/The Class <<Module.manager>>/

      <P>
        Module managers are created as instances of the class
        <<Module.manager>>. For predefined abstractions that are build
        on top of module managers see <ptr
        to="section.modules.abstractions">.
      </P>

      <P>
        <List>
          <Entry><Span class=index/<<init>>/
	    <Index/<<Module>><And><<manager>><And><<init>>/
          <Synopsis>
	    <<<init()>>>
          <Item>
            Initializes the module manager.

          <Entry><Span class=index/<<link>>/
	    <Index/<<Module>><And><<manager>><And><<link>>/
          <Synopsis>
	    <<<link(url:?+{UrlV} ?_{ModuleR} <= _)>>>
	    <<<link(name:?+{NameV} ?_{ModuleR} <= _)>>>
          <Item>
            Links the module identified either by a url ?_{UrlV} (a
            virtual string) or a module name ?_{NameV} (a virtual
            string). Returns the module ?_{ModuleR} (which might be a
            future to a module).
          <P>
            The argument for the module is optional, if it is omitted
            the module is requested immediately.

          <Entry><Span class=index/<<apply>>/
	    <Index/<<Module>><And><<manager>><And><<apply>>/
          <Synopsis>
	    <<<apply(?+{Functor} ?_{ModuleR} <= _)>>>
	    <<<apply(url:?+{UrlV} ?+{Functor} ?_{ModuleR} <= _)>>>
	    <<<apply(name:?+{NameV} ?+{Functor} ?_{ModuleR} <= _)>>>
          <Item>
            Applies the functor ?_{Functor}, where the url ?_{UrlV} (a
            virtual string) or the module name ?_{NameV} (a virtual
            string) serve as base url for linking the functor's
            import. If neither a module name nor a url is given, the 
            current working directory is taken as base url.
          <P>
            The argument for the module is optional.
          <P>
            Please note that the resulting module is <Em/not/ added to
            the module table, the URL argument only serves as base url
            for the functor's import.

          <Entry><Span class=index/<<enter>>/
	    <Index/<<Module>><And><<manager>><And><<enter>>/
          <Synopsis>
	    <<<enter(url:?+{UrlV} ?_{ModuleR})>>>
	    <<<enter(name:?+{NameV} ?_{ModuleR})>>>
          <Item>
            Installs the module ?_{ModuleR} under the url ?_{UrlV} (a
            virtual string) or the module name ?_{NameV} (a virtual
            string).
          <P>
            Raises an exception if the module manager already has a
            module under that particular url installed.
        </List>
       </P>         
    </Section>

    <Section id="Section.Modules.Abstractions">
      <Title/Predefined Abstractions/

      <P>
        <List>
          <Entry><Span class=index/<<link>>/
	    <Index/<<Module>><And><<link>>/
          <Synopsis>
	    <<<{Module.link ?+{UrlVs} ?_{Rs}}>>>
          <Item>
             Takes a list ?_{UrlVs} of urls (as virtual strings) and
             and returns the list of modules  created by linking.
          <P>
            All functors are linked by the same module manager,
            however each application of <<Module.link>> employs a new
            module manager. This has the following
            consequences:
            <List>
              <Item> 
                Modules imported by several functors are shared.
              <Item>
                Each application of <<Module.link>> links required
                functors anew. That is, after replacing a functor on
                the file system, an application of <<Module.link>>
                considers the new functor for linking.
            </List>
          <P>
            <<Module.link>> is defined as follows:
<<<fun {Module.link UrlVs}
   ModMan = {New Module.manager init}
in
   {Map UrlVs fun {$ Url}
	         {ModMan link(url:Url $)}
	      end}
end>>>

          <Entry><Span class=index/<<apply>>/
	    <Index/<<Module>><And><<apply>>/
          <Synopsis>
            <<<{Module.apply ?+{Xs} ?_{Rs}}>>>
          <Item>
            Takes a list of functors or pairs of urls (as virtual
            strings) as input. The url in a pair of url and functor
            describes the base url with which the import urls of the
            functor gets resolved. If it is missing the current
            working directory is used for url resolution. 
          <P>
            Returns a list of modules computed by functor application.
          <P>
            <<Module.apply>> is defined as follows:
<<<fun {Module.apply UFs}
   ModMan = {New Module.manager init}
in
   {Map UFs fun {$ UF}
	       case UF of U#F then
		  {ModMan apply(url:U F $)}
	       else
		  {ModMan apply(UF $)}
	       end
	    end}
end>>>
        </List>
       </P>         
      
    </Section>


  </Chapter>

