\chapter{Objekte der Tycoon Modulverwaltung}
\label{cha_objekte}

In diesem Kapitel werden die in der Sprache \tl zur Verf"ugung
stehenden Mittel zur Programmierung im Gro"sen vorgestellt.  Gem"a"s
Abschnitt~\ref{subsec_identifikation} stellt dies die Grundlage f"ur
die weitere Betrachtung dar.  Hier werden diejenigen Objekte
identifiziert, mit der die Modulverwaltung umgeht und deren
Beziehungen sie darstellt.

\tl stellt Moduln ({\itshape module}), Schnittstellen ({\itshape
interface}) und Bibliotheken ({\itshape library}) bereit, die hier im
folgenden als Objekte bezeichnet werden.  Sie sind Gegenstand der
Tycoon Modulverwaltung.  Die Ausf"uhrungen st"utzen sich auf
\cite{tycoon_po} und \cite{tycoon_intr}.

\section{Schnittstelle}
\label{sec_schnittstelle}

Schnittstellen enthalten die Signaturen f"ur Funktionen, Variablen,
Typen und Typoperatoren.  Die Schnittstelle zu einem Modul ist ein
benannter Tupel- oder Recordtyp und damit ein Objekt erster Klasse
(s. Abbildung~\ref{abb_interface} und~\ref{abb_interfaceTL}).
Bezeichner, die in einer Schnittstelle deklariert sind, werden mittels
Punktnotation angesprochen.

Da es beliebig viele Werte eines Typs geben kann, so kann auch eine
Schnittstelle von beliebig vielen Moduln implementiert werden.  Die in
Abbildung~\ref{abb_interface} gezeigte Schnittstelle kann also einmal
von dem Modul in Abbildung~\ref{abb_modul} implementiert werden.  Es
k"onnte aber auch von einem anderen Modul gleichen Typs implementiert
werden, welches z.~B.\ ein Array zur Darstellung des Stapels benutzt.

Ein Unterschied der in Abbildung~\ref{abb_interface}
und~\ref{abb_interfaceTL} gezeigten Beispiele besteht in der
Handhabung zu importierender Bezeichner.  W"ahrend im ersten Fall alle
zu importierenden Moduln und Schnittstellen explizit in der {\itshape
import}-Phrase angegeben werden m"ussen, sind im zweiten Beispiel alle
im Sichtbarkeitsbereich von {\itshape Stack}\/ befindlichen Bezeichner
automatisch auch erreichbar.

\begin{figure}[htb]
\hrule
\vskip \baselineskip
\begin{alltt}
\textbf{interface} Stack
  \textbf{import}
  \textbf{export}
    T <:\textbf{Oper}(E <:\textbf{Ok}) \textbf{Ok}
    new (E <:\textbf{Ok}) :T(E)
    empty (E <:\textbf{Ok}  stack :T(E)) :Bool
    push (E <:\textbf{Ok}  element :E  stack :T(E)) :T(E)
    pop (E <:\textbf{Ok}  stack :T(E)) :T(E)
    top (E <:\textbf{Ok}  stack :T(E)) :E
\textbf{end}
\end{alltt}
\hrule
\caption{Schnittstelle f"ur die Implementation eines Stack-Moduls}
\label{abb_interface}
\end{figure}

\begin{figure}[htb]
\hrule
\vskip \baselineskip
\begin{alltt}
\textbf{Let} Stack = \textbf{Tuple}
  T <:\textbf{Oper}(E <:\textbf{Ok}) \textbf{Ok}
  new (E <:\textbf{Ok}) :T(E)
  empty (E <:\textbf{Ok}  stack :T(E)) :Bool
  push (E <:\textbf{Ok}  element :E  stack :T(E)) :T(E)
  pop (E <:\textbf{Ok}  stack :T(E)) :T(E)
  top (E <:\textbf{Ok}  stack :T(E)) :E
\textbf{end}
\end{alltt}
\hrule
\caption{"Aquivalente Formulierung der Schnittstelle aus
Abbildung~\protect\ref{abb_interface} ohne Benutzung
ausgewiesener Modularisierungsmechanismen}
\label{abb_interfaceTL}
\end{figure}


\section{Modul}
\label{sec_modul}

\begin{figure}[htb]
\hrule
\vskip \baselineskip
\begin{alltt}
\textbf{module} stack
  \textbf{import}
    list :List
  \textbf{export}
    \textbf{Let} T(E <:\textbf{Ok}) = list.T(E)
    \textbf{let} new (E <:\textbf{Ok}) :T(E) = 
      list.new (:E)
    \textbf{let} empty (E <:\textbf{Ok}  stack :T(E)) :Bool = 
      list.empty (stack)
    \textbf{let} push (E <:\textbf{Ok}  element :E  stack :T(E)) :T(E) =
      list.cons (element stack)
    \textbf{let} pop (E <:\textbf{Ok}  stack :T(E)) :T(E) =
      list.tail (stack)
    \textbf{let} top (E <:\textbf{Ok}  stack :T(E)) :E =
      list.head (stack)
\textbf{end}
\end{alltt}
\hrule
\caption{Formulierung eines Moduls mit dem daf"ur von der Sprache \tl 
bereitgestellten {\itshape module}-Konstrukt}
\label{abb_modul}
\end{figure}

\begin{figure}[htb]
\hrule
\vskip \baselineskip
\begin{alltt}
\textbf{let} stack (list :List) = \textbf{begin}
  \textbf{Let} T(E <:\textbf{Ok}) = list.T(E)
  \textbf{let} new (E <:Ok) :T(E) = 
    list.new (:E)
  \textbf{let} empty (E <:\textbf{Ok}  stack :T(E)) :Bool = 
    list.empty (stack)
  \textbf{let} push (E <:\textbf{Ok}  element :E  stack :T(E)) :T(E) =
    list.cons (element stack)
  \textbf{let} pop (E <:\textbf{Ok}  stack :T(E)) :T(E) =
    list.tail (stack)
  \textbf{let} top (E <:\textbf{Ok}  stack :T(E)) :E =
    list.head (stack)
  \textbf{let} result: Stack = \textbf{tuple}
    \textbf{Let} T = T
    \textbf{let} new = new
    \textbf{let} empty = empty
    \textbf{let} push = push
    \textbf{let} pop = pop
    \textbf{let} top = top
  \textbf{end}
\textbf{end}
\end{alltt}
\hrule
\caption{Zu Abbildung~\protect\ref{abb_modul} "aquivalente Darstellung
eines Moduls}
\label{abb_modulTL}
\end{figure}

Ein Modul ist die Implementation seiner Schnittstelle.  In \tl wird
ein Modul durch eine Funktion beschrieben, die zu einem Tupelwert
evaluiert, der kompatibel zum Typ der entsprechenden Schnittstelle
sein mu"s.  Dieser Tupel mu"s entsprechend der Signaturen der
Schnittstelle kompatible Bindungen aufweisen.  Von dem Modul
importierte Bezeichner treten als Parameter der Funktion auf.

Wie in Abbildung~\ref{abb_modulTL} zu sehen, werden durch eine am Ende
der Funktion {\itshape }\/ vorgenommene explizite Bindung des
R"uckgabewertes drei Dinge erreicht:

\begin{itemize}
\item
Innerhalb der Funktion (Modulrumpf) k"onnen auch lokale, also nicht
exportierte, Bindungen vorgenommen werden.  Im Beispiel der
Abbildung~\ref{abb_modulTL} wurde hiervon kein Gebrauch gemacht.

\item
Die Reihenfolge der zu exportierenden Bindungen ist nicht relevant.

\item
Die Initialisierung des Moduls kann Seiteneffekte aufweisen.
\end{itemize}

\noindent
Nach der Definition im Beispiel aus Abbildung~\ref{abb_modulTL} mu"s
der Parameter der Funktion {\itshape stack}\/ durch

\begin{quote}
{\ttfamily let stack = stack (list);}
\end{quote}

\noindent
an den Bezeichner {\itshape list} gebunden und die Funktion evaluiert
werden.  Erst dann l"a"st sich {\itshape stack}\/ so benutzen, als ob
es importiert worden w"are.

Intern wird ein Modul repr"asentiert durch

\begin{description}
\item [Bytecode:] 
Dies ist der vom Compiler erzeugte TVM-Code.  Dieser kann von der Tycoon
Maschine (TVM) ausgef"uhrt werden.
\item [Literale:]
Hierbei handelt es sich um einen Vektor, der Verweise auf lokale
Konstanten enth"alt, z.~B.\ ein konstanter String, der ausgegeben
wird.
\item [Tupelwert:]
Dies ist der Wert, zu dem das Modul evaluiert wird.
\end{description}

Im Rahmen dieser Arbeit ist haupts"achlich der Tupelwert eines Moduls
von Bedeutung.  Die weiteren Details dieser Repr"asentation sind nicht
relevant, da das Modul von der Modulverwaltung stets als Einheit
behandelt wird.

\begin{figure}[htb]
\hrule
\vskip \baselineskip
\noindent
\begin{minipage}[t]{.46\linewidth}
\begin{alltt}
\textbf{interface} A
\textbf{export}
  T <:\textbf{Ok}
  x :T
\textbf{end}

\textbf{interface} B
\textbf{import} a :A
\textbf{export}
  y :a.T
\textbf{end}

\textbf{interface} C
\textbf{import} a :A
\textbf{export}
  f(z :a.T) :\textbf{Ok}
\textbf{end}

\textbf{interface} D
\textbf{export}
\textbf{end}



\end{alltt}
\end{minipage}\hfill
\begin{minipage}[t]{.46\linewidth}
\begin{alltt}
\textbf{module} a :A
\textbf{export}
  \textbf{Let} T = \ldots
  \textbf{let} x = \ldots
\textbf{end}

\textbf{module} b :B
\textbf{import} a :A
\textbf{export}
  \textbf{let} y = a.x
\textbf{end}

\textbf{module} c :C
\textbf{import} a :A
\textbf{export}
  \textbf{let} f(z :a.T) = \ldots
\textbf{end}

\textbf{module} d :D
\textbf{import} b :B  c :C
\textbf{export}
  c.f(b.y)
\textbf{end}
\end{alltt}
\end{minipage}
\hrule
\caption{Beispiel zum Problem des Rautenimports (aus \protect\cite{tycoon_po})}
\label{abb_rautenimport}
\end{figure}

\begin{sloppypar}
Die Beispiele machen eine weitere bewu"ste Einschr"ankung der
Orthogonalit"at der Benennungs-, Bindungs- und Typisierungskonzepte
der Sprache \tl deutlich.  Eine Schachtelung von Moduln und
Schnittstellen mit den Konstrukten {\itshape module}\/ und {\itshape
interface}\/ ist nicht m"oglich.  Eine Formulierung ohne diese Phrasen
l"a"st eine Schachtelung jedoch zu.
\end{sloppypar}

\section{Bibliothek}
\label{sec_bibliothek}

Eine Bibliothek legt die Sichtbarkeitsbereiche f"ur Moduln und
Schnittstellen fest.  Der Sichtbarkeitsbereich eines Bezeichners ist
durch die in der Bibliothek vor ihm aufgef"uhr\-ten Bezeichner
bestimmt.  Dies schlie"st zyklische Abh"angigkeiten zwischen
Komponenten aus.  Es l"ost weiterhin das Problem des Rautenimports
(s.~Abbildung~\ref{abb_rautenimport}).  In einer Situation, in der
zwei unterschiedliche Moduln {\itshape b}\/ und {\itshape c}\/ ein
weiteres Modul {\itshape a}\/ importieren und von dem Modul {\itshape
d}\/ importiert werden, kann aus der Namensgleichheit des Bezeichners
{\itshape a}\/ in {\itshape b}\/ und {\itshape c}\/ gefolgert werden,
da"s es sich bei der Funktionsapplikation in {\itshape d}\/ um den
gleichen Typ {\itshape a.T}\/ handelt \cite{tycoon_po,quest}.


Bibliotheken k"onnen, wie in Abbildung~\ref{abb_libfruits}
dargestellt, geschachtelt werden.  Dabei mu"s unterschieden werden,
zwischen Bibliotheken, die andere Bibliotheken innerhalb des {\itshape
with library}-Konstruktes auff"uhren.  Damit sind alle Bezeichner
einer Bibliothek in nachfolgend genannten Bibliotheken bekannt.
Dar"uber hinaus k"onnen in einer Bibliothek explizit Bezeichner einer
anderen Bibliothek, die in ihrem Sichtbarkeitsbereich liegt, durch
{\itshape import}\/ eingef"uhrt werden.  Dies f"uhrt zu zwei Arten von
Bibliotheken:

\begin{enumerate}
\item 
Eine Bibliothek bzw.\ die in ihr deklarierten Moduln und
Schnittstellen kann auf die Verwendung von Komponenten aus anderen
Bibliotheken angewiesen sein.  Eine derartige Bibliothek kann also
immer nur als {\itshape Subbibliothek}\/ einer anderen Bibliothek
auftreten und somit nie Wurzelbibliothek sein (vgl.\
Abschnitt~\ref{sec_wurzelbibliothek}).  Im Beispiel aus
Abbildung~\ref{abb_libfruits} trifft dies f"ur die Bibliothek
{\itshape FruitLib}\/ zu.
\item
Existieren in einer Bibliothek keine Moduln oder Schnittstellen, die
Komponenten aus anderen Bibliotheken importieren, so kann diese
Bibliothek als Wurzelbibliothek auftreten (Bibliothek {\itshape
Root}\/ aus Abbildung~\ref{abb_libfruits}).  Au"serdem kann diese
Bibliothek, ohne da"s Namenskonflikte irgendeiner Art entstehen
w"urden, innerhalb eines Bibliothekssystems umgruppiert werden.
\end{enumerate}

Trotz der M"oglichkeit zur Schachtelung sind {\itshape alle}\/
Bezeichner der Bibliothek {\itshape FruitLib} in den Bibliotheken
{\itshape GreensLib}\/ und {\itshape FlowerLib}\/ sichtbar.  Es
existiert nur {\itshape ein}\/ globaler Sichtbarkeitsbereich, in dem
sich alle Komponenten befinden und gem"a"s der oben erw"ahnten Regel
sichtbar sind.

\section{Versteckte Bezeichner}
\label{sec_hidden}

\begin{figure}[htb]
\hrule
\vskip \baselineskip
\begin{alltt}
\textbf{library} Root
\textbf{with}
  \textbf{interface}
    Field
  \textbf{module}
    field :Field
  \textbf{library}
    FruitLib GreensLib FlowerLib   
\textbf{end}
                         
\textbf{library} FruitLib         
\textbf{import} field :Field
\textbf{with}            
  \textbf{interface}
    Apple                
    Tomato               
    Peach                
  \textbf{module}
    apple :Apple         
    tomato :Tomato       
    peach :Peach         
  \textbf{hide}                   
    tomato Tomato        
\textbf{end}
\end{alltt}
\hrule
\caption{Geschachtelte Bibliotheken mit einem versteckten Bezeichner}
\label{abb_libfruits}
\end{figure}

\begin{sloppypar}
Mit der {\itshape hide}-Klausel kann zus"atzlich zum Konzept der
Bibliotheken die Sichtbarkeit bzw.\ Importierbarkeit von Moduln und
Schnittstellen eingeschr"ankt werden.  Ein in der {\itshape
hide}-Klausel aufgef"uhrter Bezeichner ist im Rahmen der
entsprechenden Sichtbarkeitsbereiche nur innerhalb der unmittelbar
einschlie"senden Bibliothek importierbar, nicht aber au"serhalb.
\end{sloppypar}

In der in Abbildung~\ref{abb_libfruits} aufgef"uhrten Bibliothek ist
der Bezeichner {\itshape tomato}\/ nur innerhalb der Bibliothek
{\itshape FruitLib}\/ importierbar, aufgrund der Sichtbarkeitsregeln
sogar nur in {\itshape peach}.  {\itshape Tomato}\/ ist au"serdem im
Modul {\itshape apple}\/ und {\itshape Peach} sichtbar.  Hingegen sind
{\itshape {peach}}, {\itshape Peach}, {\itshape apple}\/ und {\itshape
Apple}\/ auch im Sichtbarkeitsbereich der Bibliothek {\itshape
FlowerLib} und k"onnen von darin enthaltenen Komponenten importiert
werden.

\begin{sloppypar}
Eine Namens"uberdeckung einer versteckten Komponente in einer anderen
Bibliothek durch Redefinition des entsprechenden Bezeichners ist nicht
m"oglich, da die Sichtbarkeit von versteckten Bezeichnern nicht
eingeschr"ankt ist.  Es k"onnte also in der Bibliothek {\itshape
FlowerLib}\/ kein Bezeichner {\itshape tomato}\/ oder {\itshape
Tomato}\/ definiert werden, in diesem Fall k"ame es zu einer
Fehlermeldung.  Dies vereinfacht die Reorganisation gro"ser
Bibliothekssysteme, da verhindert wird, da"s durch Umstrukturierungen
neue Namenskonflikte entstehen.  {\itshape Tomato}\/ und {\itshape
tomato}\/ k"onnten also auch sichtbar in der Bibliothek {\itshape
GreensLib}\/ deklariert werden anstelle in {\itshape FruitLib}, ohne
da"s ein Namenskonflikt entst"unde.
\end{sloppypar}

\begin{sloppypar}
Der Nachteil dieses Ansatzes ist, da"s, obwohl Bezeichner in einer
Bibliothek versteckt deklariert sind, diese dennoch bekannt sein
m"ussen.  Z.~B.\ l"a"st sich nicht gleichzeitig in der Bibliothek
{\itshape FruitLib}\/ ein versteckter Bezeichner {\itshape tomato}\/
deklarieren und in der Bibliothek {\itshape GreensLib}\/ ein Bezeichner
gleichen Namens sichtbar oder ebenfalls versteckt.  Dies macht die
Kombination beliebiger Bibliotheken nur aufgrund der sichtbaren
Bezeichner unm"oglich.
\end{sloppypar}

\section{Zustand}
\label{sec_zustand}

"Ubersetzte Komponenten, insbesondere Moduln und Schnittstellen,
k"onnen sich in verschiedenen Zust"anden befinden.  Je nach Art
der Komponente hat dies unterschiedliche Bedeutungen.

Bibliotheken werden in dieser Diskussion nicht weiter betrachtet.  Sie
k"onnen sich entweder im Objektspeicher befinden und dann
Sichtbarkeitsbereiche f"ur andere Komponenten festlegen oder aber
nicht geladen sein.

\subsection{Modul}

In Abschnitt~\ref{sec_modul} wurde ausf"uhrlich erl"autert, da"s ein
Modul durch eine Funktion repr"asentiert wird, die einen Tupelwert
zur"uckgibt.  Diese Funktion kann nun in den Objektspeicher {\itshape
geladen}\/ werden (vgl.\ Abbildung~\ref{abb_zustand}).  Es ist der
erste Zustand, den ein Modul annehmen kann.

Im n"achsten Schritt kann die Funktion, parametrisiert mit den Moduln
und Schnittstellen, die sie importiert, ausgef"uhrt werden.  Das Modul
befindet sich dann im Zustand {\itshape gebunden}.  Dieses Modul bzw.\ 
sein Modulwert kann nun von anderen Moduln und Schnittstellen, in
deren Importliste es sich befindet, referenziert werden.

Soll der Wert des Moduls f"ur den Benutzer sichtbar sein, so mu"s er
an einen Namen gebunden werden.  Dies bedeutet, da"s der Wert des
Moduls im Toplevel-Vektor eingetragen wird.  Das Modul ist damit
{\itshape definiert}.

Aus der Aufstellung wird deutlich, da"s sich die Zust"ande
voraussetzen: Ein Modul kann nur gebunden sein, wenn es auch geladen
ist.  Ebenso kann nur eine Bindung auf dem Toplevel definiert werden
f"ur ein Modul, das bereits gebunden ist.  Dies geschieht meist in
einem einzigen Schritt durch Import des Moduls.

\begin{figure}[htb]
\centering\mbox{\epsfig{file=zustand.eps}}
\caption{Zust"ande, in denen sich ein Modul befinden kann.}
\label{abb_zustand}
\end{figure}

\subsection{Schnittstelle}

Im Gegensatz zu einem Modul stellt eine Schnittstelle Typinformation
dar.  Diese kann in den Objektspeicher {\itshape geladen}\/ werden.

Ein weiterer Unterschied zum Modul besteht im Zustand {\itshape
gebunden}.  Diesen kann eine Schnittstelle nicht annehmen, da sie
keinen Wert, sondern einen Typ repr"asentiert.  Das Aufl"osen der
externen Verweise innerhalb der Typinformation (de Bruijn-Index)
geschieht bei einer Schnittstelle erst, wenn sie auf dem Toplevel
definiert wird.  Z.~B.\ wird in einem Modul durch

\begin{quote}
{\ttfamily \textbf{import} :List}
\end{quote}

\noindent
nur die Schnittstelle des Moduls {\itshape List}\/ bekanntgemacht.  Es
werden also nur Typinformationen referenziert, die zur
"Ubersetzungszeit relevant sind, nicht aber zur Laufzeit.  Die
Implementation von dort deklarierten Funktionen etc.\ kann auf diese
Weise also nicht angesprochen werden.  Folglich wird die Schnittstelle
(ohne Implementation) zum Evaluieren des Modulwertes nicht ben"otigt.

Wie ein Modul kann eine Schnittstelle bzw.\ die Typinformation an
einen Namen (den Schnittstellennamen) gebunden und auf dem Toplevel
definiert werden.

