
%%%%%%%%% Alte Gliederung %%%%%%%%%%
%\chapter{objektorientierte Programmierung in TL}
%Das Kapitel stellt einige Ans"atze, objektorientierte Programmierung in
%TL zu erm"oglichen, vor. Es werden die grundlegenden Schwierigkeiten bei
%der vollst"andigen Umsetzung der f"ur eine Massendatenbibliothek erstrebenswerten objektorientierten Konzepte dargestellt.
% \section{Beispiele}
%
%  \subsection{Style}Bei der Implementation von Style-Objekten werden
%  diese als Instanzen eines ADT's mit Hilfe von Modulen modelliert.
%  Dabei wird der Widerspruch zwischen Kapselung des ADT's und
%  inkrementeller Erweiterung in der Subklasse durch unterschiedliche
%  Modulebenen f"ur reine Nutzer und f"ur Subklassenimplementierer aufgel"ost.
%  %%\cite{Ingrids Diss,...}
%
%  \subsection{Starview}Die Einbindung einer externen klassenorientierten Grafikbibliothek\ldots.
%
%  \subsection{Fibonacci}\ldots\cite{AlbGhe}
%
% \section{Grenzen von TL}
%
%  \subsection{Methodenredefinition und 'late binding'}Die Realisierung
%des Konzepts der abstrakten Klasse verlangt die M"oglichkeit zur
%Redefinition von Methoden und die Bindung an Aufrufe dieser Methoden
%in vorab definiertem, abstraktem Protokoll. Daf"ur sind in TL
%'Self-Parameter' notwendig, die im Methodenrumpf den Selbstbezug auf die aktuellen
%Methoden erm"oglichen.
%  
%  \subsection{Methodenredefinition und Typisierung}Problematisch ist das
%"Uberschreiben von Methoden, die andere, noch nicht realisierte,
%virtuelle Methoden nutzen oder andere Objekte des Klassentyps
%ben"otigen. Solche Methoden haben 'Self-Parameter' bzw. Parameter vom
%Objekttyp. Die Redefinition in spezialisierten Subklassen scheitert an
%der Kontravarianzregel.
%
% \section{Schlu"sfolgerungen f"ur das Tycoon-Projekt}Die Neugestaltung
%der Massendatenbibliothek erfolgt in TooL, einer neuen
%objektorientierten Hochsprache des Tyoon-Systems. TooL ist als neues
%Compiler-Frontend neben TL realisiert.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


	
\chapter{Bibliotheksentwurf in TL} \label{oointl}Die in den vorhergehenden
Kapiteln herausgearbeiteten Qualit"atsmerkmale f"ur Softwarebibliotheken im
allgemeinen und Bibliotheken f"ur Massendatentypen im besonderen (Kapitel
\ref{SoftBibs}), sowie die in Abschnitt \ref{ModProg} dargelegten Schw"achen
einer modulorientiert entworfenen Massendatenbibliothek f"uhren zur Bevorzugung
eines objektorientierten Entwurfsansatzes. Dies wirft die Frage auf, inwieweit
sich ein solcher Ansatz durch einen  
objektorientierten Programmierstil in der Programmiersprache TL, der
hochsprachlichen Schnittstelle des Tycoon-Systems umsetzen l"a"st. 
Dabei treten einige grundlegende Schwierigkeiten auf. Diese sollen 
hier anhand einiger Beispiele zusammengefa"st werden. Der direkt
anschlie"sende 
Abschnitt skizziert aber zun"achst kurz die Eigenschaften von TL.

\section{Die Programmiersprache TL}Dieser Abschnitt stellt einige der f"ur die
weiteren Ausf"uhrungen dieses Kapitels ben"otigten Sprachkonzepte von TL
vor. Eine ausf"uhrliche Beschreibung findet sich in \cite{MMS94,Mat92}.

TL ist eine strikt typisierte, funktionale Sprache, die aber auch imperative
Eigenschaften wie destruktive Zuweisungen und Seiteneffekte in Funktionen
beinhaltet. Der imperativen Seite ist z.B. die explizite Deklaration von
ver"anderbaren Variablen mit Hilfe des Schl"usselwortes {\bf var}
zuzurechnen. TL definiert eine strukturelle Subtypbeziehung durch statische
"Uberpr"ufung induktiv formulierter Typregeln. Funktionen und Typen sind in TL
gleichberechtigte Sprachkomponenten ({\em first class status}), das hei"st, sie
k"onnen beispielsweise auf 
Variablen zugewiesen oder auf Funktionsparametern "ubergeben werden. TL
unterst"utzt Subtyppolymorphismus und gebunden parametrischen
Polymorphismus. Weiterhin bietet die Sprache benutzerdefinierte
Typoperatoren zur Formulierung generischer Typausdr"ucke. Die Typhierarchie der
nicht parametrisierten Typen wird durch den Supertyp aller Typen {\bf Ok} nach
oben hin und durch den Subtyp aller Typen {\bf Nok} nach unten hin
abgeschlossen. Zur Modularisierung der Programme wird die Aufteilung in
Schnittstelle ({\bf interface}) und Implementierung ({\bf module})
unterst"utzt. 

Zur Datenmodellierung bietet TL vordefinierte Typ- und Wertkonstruktoren f"ur
Tupel, Tupel mit Varianten, Records und Arrays. Auch f"ur Funktionen stehen
entsprechende Operatoren zur Verf"ugung. Rekursive Typ- oder Wertbindungen
erfolgen explizit mit Hilfe entsprechender Schl"usselworte ({\bf Rec}, {\bf
rec}). 
Der aggregierende Typkonstruktor {\bf Tupel} beispielsweise "ahnelt einem {\em
Record} in Pascal oder einer {\em Structure} in C. Seine Felder werden durch
eine geordnete Folge von Signaturen beschrieben.

\begin{xple}
  \k{Let} IntegerList $=$ \k{Tuple} RepT $<:$Ok  first():Int \k{end}  
\end{xple}

Der Typ {\sf IntegerList} ist ein Tupel mit einer Typsignatur {\sf RepT} und
einer Funktion {\sf first}. Typsignaturen in Tupeltypen sind die Grundlage f"ur
die Darstellung abstrakter Datentypen in TL. Der Typ {\sf RepT} ist
(semi)abstrakt. "Uber einen Wert dieses Typs sind nur die Informationen
bekannt, welche sich aus der deklarierten Subtypbeziehung ergeben.

Zur Unterst"utzung inkrementeller Softwareentwicklung bietet TL die Konstrukte
{\bf Repeat} und {\bf open}, mit deren Hilfe Typdefinitionen bzw. Wertbindung
wiederholt werden k"onnen. So ist beispielsweise die Definition eines Typs
{\sf Student} unter Verwendung des Typs {\sf Person} sowie die Erzeugung der
korrespondierenden Werte mit Hilfe dieser Schl"usselworte m"oglich.

\begin{xple}
  \k{Let} Person  $=$ \k{Tuple} name :String age :Int \k{end}
  \k{Let} Student $=$ \k{Tuple} \k{Repeat} Person semester :Int \k{end}

  \k{let} paul :Person $=$ \k{tuple} \k{let} name $=$ ''Paul'' \k{let} age $=$ 27 \k{end}
  \k{let} paulAsStudent : Student $=$ \k{tuple} \k{open} paul \k{let} semester $=$ 6 \k{end}
\end{xple}

Der Aufruf von {\bf Repeat} f"uhrt zur Wiederholung der Signaturdefinitionen
des Typs {\sf Person}, w"ahrend mit {\bf open} die Wertbindungen der
Feldbezeichner des Tupelwertes {\sf paul} unter Erzeugung gleichnamiger
Bezeichner in den Tupelwert {\sf paulAsStudent} "ubernommen werden.

F"ur die Beschreibung weiterer Spracheigenschaften und Ausdrucksmittel von TL
sei auf die bereits zu Anfang des Abschnitts genannten Quellen verwiesen. 

\section{Beispiele}

Soll der objektorientierte
Programmierstil in TL etabliert werden, so scheint es zun"achst naheliegend zu 
sein, die Klassen durch abstrakte Datentypen zu beschreiben. Auf diese 
Weise w"are die an der Schnittstelle des abstrakten Datentyps
angebotene Funktionalit"at als Protokoll des Objekts aufzufassen.
\subsection{Subtypbeziehung zwischen abstrakten Datentypen}
Zur Beschreibung des durch eine Klasse definierten Objekts, mu"s an der
Schnittstelle des die Klasse modellierenden abstrakten Datentyps
ein Objekttyp angeboten werden. In dieser Konstellation kommt es zum Konflikt 
zwischen zwei Zielvorstellungen. Einerseits soll bei der Definition
dieses Types die eigentliche Implementierung zumindest teilweise versteckt
werden, was die Definition des Objekttyps als abstrakte Typvariable
begr"undet. Andererseits ist es aber beabsichtigt,    
weitere Klassen zu formulieren, deren Objekte als Subtypen der 
ersten Klasse beschrieben sind. Ein solcher Subtyp kann zwar in der
Schnittstelle noch definiert werden, die Implementierung scheitert jedoch 
an der Kapselung der anderen Klasse. Der 
Supertyp ist nur "uber die Schnittstelle zug"anglich,  wo er als abstrakte
Typvariable deklariert wurde. Bei der Implementierung des ebenfalls abstrakt
definierten Subtyps werden nun Informationen "uber die Beschaffenheit des 
Supertyps ben"otigt, um die Subtypbeziehung einhalten zu k"onnen. Dies bedeutet
aber eine Durchbrechung der Kapselung, die bei der Definition des Supertyps 
durchgef"uhrt wurde. Formal scheitert die Definition des Subtyps an der von TL
verlangten Namens"aquivalenz f"ur abstrakte Typvariablen.

%%%%%%%%%Bild{Subtypisierung von abstrakten Datentypen.}
\begin{figure}[t]
\begin{xple}
  \k{Let} PointD1 $=$ \k{Tuple} T1 $<$: \k{Ok} \k{end};

  \k{let} pointD1 :PointD1 $=$ \k{tuple} \k{Let} T1 $=$ \k{Tuple} x :\k{Int} \k{end} \k{end};

  \k{Let} PointD2 $=$ \k{Tuple} T2 $<$: PointD1.T1 \k{end};

  \k{let} b:PointD2 $=$ \k{tuple} \k{Let} T2 $<$:pointD1.T1 $=$ \k{Tuple}  x,y :\k{Int} \k{end} \k{end}; 
\end{xple}
\caption{Subtypisierung von abstrakten Datentypen}\label{SubtADT}
\end{figure}

In Abbildung \ref{SubtADT} wird die Situation mit Hilfe von Tupeltypen und 
ihren Werten veranschaulicht, welche sich in TL hinsichtlich der Kapselung
genauso 
verhalten wie Schnittstelle und Modul. Der Typ {\sf PointD1} definiert einen in
ein Tupel gekapselten abstrakten Typ {\sf T1}. Die Variable {\sf pointD1} h"alt
einen Wert des Typs {\sf PointD1} mit dem als Tupeltyp implementierten Typ {\sf
T1}. Typ {\sf PointD2} fordert nun einen Subtyp {\sf  
T2} des abstrakten Typs {\sf PointD1.T}. Die Implementierung des Typs {\sf T2}
wird aber aus den oben genannten Gr"unden vom Typ"uberpr"ufungsalgorithmus von
TL zur"uckgewiesen.

%%%%%%%%%Bild{Subtypisierung von abstrakten Datentypen:L"osung}
\renewcommand{\epsfsize}[2]{0.789#1}
\begin{figure}[htb]
\begin{center}
\leavevmode
\epsfxsize=14cm
\epsffile{../Bilder/bjoern/TL.ADT.ps}
\end{center}
\caption{Schichtung von Spezifikation und Repr"asentation}\label{SubtADTL}
\end{figure}

Eine L"osung des Problems ist m"oglich \cite[S.101]{DissIngrid}, indem
eine zweite Schicht von Schnittstellen eingef"uhrt wird, so da"s jede Klasse
schlie"slich durch 
zwei Schnittstellen und die entsprechenden Implementationen repr"asentiert wird
Die obere Schnittstelle dient nur dazu, den Objekttyp zu kapseln und 
gleichzeitig eine Subtypbeziehung zwischen den Objekttypen verschiedener
Schnittstellen zuzulassen. Dies wird erreicht, indem die Objekttypen 
dieser ersten Schicht in den Implementationsmodulen gleichgesetzt werden.
Damit wird nach au"sen hin die Subtypbeziehung aufrechterhalten. Die erste
Schicht entspricht in Abbildung \ref{SubtADTL} den Typen {\sf PointD1} und {\sf
PointD2}  
sowie den zugeh"origen Variablen.

%%%%%%%%%Bild:Methoden Redefinition ohne SelfParameter.
\begin{figure}[htb]
\begin{center}
\begin{xple}
\begin{tabbing}
        \=      \k{let} empty :\k{Bool} $=$ size() $==$ 0                          \=\kill
\>\k{module} superClass\>\k{module} subClass\\
\>  \k{import}\>  \k{import} superClass\\
\>  \k{export}\>  \k{export}\\
\>  \k{Let} T $<$:\k{Ok} $=$ \k{Tuple}\>    \k{Let} T $<$:\k{Ok} $=$ \k{Tuple}\\
\>    \k{var} size() :\k{Int}\>        \k{Repeat} superClass.T\\
\>    \k{var} empty() :\k{Bool}\>      \k{end}\\
\>    \k{end}\>  \k{let} create() :T $=$\\
\>  \k{let} create() :T $=$\>    \k{begin}\\
\>    \k{tuple}\>      \k{let} super $=$ superClass.create()\\
\>      \k{let} \k{var} size() :\k{Int} $=$\>      \k{let} result $=$ \\
\>        \k{raise exception} 'virtuelle Methode'\>        \k{tuple}\\
\>      \k{let} \k{var} empty() :\k{Bool} $=$ size() $==$ 0\>          \k{open} super\\
\>    \k{end}\>        \k{end}\\
\>\k{end};\>      result.size $:=$ \k{fun}() :\k{Int} ...\\
\>\>      result\\
\>\>    \k{end}\\
\>\>\k{end};\\
\end{tabbing}
\end{xple}
\end{center}
\caption{Virtuelle Methoden I.}\label{RdOhSe}
\end{figure}

Die Schnittstelle der zweiten Schicht
legt nun den eigentlichen Objekttyp offen. Dadurch ist auf dieser Schicht
die Kapselung kein Hindernis mehr f"ur die Formulierung von
Subtypbeziehungen zwischen den Objekttypen. In Abbildung \ref{SubtADTL} findet 
man die zur zweiten Schicht korrespondierenden Typen {\sf PointD1Rep} und {\sf
PointD2Rep}. Da nun nach
au"sen hin "uber die erste Schicht andere Objekttypen angeboten werden als
die letztlich f"ur die Zustandsrepr"asentation notwendigen Objekttypen der
zweiten Schicht, mu"s bei der Implementation des Protokolls der ersten
Schicht die Abbildung auf diese Repr"asentationstypen geleistet werden.
Insgesamt wird der Klassenentwurf und die Verwaltung der Objekte einer Klasse
durch diese Konstruktion komplizierter.

\subsection{Sp"ate Bindung}\label{SptBndng}
Die sogenannte sp"ate Bindung ist f"ur den objektorientierten Entwurf
von entscheidender Bedeutung, insbesondere f"ur die Wiederverwendung von
Implementierungen. Durch die sp"ate Bindung wird es m"oglich, gemeinsames
Protokoll in abstrakten Oberklassen zu spezifizieren. Dieses Protokoll kann
dann durch die Erben der Klasse durch Implementierung der abstrakten Methoden
individuell angepa"st und damit wiederverwendet werden.

Eine weitere M"oglichkeit ist die Optimierung von Methoden in Subklassen. Durch
Redefinition der Methode unter Ausnutzung genauerer Informationen in der
Subklasse kann eine Methode optimiert werden. Das abstrakte Protokoll der
Oberklasse bleibt unber"uhrt.

%%%%%%%%%Bild:Erhalt der alten Bindung.
\renewcommand{\epsfsize}[2]{0.789#1}
\begin{figure}[htb]
\begin{center}
\leavevmode
\epsffile{../Bilder/bjoern/Bind.ohne.Self.ps}
\end{center}
\caption{Fortbestand der alten Bindung}\label{VoBeAlBi}
\end{figure}

Die sp"ate Bindung sollte deshalb bei der Umsetzung eines objektorientierten
Programmierstils in TL auch abgebildet werden. Um die Redefinition von Methoden
zu erm"oglichen, werden diese als auf modifizierbare Variablen zugewiesene
Funktionen modelliert (Abbildung \ref{RdOhSe}). Damit "uberhaupt die Bindungen
der Oberklasse genutzt werden k"onnen, mu"s ein Objekt dieser Klasse explizit
erzeugt werden. Die Bindungen k"onnen dann mit Hilfe des TL-Konstruktes {\bf
open} in das Subklassenobjekt importiert werden. 

In Abbildung \ref{RdOhSe} wird im Modul {\sf superClass} die Methode {\sf size}
als virtuelle Methode
zun"achst nicht implementiert. Sie wird aber von Methode {\sf empty}
genutzt, welche auf diese Weise bereits in der Oberklasse definiert
werden kann. Die Definition der Methode {\sf size} im die Subklasse 
modellierenden Modul {\sf subClass} f"uhrt aber nicht zu dem 
gew"unschten Ergebnis, da durch {\em open} neue Variablen angelegt werden. Es
bleibt f"ur die Methode {\sf empty} die Bindung  
an den alten, eine Ausnahme ausl"osenden Funktionsrumpf erhalten. Die 
Bindungsverh"altnisse werden noch einmal in Abbildung \ref{VoBeAlBi}
skizziert.

Die Zuweisung der neuen Implementierung von {\sf size} ist aber erfolgreich,
wenn sie direkt nach Erzeugung des Objektes der Oberklasse auf die
Funktionsvariable dieses Objekts erfolgt. Alle Bindungen die innerhalb des
Objektes der Oberklasse an die Funktionsvariable bestehen, "ubernehmen jetzt
die neue Implementierung. Problematisch wird es allerdings, wenn die Bindungen
bereits aus einem Vorg"angerobjekt des Objektes der Oberklasse stammen. Die
Variablen dieses Vorg"angers sind nicht mehr erreichbar. Alle Methoden die
Bindungen an diese Variablen enthalten, m"u"sten dann ebenfalls "uberschrieben
werden. 
\subsubsection{Ausnutzung der dynamischen Parameterbindung}\label{DynPara}
Eine Vereinfachung kann jedoch durch Ausnutzung der
dynamischen Bindung von Funktionsparametern erreicht werden. Dazu ist es 
notwendig, einen {\sf Self}-Parameter einzuf"uhren. Statt nun bei der
Implementierung einer Funktion direkt auf die anderen Funktionen oder Variablen
des Objekts zuzugreifen, geht man den indirekten Weg "uber den {\sf
Self}-Parameter der zu implementierenden Funktion. Beim Aufruf einer Funktion
mit {\sf Self}-Parameter mu"s auf diesem das Empf"angerobjekt "ubergeben
werden: {\sf obj.empty(obj).} Auf diese Weise wird sichergestellt, da"s die
aktuellen Bindungen des Objekts ber"ucksichtigt werden.

Als Beispiel dient Abbildung \ref{RdMiSe} in der nun die abgewandelte {\sf empty}-Methode zu 
sehen ist. Sie hat den angek"undigten {\bf Self}-Parameter. In der
Implementierung von {\sf empty} wird nun die {\sf size}-Methode "uber den {\bf
Self}-Parameter angesprochen.

%%%%%%%%%Bild:Methoden Redefinition mit SelfParameter.
\begin{figure}[htb]
\begin{center}
\begin{xple}
\begin{tabbing}
       \=      \k{let} empty :\k{Bool} $=$ size() $==$ 0                          \=\kill
\>\k{module} superClass\>\k{module} subClass\\
\>  \k{import}\>  \k{import} superClass\\
\>  \k{export}\>  \k{export}\\
\>  \k{Let} \k{Rec} T $<$:\k{Ok} $=$ \k{Tuple}\>    \k{Let} \k{Rec}T $<$:\k{Ok} $=$ \k{Tuple}\\
\>    \k{var} size(self :T) :\k{Int}\>        \k{Repeat} superClass.T\\
\>    \k{var} empty(self :T) :\k{Bool}\>      \k{end}\\
\>    \k{end}\>  \k{let} create() :T $=$\\
\>  \k{let} create() :T $=$\>    \k{begin}\\
\>    \k{tuple}\>      \k{let} super $=$ superClass.create()\\
\>      \k{let} \k{var} size(self :T) :\k{Int} $=$\>      \k{let} result $=$ \\
\>        \k{raise exception} 'virtuelle Methode'\>        \k{tuple}\\
\>      \k{let} \k{var} empty(self :T) :\k{Bool} $=$ self.size(self) $==$ 0\>          \k{open} super\\
\>    \k{end}\>        \k{end}\\
\>\k{end};\>      result.size $:=$ \k{fun}(self :T) :\k{Int} ...\\
\>\>      result\\
\>\>    \k{end}\\
\>\>\k{end};\\
\end{tabbing}
\end{xple}
\end{center}
\caption{Methoden mit {\bf Self}-Parameter}\label{RdMiSe}
\end{figure}

Durch eine solches Vorgehen entst"unden eine Vielzahl von Funktionen
mit Parameter vom Objekttyp. Derartige Funktionen werden aber zum Problem, wenn
der Objekttyp in der Subklasse spezialisiert wird und eine Redefinition der
Funktion erfolgen soll. Die Zuweisung auf die in der Oberklasse definierte
Funktionsvariable ist nur m"oglich, wenn der Typ der zuzuweisenden Funktion
Subtyp des Variablentyps ist. Die Spezialisierung des Objekttyps in der
Subklasse und damit des Parametertyps verletzt jedoch die in TL g"ultige
Kontravarianzregel f"ur die Subtypbeziehung von Funktionstypen. 
Ein Verzicht auf die Spezialisierung des Parametertyps w"urde eine zu starke
Restriktion darstellen, da die Information "uber die zus"atzlichen Funktionen
des Objekttyps nicht mehr f"ur die Implementation der Funktionen zur Verf"ugung
st"unde (alle Zugriffe m"u"sten "uber den {\sf Self}-Parameter erfolgen). 

Ein L"osungsansatz f"ur diese Problematik ist es, den {\sf Self}-Parameter  
nicht "uber den Objekttyp des jeweiligen Moduls zu definieren, sondern 
f"ur ihn den Supertyp aller Typen in TL, den Typ {\sf :Ok} zu w"ahlen. Dieser 
k"onnte dann innerhalb des Funktionsrumpfes durch Typumwandlung auf den
Objekttyp des Moduls spezialisiert werden. Dadurch w"are aber der Vorteil der
statischen Typisierung, Laufzeitfehler zu vermeiden, aufgehoben, denn bei
"Ubergabe eines falschen, nicht spezialisierten Objekts w"urde 
die fehlerhafte "Ubergabe nicht mehr zur "Ubersetzungszeit erkannt.
Beim Zugriff auf nicht vorhandene Informationen m"u"ste es dann zwangsl"aufig
zu Laufzeitfehlern kommen.

In Abbildung \ref{MeReTyAn} wird diese Technik 
f"ur die schon bekannten Funktionen {\sf empty} und {\sf size} angedeutet. Der
{\sf Self}-Parameter ist nun vom Typ {\sf Ok} und in der Implementierung der
Funktion {\sf empty} wird
die Funktion {\sf typecast} des Moduls {\sf unsafe} genutzt, um die Funktion
{\sf size} wieder aufrufen zu k"onnen. Im Modul {\sf subClass} wird f"ur die
Realisierung der Funktion {\sf size} die gleiche Technik benutzt.

%%%%%%%%%Bild:Methoden Redefinition mit SelfParameter und Typanpassung.
\begin{figure}[htb]
\begin{center}
\begin{xple}
\begin{tabbing}
       \=      \k{let} empty :\k{Bool} $=$ size() $==$ 0                          \=\kill
\>\k{module} superClass\>\k{module} subClass\\
\>  \k{import} unsafe\>  \k{import} superClass\\
\>  \k{export}\>  \k{export}\\
\>  \k{Let} T $<$:\k{Ok} $=$ \k{Tuple}\>    \k{Let} T $<$:\k{Ok} $=$ \k{Tuple}\\
\>    \k{var} size(self :Ok) :\k{Int}\>        \k{Repeat} superClass.T\\
\>    \k{var} empty(self :Ok) :\k{Bool}\>      \k{end}\\
\>    \k{end}\>  \k{let} create() :T $=$\\
\>  \k{let} create() :T $=$\>    \k{begin}\\
\>    \k{tuple}\>      \k{let} super $=$ superClass.create()\\
\>      \k{let} \k{var} size(self :Ok) :\k{Int} $=$\>      \k{let} result $=$ \\
\>        \k{raise exception} 'virtuelle Methode'\>        \k{tuple}\\
\>      \k{let} \k{var} empty(self :Ok) :\k{Bool} $=$\>          \k{open} super\\
\>        \k{begin}\>        \k{end}\\
\>          \k{let} my $=$ unsafe.typecast(self :T)\>      result.size $:=$\\ 
\>          my.size(my) $==$ 0\>       \k{fun}(self :Ok) :\k{Int}\\
\>        \k{end}\>       ...unsafe.typecast(self :T) ...\\
\>    \k{end}\>      result\\
\>\k{end};\>    \k{end}\\
\>\>\k{end};\\
\end{tabbing}
\end{xple}
\end{center}
\caption{Methoden mit {\sf Self}-Parameter und Typanpassung}\label{MeReTyAn}
\vspace*{0.85cm}
\end{figure}

{\samepage Akzeptabel scheint die geschilderte Technik allenfalls f"ur die
{\bf Self}-Parameter, welche ja immer mit dem 'Empf"angerobjekt' selbst  
instantiiert w"urden. Dieser Vorgang w"are m"oglicherweise durch Einsatz der
Syntaxerweiterungsmechanismen von TL automatisierbar, so da"s die Gefahr eines
Laufzeitfehlers durch falsche "Ubergabe nicht so gro"s w"are. Soll auch die
Spezialisierung anderer, 'normaler' Objekttypparameter erm"oglicht werden, wie
dies in manchen objektorientierten Sprachen der Fall ist, so ist die Technik
nicht verwendbar. Ohne den Schutz der Syntaxerweiterung ist die Gefahr, da"s
Typfehler erst zur Laufzeit bemerkt werden, zu gro"s.  }

%\vspace*{0.5cm}
\subsubsection{Ausnutzung rekursiver Bindung}
Eine weitere M"oglichkeit, die sp"ate Bindung der Methoden zu simulieren, 
besteht darin, statt des {\bf Self}-Parameters eine explizite rekursive 
Bindung zu verwenden, wie in Abbildung \ref{ReBiStSe} zu sehen. Im Modul
{\sf superClass} greift die Funktion {\sf empty} bei ihrer Implementierung nun
"uber die rekursiv gebundene Variable {\sf self} auf die Funktion {\sf size}
zu. Der Vorteil liegt in dem von der Reihenfolge der innerhalb des Tupels
durchgef"uhrten Deklarationen unabh"angigen Zugriff auf diese
Deklarationen.

F"ur die sp"ate Bindung ergibt sich aber kein Unterschied
gegen"uber der Variante ohne {\sf Self}-Parameter, die zu Beginn des Abschnitts
\ref{SptBndng} vorgestellt wurde. Die Spezialisierung durch eine weitere
Funktion erfordert bei der Objekterzeugung die Definition eines neuen
Tupelwertes. In diesem k"onnen dann die Bindung des Superobjekts mittels {\bf
open} importiert werden. Allerdings werden dabei aber neue Funktionsvariablen
angelegt, die  
nur die Wertbindung des Superobjekts "ubernehmen. Dies bedeutet f"ur
das Modul {\sf subClass} in Abbildung \ref{ReBiStSe}, da"s die Zuweisung der
Implementierung von {\sf size} auf diese neue Funktionsvariable erfolgt. 
Die vom Superobjekt "ubernommene {\sf empty}-Funktion ist aber mit 
ihrem Aufruf von {\sf size} weiterhin rekursiv an die Funktionsvariable 
des Superobjekts gebunden. Daher wird der gew"unschte Effekt also
nicht erzielt.

Bei der Verwendung von {\bf Self}-Parametern trat dieses 
Problem nicht auf, da die Bindung "uber den Parameter immer zum Empf"anger
des Funktionsaufrufes selbst und damit zu den aus Sicht des Empf"angers 
aktuellsten Variablenbelegungen erfolgte.
%%%%%%%%%Bild:Methoden Redefinition mit rekursiver Bindung.
\begin{figure}[htb]
\begin{center}
\begin{xple}
\begin{tabbing}
        \=      \k{let} empty :\k{Bool} $=$ size() $==$ 0                          \=\kill
\>\k{module} superClass\>\k{module} subClass\\
\>  \k{import}\>  \k{import} superClass\\
\>  \k{export}\>  \k{export}\\
\>  \k{Let} T $<$:\k{Ok} $=$ \k{Tuple}\>    \k{Let} T $<$:\k{Ok} $=$ \k{Tuple}\\
\>    \k{var} size() :\k{Int}\>        \k{Repeat} superClass.T\\
\>    \k{var} empty() :\k{Bool}\>      capacity() :Int\\
\>    \k{end}\>      \k{end}\\
\>  \k{let} create() :T $=$\>  \k{let} create() :T $=$\\
\>    \k{let} \k{rec} self :T $=$\>    \k{begin}\\
\>    \k{tuple}\>      \k{let} super $=$ superClass.create()\\
\>      \k{let} \k{var} size() :\k{Int} $=$\>      \k{let} result $=$ \\
\>        \k{raise exception} 'virtuelle Methode'\>        \k{tuple}\\
\>      \k{let} \k{var} empty() :\k{Bool} $=$ self.size() $==$ 0\>          \k{open} super\\
\>    \k{end}\>        \k{let} \k{var} capacity() = ...\\
\>\k{end};\>        \k{end}\\
\>\>      result.size $:=$ \k{fun}() :\k{Int} ...\\
\>\>      result\\
\>\>    \k{end}\\
\>\>\k{end};\\
\end{tabbing}
\end{xple}
\end{center}
\caption{Rekursive Bindung statt {\bf Self}-Parameter}\label{ReBiStSe}
\end{figure}

\section{Folgerungen}
Es ist generell m"oglich die ben"otigten objektorientierten Konzepte in TL
abzubilden. Die Simulation aller Konzepte gleichzeitig l"a"st aber die
Modellierungsvorg"ange komplizierter werden. Dadurch wird die 
"Ubersichtlichkeit reduziert und die Wahrscheinlichkeit technisch 
fehlerhafter Modellierung erh"oht. Wie weit sich dieses durch Nutzung der
Syntaxerweiterungsmechanismen von TL vermeiden l"a"st, wurde nicht
abschlie"send untersucht. Ein solches Vorgehen w"urde es aber auch erschweren,
spezifisch auf die objektorientierten Konzepte zugeschnittene
Optimierungen vorzunehmen.
Die oben geschilderten "Uberlegungen und das Verlangen nach einer besseren
Unterst"utzung der objektorientierten Programmierung im Tycoon-System
f"uhrten zur Entwicklung der objektorientierten TL-Variante TooL. Welche als
Implementierungssprache f"ur die im Rahmen dieser Arbeit entwickelte
Beh"alterklassenbibliothek genutzt wurde. Eine Einf"uhrung in diese Sprache und
die Vorstellung der Beh"alterklassenbibliothek sind die Themen der n"achsten
Kapitel.

%%%%%%%%%%%%%%%%Bild: Methoden Redefinition mit SelfParameter.
%\begin{figure}[htp]
%\begin{xple}
%\k{interface} Point
%\k{export}
%  \k{Let} \k{Rec} T $<$:\k{Ok} $=$ \k{Tuple} 
%      \k{var} x  :\k{Int}
%      \k{var} distance(point :T) :\k{Int}
%        \k{}(* Distanz zu einem anderen Punkt *)
%    \k{end}
%  create() :T
%\k{end};
%%\k{module} point
%\k{export}
%  \k{Let} \k{Rec} T $<$:\k{Ok} $=$ Point.T
%  \k{let} create() :T $=$ 
%%    \k{tuple}
%      \k{let} \k{var} x $=$ 0
%      \k{let} \k{var} distance(point :T) :\k{Int} $=$ 
%        \k{begin} x $-$ point.x \k{end}
%%    \k{end}
% \k{end};
%\end{xple}
%\caption{Redefinition von Methoden mit Objekttypparameter I}\label{RdObTyPa}
%\end{figure}
%%%%%%%%Bild:Methoden Redefinition mit SelfParameter.
%\begin{figure}[htb]
%\begin{xple}
%\k{interface} SuperClass
%  \k{import}
%  \k{export}
%%    \k{Let} \k{Rec} T $<$:\k{Ok} $=$ \k{Tuple} 
%      \k{var} size() :\k{Int}             (* wird benutzt *)
%      empty(self :T) :\k{Bool}      (* Benutzer *)
%%%    \k{end}\vspace{0.3cm}
%    create() :T
%%%%\k{end};\vspace{0.7cm}
%%%%%%%\k{module} superClass
%  \k{import} 
%%%%%%%  \k{export}
%  \k{Let} \k{Rec} T $<$: \k{Ok} $=$ SuperClass.T
%%%%    \k{let} create() :T $=$ 
%      \k{tuple}
%        \k{let} \k{var} size() :\k{Int} $=$ 
%          \k{raise exception} 'virtuelle Methode'
%%%%        \k{let} empty(self :T) :\k{Bool} $=$ self.size() $==$ 0
%      \k{end}
%  \k{end};
%\end{xple}
%\caption{Methoden mit {\bf Self}-Parameter}\label{RdMiSe}
%\end{figure}
%%%%%%%%%Bild:Redefinition von Self-parametrisierten Funktionen. 
%\renewcommand{\epsfsize}[2]{0.789#1}
%\begin{figure}[htp]
%\begin{center}
%\leavevmode
%%\epsfysize=4cm
%\begin{xple}
%\k{interface} Point2
%\k{import} :Point
%\k{export}
%  \k{Let} \k{Rec} T $<$:\k{Ok} $=$ \k{Tuple} 
%    \k{Repeat}  Point.T  
%    \k{var} y  :\k{Int}
%  \k{end}
%  create() :T
%\k{end};
%\k{module} point2
%\k{import} point :Point
%\k{export}
%  \k{Let} \k{Rec} T $<$:\k{Ok} $=$ Point2.T
%  \k{let} create() :T $=$ 
%    \k{begin}
%      \k{let} super $=$ point.create()
%      \k{let} result $=$ 
%        \k{tuple}
%          \k{open} super
%          \k{let} \k{var} y $=$ 0
%        \k{end}
%      result.distance $:=$ \k{fun}(point :T) :\k{Int}  
%        \{\ldots result.x $-$ point.x \ldots result.y $-$ point.y \ldots \}
%      result
%    \k{end}
% \k{end};
%\end{xple}
%\end{center}
%\caption{Redefinition von Methoden mit Objekttypparameter II}\label{RdObTyPaB}
%\end{figure}
%\begin{figure}[htb]
%\begin{xple}
%\k{interface} SubClass
%%  \k{import} :SuperClass
%  \k{export}
%    \k{Let} \k{Rec} T$<$:\k{Ok} $=$ \k{Tuple} 
%        \k{Repeat} SuperClass.T 
%      \k{end}
%    create() :T
%\k{end};\vspace{0.3cm}
%\k{module} subClass
%  \k{import} superClass:SuperClass
%  \k{export}
%    \k{Let} \k{Rec} T $<$:\k{Ok} $=$ \k{Tuple}  
%        \k{Repeat} SuperClass.T
%%      \k{end}
%    \k{let} create() :T $=$ 
%      \k{begin}
%        \k{let} super $=$ superClass.create()
%        \k{let} result $=$ 
%          \k{tuple}
%%            \k{open} super
%%          \k{end}
%        result.size $:=$ \k{fun}() :\k{Int} ...
%        result
%%      \k{end}
%\k{end};
%\end{xple}
%\caption{Virtuelle Methoden II}\label{RdOhSeB}
%\end{figure}
%%%%%%%%%
%%%%%%%%%  Text einf"ugen.
%%%%%%%%%
%%%%%%%%%Bild{Subtypisierung von abstrakten Datentypen:L"osung}
%\begin{figure}[htb]
%\begin{xple}
%  \k{Let} A $=$ \k{Tuple} \k{Let} T $=$ \k{Tuple} x :\k{Int} \k{end} \k{end};
%
%  \k{let} a :A $=$  \k{tuple} \k{Let} T $=$ A.T \k{end};
%
%  \k{Let} B $=$ \k{Tuple} \k{Let} T $=$ \k{Tuple} \k{Repeat} A.T y :\k{Int} \k{end} \k{end};
%
%  \k{let} b :B $=$ \k{tuple} \k{Let} T $=$ B.T \k{end};
%
%  \k{Let} C $=$ \k{Tuple} T $<$: \k{Ok} \k{end};
%  
%  \k{let} c :C $=$ \k{tuple} \k{Let} T $<$:\k{Ok} $=$ A.T \k{end};
%
%  \k{Let} D $=$ \k{Tuple} T $<$:c.T \k{end};
%
%  \k{let} d :D $=$ \k{tuple} \k{Let} T $<$:c.T $=$ c.T \k{end};
%\end{xple}
%\caption{Getrennte Schnittstellen}\label{SubtADTL}
%\end{figure}
%%%%%%%%%Bild:Methoden Redefinition ohne SelfParameter.
%\begin{figure}[htb]
%\begin{xple}
%\k{interface} SuperClass
%  \k{import}
%  \k{export}
%    \k{Let} \k{Rec} T $<$:\k{Ok} $=$ \k{Tuple} 
%      \k{var} size() :\k{Int}             (* wird benutzt *)
%      empty :\k{Bool}              (* Benutzer *)
%    \k{end}
%    create() :T
%\k{end};
%\k{module} superClass
%  \k{import} 
%  \k{export}
%  \k{Let} \k{Rec} T $<$: \k{Ok} $=$ SuperClass.T
%    \k{let} create() :T $=$ 
%      \k{tuple}
%        \k{let} \k{var} size() :\k{Int} $=$ 
%          \k{raise exception} 'virtuelle Methode'
%        \k{let} empty :\k{Bool} $=$ size() $==$ 0
%      \k{end}
%  \k{end};
%\end{xple}
%\caption{Virtuelle Methoden I.}\label{RdOhSe}
%\end{figure}
%%%%%%%%%%%%%%%%Bild: Methoden Redefinition mit Typecast.
%\begin{figure}[htp]
%\begin{xple}
%\k{interface} Point
%\k{export}
%  \k{Let} \k{Rec} T $<$:\k{Ok} $=$ \k{Tuple} 
%      \k{var} x  :\k{Int}
%      \k{var} distance(point :\k{Ok}) :\k{Int}
%        \k{}(* Distanz zu einem anderen Punkt *)
%    \k{end}
%  create() :T
%\k{end};
%\k{module} point
%\k{import unsafe}
%\k{export}
%  \k{Let} \k{Rec} T $<$:\k{Ok} $=$ Point.T
%  \k{let} create() :T $=$ 
%    \k{tuple}
%      \k{let} \k{var} x $=$ 0
%      \k{let} \k{var} distance(point :\k{Ok}) :\k{Int} $=$
%        \k{begin} 
%%          \k{let} otherPoint = unsafe.typecast(point :T)
%           x $-$ otherPoint.x
%\k{end} \k{end}
% \k{end};
%\end{xple}
%\caption{Methoden Redefinition mit Typanpassung}\label{MeReTyAn}
%\end{figure}

%\begin{figure}[htp]
%\begin{xple}
%\k{interface} SuperClass
%\k{export}
%  \k{Let} T $<$:\k{Ok} $=$ \k{Tuple}
%    \k{var} size() :\k{Int}
%    empty() :\k{Bool}
%    \k{end}
%  create() :T
%\k{end};
%\k{module}
%\k{export}
%  \k{Let} T $<$:\k{Ok} $=$ SuperClass.T
%  \k{let} create() :T $=$ \k{begin}
%    \k{let} \k{rec} self:T $=$
%      \k{tuple}
%        \k{let} \k{var} size() :\k{Int} $=$ \k{raise} \k{exception}
%        \k{let} empty() :\k{Bool} $=$ self.size $==$ 0
%      \k{end}
%    \k{end}
%\k{end};
%\end{xple}
%\caption{Rekursive Bindung statt {\bf Self}-Parameter}\label{ReBiStSe}
%\end{figure}
%\begin{figure}[htp]
%\begin{xple}
%\k{interface} SubClass
%\k{import} SuperClass
%\k{export}
%  \k{Let} T $<$: \k{Ok}
%     \k{Tuple}
%      \k{Repeat} SuperClass.T
%      \k{var} capacity() :\k{Int}
%    \k{end}
%  create() :T
%\k{end};
%\k{module} SubClass
%\k{import} superClass
%\k{export}
%  \k{Let} T $<$: \k{Ok} $=$ SubClass.T
%  \k{let} create() :T $=$ \k{begin}
%    \k{let} super $=$ superClass.create()
%    \k{let} self $=$
%      \k{tuple}
%        \k{open} super
%        \k{let} \k{var} capacity() $=$ \k{raise} \k{exception}
%      end
%    self.size $:=$ \k{fun}() :\k{Int} 5
%    self
%    \k{end}
%\end{xple}
%\caption{Rekursive Bindung und Spezialisierung}\label{ReBiSp}
%\end{figure}
