Bei der Zusammenstellung von Texten und Abbildungen wurde mit größter Sorgfalt vorgegangen. Trotzdem können Fehler nicht vollst ändig ausgeschlossen werden. Verlag, Herausgeber und Autoren können für fehlerhafte Angaben und deren Folgen weder eine juristische Verantwortung, noch irgendeine Haftung übernehmen. Für Verbesserungsvorschläge und etwaige Hinweise auf Fehler sind Verlag und Autor dankbar. Die gewerbliche Nutzung der in diesem Produkt gezeigten Modelle und Arbeiten ist nicht zulässig.
Das Werk einschließlich all seiner Teile ist urheberrechtlich geschützt. Jede Verwertung außerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne Zustimmung des Verlages unzulässig und strafbar. Das gilt insbesondere für Verfielfältigungen, Übersetzungen, Mikroverfilmungen und die Einspeisung, Verarbeitung und Verbreitung in elektronischen Systemen.
Meiner Frau Ursula und meinen Söhnen Thomas und Johannes in Liebe gewidmet
Inhaltsverzeichnis
Vorwort
I Grundlagen
1 Einführung
1.1 Konstitutive Prinzipien in A++
Abstraktion
Referenz
Synthese
Closure
Lexical Scope
2 Sprachdefinition
2.1 Syntax und Semantik von A++
Anmerkungen zur Syntax:
2.2 Beispiele zur Syntax von A++
Beispiele zur Abstraktion 1. Alternative in 2.2
Beispiele zur Abstraktion 2. Alternative in 2.2
Beispiele zur Referenz 2.3
Beispiele zur Synthese 2.4
2.3 A++ Erweiterung
Syntax von A++ mit vorgegebenen Primitiv-Abstraktionen
Beispiele zu den Erweiterungen in A++
3 Erste Entfaltung von A++
3.1 Programmierstil in A++
3.2 Grundlegende Logische Abstraktionen
Abstraktionen ‘true’ und ‘false’
Abstraktionen ‘lif’
3.3 Erweiterte Logische Abstraktionen
3.4 Numerische Abstraktionen
Abstraktion für die Zahl ‘0’
Abstraktion für die Zahl ‘1’
Abstraktion für die Zahl ‘2’
Abstraktion für das Prädikat ‘zerop’
Abstraktion für die Zahl ‘3’
Utility-Abstraktion ‘compose’
Abstraktion für die Addition
Abstraktion für die Inkrementierung
Abstraktion für die Multiplikation
3.5 Abstraktionen für Listen
Abstraktion für den Konstruktor
Abstraktion für den Selektor ‘lcar’
Abstraktion für den Selektor ‘lcdr’
Anwendung der grundlegenden Operationen für Listen
Abstraktion für das Ende einer Liste
Abstraktion für das Prädikat ‘nullp’
Abstraktion für die Längenabfrage
Abstraktion zum Entfernen eines Objektes aus einer Liste
3.6 Erweiterte Arithmetische Abstraktionen
Abstraktion für ‘zeropair’
Abstraktion für die Dekrementierung
Abstraktion für die Subtraktion
3.7 Relationale Abstraktionen
Abstraktion für das Prädikat ‘gleich’
Abstraktion für das Prädikat ‘größer als’
Abstraktion für das Prädikat ‘kleiner als’
Abstraktion für das Prädikat ‘größer gleich’
3.8 Funktionen Höherer Ordnung
Abstraktion ‘compose’
Abstraktion für die ‘curry’-Funktion
Abstraktion für die Abbildung einer Liste
Abstraktion für die ‘curry map’-Funktion
Abstraktion für die Auswahl aus einer Liste
Abstraktion für die Suche nach einem Objekt in einer Liste
3.9 Mengen-Operationen
Abstraktion für das Prädikat ‘memberp’
Abstraktion für das Hinzufügen eines Elementes
Abstraktion für die Vereinigung von Mengen
4 Erste Anwendung von A++
4.1 Utility-Abstraktionen
Abstraktion für das sortierte Einfügen in eine Liste
Abstraktion für die Sortierung
4.2 Rekursion
Abstraktion für die Berechnung der Fakultät
Abstraktion für die Summation
Abstraktion für den Zugriff auf ein Element einer Liste
Abstraktion für die Iteration über die Elemente einer Liste
4.3 Imperative Programmierung in A++
Die Abstraktion ’while’ in A++
5 Objekt-Orientierte Anwendung von A++
5.1 Einleitung
Bildung von Klassen
Instanzen von Klassen
Beispiele für Objekt-orientierung in A++
5.2 Erstes Beispiel zur Objektorientierung in A++.
Konstruktor für Objekte der Klasse “account”
Erzeugung des Objektes “acc1” durch Aufruf von “make-account”
Senden der Botschaft “deposit” an das Objekt “acc1”
Ausführen der Funktion “deposit”
Detaillierter Code in A++
Anmerkungen zu dem ersten Beispiel zur Objektorientierung
Anmerkungen zum Aufruf der Funktion ‘konto’
5.3 Zweites Beispiel zur Objektorientierung in A++.
Anmerkung zu den einzelnen Klassen
Beziehungen zwischen den Klassen
Zusammenfassung
5.4 Drittes Beispiel zur Objektorientierung in A++.
Anmerkung zu den einzelnen Klassen
6 Abstraktion, Referenz und Synthese im Detail
6.1 Addition der zwei Zahlen ‘two’ und ‘three’
Synthese von ‘add’ und ‘two three’ (1)
Abstraktion von ‘add’ (1)
Auflösung der Referenz von ‘add’ in [1]
Synthese von (lambda(m n) . ) und ‘two three’ in [3]
Abstraktion von ‘compose’
Auflösung der Referenz von ‘compose’ in [4]
Synthese von (lambda(f g) .) und ‘(two f) (three f)’ in [6]
Abstraktion von three:
Auflösung der Referenz von ‘three’ in [7]
Synthese von (lambda(f) .) und ‘f’ in [9]
Synthese von (lambda(x) .) und ‘x’ in [10]
Abstraktion von two:
Auflösung der Referenz von ‘two’ in [11]
Synthese von (lambda(f) .) und ‘f’ in [13]
Synthese vom inneren (lambda(x) .) und ‘(f (f (f x)))’ in [14]
6.2 Multiplikation der zwei Zahlen ‘two’ und ‘three’
Synthese von mult und ‘two three’
Abstraktion von mult:
Auflösung der Referenz von ‘mult’ in [17]
Synthese von (lambda(m n) . ) und ‘two three’ in [19]
Abstraktion von compose:
Auflösung der Referenz von ‘compose’ in [20]
Synthese von (lambda(f g) .) und ‘two three’ in [22]
Abstraktion von two:
Abstraktion von three:
Auflösung der Referenz von ‘two’ und ‘three’ in [23]
Synthese vom inneren (lambda(f) .) und ‘x’ in [26]
Synthese von (lambda(f) .) und ‘(lambda(x0) .)’ in [28]
Synthese vom inneren (lambda(x0) .) und ‘x1’
Synthese von (lambda(x0) .) und ‘(x(x(x x1)))’
Umbenennung der Variablen: x –>f und x1 –>x.
7 Infrastruktur für A++
7.1 Support-Funktionen
Abstraktion für die Ausgabe einer Zahl
Abstraktion für die Ausgabe eines boole’schen Wertes
Abstraktion für die Ausgabe von Listen
7.2 A++ Interpreter
Linux
MS-Windows
Programmbeendigung
7.3 Initialisierungsdatei für den ARS-Interperter
7.4 WWW-Adressen
8 Erweiterung von A++
8.1 ARS++
8.2 ARSAPI
II ARS und C++
9 Einleitung
9.1 ’Garbage Collection’ in C++
9.2 Kurzeinführung in C++
Modularisierung
Variable, Zeiger und Referenzen
Definition von Klassen in C++
Erzeugung von Objekten
Kommunikation mit Objekten
Überladen von Operatoren
Zeiger auf das implizite Objekt
Operator zur Festlegung des Namensraumes
9.3 Einführung zum ARS-Interpreter in C++
9.4 Klassen-Hierarchie
9.5 Klasse LObject
9.6 Klasse Object
9.7 Klasse Integer
9.8 Klasse Symbol
9.9 Klasse String
9.10 Klasse List
9.11 Globale Funktionen
9.12 Klasse Null
9.13 Klasse Assoc
9.14 Klasse ARSParser
9.15 Klasse ARSClosure
9.16 Klasse ARSEval
9.17 Klasse LCar
9.18 Klasse LCadr
9.19 Klasse LIncr
9.20 Klasse LLoad
9.21 Klasse LPrint
9.22 ARS-Fehlerbehandlung
9.23 Hauptprogramm
9.24 Prozedur für die Erzeugung des ausführbaren Programmes
10 Direkte Umsetzung von ARS in C++
10.1 Schlüssel für die Umsetzung von ARS in C++
10.2 Datentypen für die Umsetzung von ARS in C++
10.3 Klasse ‘Env’ im Detail
10.4 Klasse ‘Clam’ im Detail
10.5 Anwendung der ARS-Klassen in C++
Abstraktion
Referenz
Synthese
Einfaches Beispiel
10.6 Testprogramm
Hauptprogramm
Test des funktionalen Programmierstils
Test des objekt-orientierten Programmierstils
Externe Hilfsmittel
10.7 Listen des Quell-Codes
III ARS und C
11 Einleitung
11.1 Sprachliche Hilfsmittel in C
typedef
enum
struct
union
setjmp/longjmp
11.2 Datenstrukturen im ARS-Interpreter
NAME
PRIM
VTYPE
EXPTYPE
ABS
SYN
EXP
ELIST
NLIST
VLIST
ENV
LFUN
CLAM
ACL
THUNK
VALUE
11.3 Beschreibung der Funktionen
Konstruktoren
Der Umgang mit Variablennamen
Variable und Umgebungen
Auswertung von Ausdrücken
Schnittstellen für die Eingabe
Einlesen von ARS-Code durch den ARS-Parser
12 Direkte Umsetzung von ARS in C
Datentypen
Anwendung
Beispiel
12.1 Steuerungs- und Testprogramm
Hauptprogramm
Test des objekt-orientierten Programmierstils
Test des funktionalen Programmierstils
12.2 Externe Hilfsmittel
12.3 Quellcode des ARS-Interpreters
Modul ARSC: Datentypen und Prototypen
Modul ARSC: Implementierung
Modul ARSParser
Testmodul: Funktionsprototypen
Hauptsteuerung und Testmodul
Prozedur zur Erstellung des Programms
12.4 Performance-Vergleich der ARS-Interpreter
Anhänge
A Das Lambda-Kalkül
A.1 Syntax eines Lambda-Ausdrucks
A.2 Begriffe und Regeln des Lambda-Kalküls.
Assoziativitätsregeln
Gebundene und freie Variable.
Alpha-Konvertierung
Beta-Reduktion
Eta-Reduktion
Y-Kombinator
A.3 Beispiele für Beta-Reduktion
Lambda-Kalkül-Programmierung in Scheme-Codierung
Auszuwertende Lambda-Ausdrücke in Scheme-Codierung
Basis-Abstraktionen in Scheme-Codierung
Anwendung mit Beta-Reduktion
B Gültigkeitsbereich von Namen
B.1 Interpretation von Namen
Dynamic Scope
Static Scope
Global Scope
Local Scope
B.2 Auswirkung der Art der Symbolinterpretation auf die Programmierung
Auswirkung von ”Dynamic Scope“ auf die Programmierung
Auswirkung von ”Static Scope“ auf die Programmierung
Verdeutlichung der Unterschiede von ”dynamic scope“ und ”lexical scope“ anhand von Beispielen
Schlusswort
Biographische Daten zur Person des Autors
Verzeichnis der Fundamentalbegriffe
Abbildungsverzeichnis
Listings
Literaturverzeichnis
Index
Vorwort
Einleitung
Dieses Buch ist basiert auf dem 1032-sepitigen Buch‘Programmierung pur’, das in der 2. erweiterten Auflage von demselben Autor im Verlag S.Toeche-Mittler in Darmstadt im Jahre 2003 veröffentlicht wurde. Die 1. Auflage erschien im Jahre 2002.(Siehe [8].), [7]).
Die Eigenschaften von A++ werden in verschiedenen Büchern in dieser Reihe vorgestellt, jedesmal mit einem anderen Schwerpunkt. Dasvorliegende Buchwird unterPunkt 3in der folgenden Liste beschrieben.
1. InA++ Die kleinste Programmiersprache der Welt[10] geht es darum, die theoretischen Grundlage dieser Sprache zu präsentieren und die Mächtigkeit von A++ aufzuzeigen.
2. In dem 2. BuchProgrammieren lernen mit A++[13] ist auch eine Einführung in A++ enthalten, der Fokus des Buches liegt aber darauf zu zeigen, wie in den anwendungsorientiertenProgrammiersprachen Python und JavaA++-orientiert programmiert werden kann.
In der englischsprachigen AusgabeA++ The Smallest Programming Language in the Worldwird außerdem dieProgrammiersprache Perlund die A++-orientierte Programmierung in dieser Sprache erläutert.Siehe:[11]!
3. In dem 3. BuchA++ und systemnahe Programmiersprachen[12] liegt der Schwerpunkt darauf, aufzuzeigen, wie auch in den Programmiersprachen C und C++ A++orientiert programmiert werden kann.
4. In dem 4. BuchVon A++ nach ARS++[14] wird schließlich eine Erweiterung von A++ vorgestellt, die einer neuen Programmiersprache entspricht (mit Compiler und virtueller Maschine) in der die Funktionalität von Python, Java, C++ und C enthalten ist. Dies ist mglich, da in ARS++ eine Schnittstelle zu den anderen Sprachen namens ARSAPI eingebaut ist.
DieWerkzeuge und Hilfsmittelzu diesem Buch werden in einem Download-Verzeichnis im Internet bereitgestellt.Siehe: 7.4 auf Seite 85.
Theoretische Grundlagen von A++
Zweck des Buches
In diesem kleinen Büchlein, geht es primär darum an der Programmierung interessierten Leserinnen und Lesern ein Instrument vorzustellen, mit dem sie sehr schnell und sehr effizient Programmieren lernen können, ohne sich schon für eine der populären, voll-ausgebauten Programmiersprachen entscheiden zu müssen und ohne einen großen Kostenaufwand zu haben.
Dass es möglich ist, mit den Denkmustern von A++ in anderen Programmiersprachen produktiv sein zu können wird in diesem Buch gezeigt, indem nach einer Einführung in die ProgrammiersprachenC++undCdieA++-orientierte Programmierungin diesen zwei Sprachen vorgestellt wird.
Diese zwei ausgewählten Programmiersprachen gehören zu der Gruppe der systemnahen Programmiersprachen, die meistens benutzt werden fr die Programmierung von Betriebssystemen (z.B. Linux) und Systemhilfsprogramme.
Im Unterschied dazu gibt es die Programmiersprachen für die anwendungsorientierte Programmierun, wie z.B. Python, Perl und Java. Diesen Programmiersprachen im Zusammenhang mit A++ widmet sich das BuchProgrammieren lernen mit A++. (Siehe:[13]).
Thematik des Buches
Das Wesentliche der Programmierung
A++ist die kleinste Programmiersprache der Welt, deren Sinn es ist einzig dasWesentliche der Programmierungdarzustellen, und zwar in einer Form dass damit gearbeitet werden kann, dass man es einüben kann. So soll A++ hilfreich sein beim Erlernen des Programmierens ganz allgemein, aber auch beim Erlernen von konkreten Programmiersprachen.
Elementarteilchen der Programmierung
InA++werden dieElementarteilchen der Programmierungin reinster Form sichtbar gemacht. Man kann diese gründlich studieren, den richtigen Umgang mit ihnen einüben und sich so die wichtigsten Rüstzeuge der Programmierung aneignen.
Vereinfachung der Programmierung
In dem Bemühen, Programmierung auf das Wesentliche zu reduzieren, geht es darum, Lernende zu bewahren, sich von einer Unzahl von Vorschriften und Regeln einer bestimmten Programmiersprache die Programmierung an sich vergraulen zu lassen.
Energien, die in den meisten Sprachen für die Beherrschung und das Einhalten der Syntax aufgebracht werden müssen, kommen in A++ der wichtigeren Aufgabe der logischen Bewältigung des zu lösenden Problems zugute.
Einfache, umfassende und m ächtige Denkmuster
Es wird hier dank des Lambda-Kalküls eine Sicht der Programmierung gewonnen, die eine befreiende Wirkung hat. Das Denken wird aus den Niederungen des komplexen Regelwerks einer bestimmten Programmiersprache herausgeholt und heraufgehoben auf die Höhen eineseinfacheren,umfassenderenund deshalbmächtigerenDenkens. Das Lambda-Kalkül bietet die theoretische Grundlage für eine solche Sicht.
Verallgemeinerung des Lambda-Kalküls
Der NameA++ist eine Abkürzung vonAbstraktion plus Referenz plus Synthese. Hiermit werden die dreiPrinzipien von A++benannt, die gleichzeitig ihr einziger Inhalt sind. Diese Prinzipien stellen eine Verallgemeinerung der Grundoperationen des Lambda-Kalküls von Alonzo Church dar. Das Lambda-Kalkül ist ein mathematisch-logisches System, das 1941 von dem LogigerAlonzo Churchin seinem Buch:‘The Calculi of Lambda Conversion’der Welt vorgestellt wurde. Siehe hierzu unsere kurze Zusammenfassung im Anhang A auf Seite 247.
Während das Lambda-Kalkül der Funktionalen Programmierung ihre theoretische Grundlage liefert, istA++in der Lage einetheoretische Grundlage für die drei bekanntesten Paradigmen der Programmierungzu liefern, d.h. für die funktionale, die objekt-orientierte und die imperative Programmierung.
Verallgemeinerung der Grundoperationen des Lambda-Kalküls:
•Abstraktion:Etwas einen Namen geben
•Referenz:Auf etwas mit seinem Namen Bezug nehmen
•Synthese:Aus zwei oder mehr Dingen etwas Neues erzeugen
Die Primitiv-Operationen vonA++gehen inhaltsmäßig über die Grundoperationen des Lambda-Kalküls hinaus, indem ihnen in der Anwendung in einem Programm jedwede Einschränkung genommen wird.
Die Verallgemeinerung besteht darin, dass der Begriff der Abstraktion allgemeiner als im Lambda-Kalkül definiert wird, nämlich als ’etwas einen Namen geben’. Hinter dem Namen verbergen sich alle Details des Definierten.Eine solche Namensvergabe setzt eine explizite Namensdefinition voraus.
ImLambda-Kalküldagegen ist eine explizite Vergabe eines Namens für eine Lambda-Abstraktion bei deren Bildung nicht vorgesehen. Dort erfolgt sie lediglich implizit bei einer Synthese von Lambda-Ausdrücken.
Die Auswirkungen dieses zunächst als klein erscheinenden Unterschiedes sind gewaltig: Während ein Ausbau desLambda-Kalkülsimmer in die Funktionalen Programmiersprachen mündet, können inA++allgmeine Muster der Programmierung definiert werden, die sowohl auf dieFunktionaleProgrammierung als auch auf dieObjekt-orientierteund dieImperativeProgrammierung angewandt werden können.
Wer sich in seinem Programmieren von den Prinzipien in A++ leiten lässt, wird Programme erstellen, die nicht nur funktionieren, sondern die auch schön sind, Programme, bei denen Leser und Leserinnen mit Bewunderung die Abstraktionen und Synthesen nachempfinden und genießen können.
Erlernen von neuen Programmiersprachen
In‘Programmierung pur’wirderstmalig der Versuch unternommen, den Weg zum Erlernen der Programmiersprachen Scheme, Java, Python, C und C++ anhand der mittlesA++erarbeiteten Denkmuster aufzuzeigen. ‘Programmierung pur’ behandelt diese Thematik nicht nur theoretisch, sondern präsentiert umfangreiche Fallstudien, um den Bezug zur Programmierpraxis zu gewährleisten.
Adressatenkreis
Dieses Buch wendet sich ebenso wie ‘Programmierung pur’ anProgrammiererund solche, die es werden wollen. Es möchte ihnen mit der speziellen Denkweise die Programmierung erleichtern, besonders auch das Erlernen neuer Sprachen. Mit der nahegelegten Sicht der Programmierung wird eine Sprachenunabhängigkeit gewonnen, ja man ist sogar offen für verschiedene Paradigmen der Programmierung. Mit der Erfahrung der gewonnenen Flexibilität ausgerüstet wird ein Programmierer oder eine Programmiererinmit mehr Freude und größerer Effizienzdie Probleme der Programmierung meistern.
Das Buch wendet sich auch anAnfänger der Programmierung. Jedoch sollte eingroßes Interesse für die Programmierungaufgrund einer persönlichen Eignung und Neigung vorhanden sein.
Zusammenfassend kann Zielgruppe des Buches wie folgt beschrieben werden:
Das Buch ist gedacht für Menschen, die einen Ausbildungsbedarf in den Grundlagen der Programmierung besitzen.
•Dies sindStudenten aller Fachrichtungen der Informatiksowie Studenten der Mathematik und Physik.
•Dies sindLehrer und Schüler an Gymnasien, die in der Oberstufe Informatikunterrich gestalten oder an ihm teilnehmen.
•Dies sind ferner alleAngestellten in der Industrie, die sich, aus welchen Gründen auch immer, mit der Programmierung auseinandersetzen müssen.
•Programmierer, die bereits programmieren können, sich aber nicht scheuen, etwas Neues kennen zu lernen, kommen als potentielle Nutznießer dieses Büchleins gewiss ebenfalls in Betracht.
Danksagung
Danken möchte ich vor allem den Vielen, die in uneigennütziger Weise durch die Bereitstellung ihrer Software zur kostenlosen Nutzung zum Zustandekommen dieses Buches beigetragen haben.
Zu dieser frei verfügbaren Software gehört natürlich TEX, LATEX, teTeX, Linux, XFree86, vim, psutils, ghostview und die vielen Scheme-Implementierungen, ganz besonders GambitC und libscheme.
Dann gilt mein Dank natürlich ganz besonders Alonzo Church, dem wir das Lambda-Kalkül verdanken und Guy L. Steele mit Gerald J. Sussman, die dieses Lambda-Kalkül als Ausgangsbasis für die Entwicklung ihrer Programmiersprache Scheme genommen haben.
Der Dank erstreckt sich auch auf die im Literaturverzeichnis aufgeführten Autoren, die uns das Lambda-Kalkül näher gebracht haben.
Georg P. Loczewski
Groß-Zimmern, im Dezember 2002 bzw. im Mai 2018
Teil I
Grundlagen
Kapitel 1
Einführung
1.1 Konstitutive Prinzipien in A++
A++steht fürAbstraktion plus Referenz plus Synthese. Diese drei Begriffe entsprechen densprachlichen Strukturelementenund denGrundoperationen in A++und werden deshalb im nächsten Kapitel im Zusammenhang mit der Syntax der Sprache noch ausführlich behandelt.
Zu den konstitutiven Prinzipien, d.h. den Prinzipien, die A++ wesentlich zu dem machen, was es ist, gehören außerdem noch die Begriffe‘Closure’und‘Lexical Scope’. Wir werden sie der Reihe nach definieren und beschreiben.
Abstraktion
FUNDAMENTALBEGRIFF1 (ABSTRAKTION)
Abstrahieren bedeutet:Etwas einen Namen geben.Es besteht darin, etwas Komplexes zu behandeln, als wäre es etwas Einfacheres, indem Details ignoriert werden.
Eine solche Abstraktion wird auch alsLambda-Abstraktionbezeichnet, wenn mit ihr dieDefinition einer Funktionverbunden ist, die zwangsläufig zurErzeugung einer ‘Closure’mündet. Bezüglich des letzteren Punktes siehe weiter unten die Definition des vierten konstitutiven Prinzips.
Referenz
FUNDAMENTALBEGRIFF2 (REFERENZ)
Auf etwas, das einen Namen erhalten hat, kann jederzeit mit diesem Namen Bezug genommen werden. Diese Bezugnahme nennen wir Referenz.
Im Zusammenhang mit der Referenz ist von großer Bedeutung auf welche Namen Bezug genommen werden kann. Dies führt zum letzten konstitutiven Prinzip von A++, dem Begriff des‘Lexical Scope’.
Synthese
FUNDAMENTALBEGRIFF3 (SYNTHESE)
Eine Synthese zu bilden bedeutet: Zwei oder mehrere Dinge (die selbst Ergebnis einer Abstraktion sind!) miteinander zu verknüpfen um etwas Neues (Komplexes) zu schaffen.
Der Begriff der Synthese entspricht weitgehend dem des Aufrufs einer Funktion oder der Abbildung, bzw. der Applikation.
Closure
Die Bildung einer Abstraktion ist in A++ nicht ein absolutes, von Allem losgelöstes Ereignis.Eine Abstraktion erfolgt immer in einem bestimmten Kontext