APL (Programmiersprache)
APL | |
---|---|
Paradigmen: | funktional, strukturiert, modular |
Erscheinungsjahr: | 1964 |
Designer: | Kenneth E. Iverson |
Entwickler: | Kenneth E. Iverson |
Typisierung: | dynamisch |
Wichtige Implementierungen: | Dyalog APL, IBM APL2, APL2000, Sharp APL, APLX, NARS2000, GNU APL |
Dialekte: | A+, Dyalog APL, APLNext, ELI, J |
Standardisierungen: | ISO8485 (1989), ISO/IEC13751 (2001) |
Beeinflusst von: | Mathematische Notation |
Beeinflusste: | J, K, Mathematica, MATLAB, Nial, PPL, Q, S |
APL, abgekürzt für A Programming Language, ist eine üblicherweise interpretierte Programmiersprache, deren Syntax überwiegend aus Symbolen besteht. Sie wurde von Kenneth E. Iverson und seinen Kollegen<ref>Falkoff, A.D., K.E. Iverson, The Design of APL, IBM Journal of Research and Development, Volume 17, Number 4, 1973-07.</ref> bei IBM in den 1960er Jahren als algorithmische Notation (u. a. für den Mathematikunterricht)<ref>Iverson K.E.,"Notation as a tool of thought (PDF; 2,2 MB)", Communications of the ACM, 23: 444-465 (August 1980).</ref> entwickelt.
Inhaltsverzeichnis
Geschichte
Mit dem Buch A Programming Language aus dem Jahr 1962 gab Kenneth Iverson den Anstoß zur Verwendung eines neuen Konzepts in der Programmierung. Bevor der erste Interpreter verfügbar war, diente APL bereits als Metasprache für die Beschreibung der Architektur des damals neu entwickelten Computersystems IBM System/360 aus der Sicht des Programmierers.<ref>A. D. Falkoff, K. E. Iverson, E. H. Sussenguth: A formal description of SYSTEM/360. In: IBM Systems Journal. Volume 3, Issue 2 (1964).</ref> Ab 1965 wurde APL als Programmiersprache auf Großrechnern (z. B. IBM System/360) implementiert und den Kunden als Timesharing-Option angeboten. Zu jener Zeit wurden IBM-Kugelkopf-Schreibmaschinen als „Terminal“ verwendet. Daher hatte der ursprüngliche Zeichensatz nur (kursive) Großbuchstaben.<ref>Die Schreibmaschine hat einen begrenzten Zeichenvorrat. Spezielle Symbole wurden deshalb durch Übereinandertippen zweier Zeichen erzeugt. Beispiel: Das Zeichen ⍝ wird durch die Folge ⋂ ⍝ Runde eine reelle Zahl Z auf S Stellen [2] ⍝ Standardwert für S ist 2, wenn der Wert beim Aufruf nicht spezifiziert wurde [3] →(0≠⎕NC'S')/RN [4] S←2 [5] RN: R←(10*-S)×⌊0.5+Z×10*S
Diese Funktion und seine Anwendung sollen die Eigenschaften von APL erläutern:
Erläuterung des Programmbeispiels
- Zeile 0: Definition der Funktion mit zwei Argumenten S („Stellen“) und Z („Zahl“) und einem expliziten Ergebnis R.
- Zeilen 1 und 2: Kommentarzeilen (erkennbar an der „Lampe“ ⍝ als erstem Zeichen).
- Zeile 3: Mit einer Bedingung wird geprüft, ob die NameClass („eingebaute Funktion“ ⎕NC) des Namens S ungleich 0 ist. 0 bedeutet „nicht definiert“. Die Verzweigung zur Marke RN gilt, wenn die Bedingung in Klammern = 1 ist, andernfalls wird RN (das einfach nur die Zeilennummer 5 ist), durch die normale APL-Anweisung 0/RN auf den „leeren Vektor“ reduziert („/“ ist der Operator reduce) und es erfolgt keine Verzweigung.
- Zeile 4: Wenn die Bedingung in Zeile 3 nicht erfüllt ist (= Wert ist unbekannt), wird S auf 2 gesetzt.
- Zeile 5: Hier findet die eigentliche Rundung statt. Kennzeichnend ist das „Weiterreichen“ errechneter Werte von rechts nach links, z. B. die Multiplikation des Parameters Z mit den Rundungsstellen S (Z×10*S). Der dadurch erzeugte um S Zehnerpotenzen größere Wert wird anschließend (also links davon) kaufmännisch (Addition von 0.5) gerundet (⌊-Funktion, genannt „floor“) und somit von weiteren Dezimalstellen befreit, so dass er nun ein ganzzahliger Wert ist. Das Ergebnis wird in die links stehende Multiplikation mit (10*-S) weitergereicht, die den Wert wieder um S Zehnerpotenzen verringert. Dies ist das Ergebnis R der Funktion.
Wirkungsweise bzw. Anwendung
Beispiele:
1 Runde 3.14159265 3.1 Runde 3.14159265 3.14 3 Runde 3.14159265 77.123 99.9 3.141 77.123 99.900 Runde 2 2 ρ(ι4)÷7 0.14 0.29 0.43 0.57
- Erstes Beispiel: Anwendung der Funktion auf Pi, Rundung auf 1 Stelle (siehe auch weiter oben).
- Zweites Beispiel: Rundung von Pi auf zwei Stellen, Test des Default-Wertes (linkes Argument fehlt).
- Drittes Beispiel: Rundung eines Vektors auf drei Stellen (rechts fehlende Nullen werden ergänzt).
- Viertes Beispiel: Rundung einer Matrix (Tabelle) auf zwei Stellen (Default) – zwei Zeilen und zwei Spalten erzeugt durch die Funktion ρ aus der Division der ersten vier natürlichen Zahlen (ι4, Funktion iota) durch 7.
Die Funktion Runde kann nicht nur wie oben gezeigt interaktiv ausgeführt werden, sie kann auch in anderen Programmen verwendet werden:
X ← 4 Runde +/MAT
Dabei sei MAT eine Tabelle mit beliebigen Zahlen, die durch die „Summenreduktion“ (+/) spaltenweise summiert wird. Die entstehenden n-stelligen Zahlen (ein Vektor) werden auf 4 Dezimalen gerundet der Variablen X zugewiesen. Stattdessen könnte man auch damit weiterrechnen, sie beispielsweise mit 2 multiplizieren:
2 × 4 Runde +/MAT
„Moderne“ Sprachkonzepte: Rekursion und Kontrollstrukturen
Eine Stärke von APL ist die Rekursion, der Aufruf einer Funktion innerhalb ihrer selbst. Dies war in der ursprünglichen Implementierung von APL bereits enthalten (im Gegensatz zu den meisten damaligen Programmiersprachen wie COBOL oder FORTRAN).
Beispiel (ohne Zeilennummern) unter Verwendung „moderner“ (in anderen APL-„Dialekten“ später eingefügte Kontrollstrukturen):
Z ← FAKULTÄT N ⍝ Da n! = n × (n-1)!, muss (am Anfang) die Rekursion ⍝ bei n=1 "gestoppt" werden (1! = 1) :If N <= 1 Z←1 :Else Z←N×FAKULTÄT N-1 :EndIf
Anm: Wegen der Verarbeitungsreihenfolge muss „n-1“ nicht in Klammern stehen (kann aber).
Mächtigkeit und Lesbarkeit
APL ist mächtig: Es gibt (abhängig von der Version) rund 70 primitive, das heißt im Interpreter verankerte (im Gegensatz zu selbst definierten) Funktionen. Diese werden durch etwa 50 Symbole dargestellt, von den rund 20 Symbole zwei verschiedene Funktionen repräsentieren in Abhängigkeit davon, ob sie mit einem oder zwei Argumenten aufgerufen werden.
Beispiel:
- In 8 ÷ 4 wird die Funktion „÷“ dyadisch als Division verwendet. Das Ergebnis ist 2.
- In ÷.25 wird die Funktion „÷“ monadisch verwendet; sie liefert den Kehrwert des rechten Arguments. Das Ergebnis ist 4.
Die meisten der in APL „eingebauten“ Funktionen wirken sowohl auf Skalare als auch auf Vektoren, Matrizen und Arrays. Wo in anderen Programmiersprachen Schleifen verwendet werden müssen, um eine Menge von Werten zu verarbeiten, genügt in der Regel bei APL der Einsatz einer primitiven Funktion. Darüber hinaus können viele dieser Funktionen mittels Operatoren erweitert werden.
Neben den primitiven Funktionen, die immer aus einem einzelnen Zeichen bestehen, gibt es eine große Anzahl von System-Funktionen und -Variablen. Datum und Uhrzeit sind z. B. in einer Systemvariablen ⎕TS (für TimeStamp) abfragbar. Systemvariablen gehören nicht zum „primitiven“ Sprachumfang, sondern sind abhängig von der Implementation. Auch Systemfunktionen sind teilweise implementationsabhängig. Sie stellen beispielsweise Schnittstellen zu anderen Programmiersprachen und zum Betriebssystem bereit.
Definierte Funktionen passen sich nahtlos in dieses Konzept ein. Sie können monadisch oder dyadisch sein und ohne spezielle Syntax mit den primitiven Funktionen zusammen in einem Statement verwendet werden. Es können sogar selbst programmierte Funktionen als Argumente eines Operators verwendet werden oder Operatoren selbst programmiert werden.
Da die primitiven Funktionen von APL nur aus einem einzigen Zeichen bestehen und diese Funktionen zudem sehr mächtig sind, kann keine andere Sprache mit vergleichbarer Kürze und Stringenz aufwarten. Wo in anderen Programmiersprachen viele Zeilen vonnöten sind, reicht bei APL häufig schon eine Anweisung mit einigen Symbolen aus.<ref>Als Beispiel möge ein Video auf YouTube dienen, in dem Schritt für Schritt zwei einzeilige APL Funktionen entwickelt werden: die erste Funktion berechnet die nächste Generation gemäß den Regeln für Conways Spiel des Lebens, die zweite Funktion stellt das Spiel dar: Conway’s Game Of Life in APL</ref>
Dies sind die berühmt-berüchtigten „one-liners“, an denen viele APL-Programmierer ihr „Denkzeug“ („APL as a tool of thought“) geschärft haben. Ken Iverson selbst hat einen one-liner geschaffen, der eine Liste der ersten N Primzahlen von 1 bis N incl. erstellt:<ref>One-liner Wars in APL</ref>
(2 = 0 +.= T o.| T) / T ← ιN
Es existieren noch extremere Beispiele. So gibt es eine APL-Lösung des n-Damen-Problems ebenfalls in einer (!) Zeile. Kritiker sprechen von APL gelegentlich als von einer „Write-once-read-never“-Sprache. Diesem Urteil liegt ein Missverständnis zugrunde: Wenn in einer Zeile APL soviel passiert wie in zwei Seiten C-Code, dann sollte man realistischerweise davon ausgehen, dass diese eine Zeile zum Verständnis etwa die gleiche Zeit benötigt wie die zwei Seiten C-Code.
APL hat sich besonders in Bereichen bewährt, in denen sich die Anforderungen konstant und schnell ändern: Versicherungen, Hedge-Fonds, Portfolio-Verwalter sowie Prototyping für neue Anwendungen.
Die verwendeten Symbole, die Kürze der Formulierung und die variable Manipulation abstrakter Objekte (die erwähnten Skalare, Vektoren, Matrizen und so weiter – sowohl in Zahlen- wie in Textform und sogar gemischt) machen APL zu einer Sprache für Mathematiker (wofür sie ja auch anfangs konzipiert war). Sie erfordert abstraktes Denken und räumliches Vorstellungsvermögen, ist dadurch aber auch einfach und sehr elegant.
Ausführungsgeschwindigkeit
Da APL interpretiert wird, kann es vergleichsweise langsam in der Ausführung sein. Dies macht sich besonders dann unangenehm bemerkbar, wenn ein APL-Programm sich um einzelne Datenteilchen kümmern muss, zum Beispiel in einem KeyPress-Event-Handler. Andererseits umfasst APL einen großen Vorrat hochspezialisierter Funktionen, die für die Verarbeitung großer Arrays optimiert sind. Werden diese Funktionen auf große Datenmengen angewendet, dann können APL-Programme wie auch andere Interpreter-Programme sehr schnell sein.
Als funktionale Sprache ist APL prinzipiell geeignet, Multiprozessormaschinen auszunutzen. In diesem Bereich gibt es derzeit die größten Weiterentwicklungen der am Markt erfolgreichen APL-Implementationen.
Entwicklung und aktuelle Situation
Bis etwa 1985 war IBM mit ihrem APL2-Interpreter auf PCs wie auf Mainframes der führende Anbieter. In den folgenden knapp 10 Jahren war APL sehr erfolgreich, wurde aber nicht nennenswert weiterentwickelt. Erst seit etwa 1992 haben kleinere Software-Unternehmen (APL2000, Dyalog APL, später auch MicroAPL) APL kontinuierlich weiterentwickelt. Mittlerweile haben diese Implementierungen IBMs APL2 in Sachen Leistungsfähigkeit deutlich hinter sich gelassen. Allerdings ist APL2 die einzige APL-Implementierung, die (auch) auf Mainframes läuft.
Die vielleicht derzeit beste Implementierung, Dyalog APL, wurde von Microsoft in den Kreis der anerkannten .NET-Sprachen aufgenommen. IBM APL2 ist dagegen erste Wahl in IBMs Websphere-Welt.
Besondere Bedeutung hat APL2 heute vor allem noch in der Banken-, Versicherungs- und der Tourismusbranche sowie in Forschung und Entwicklung.
Heute wird APL in kleinen Projekten von spezialisierten Software-Unternehmen eingesetzt sowie als Werkzeug von Fachleuten, die sich eher als Systemanalytiker oder Business-Analysten denn als Programmierer bezeichnen. Auch in den Fachabteilungen größerer Unternehmen, Forschungsinstituten und an Universitäten wird es noch immer erfolgreich genutzt.
„APL is alive and well“ und hat ein eigenes Wiki.<ref>APL wiki</ref>
2012 konnte das Computer History Museum mit der Erlaubnis von IBM den Assembler-Quelltext von APL in der 1969–1972 “XM6” Version für System/360 veröffentlichen.<ref>Len Shustek: The APL Programming Language Source Code (englisch) computerhistory.org. 10. Oktober 2012. Abgerufen am 15. Oktober 2013.</ref>
J und APL
In seinen späten Jahren hat der Hauptdesigner von APL, Ken Iverson, einen zweiten Versuch gewagt. Das Ergebnis ist die Programmiersprache J, die nichts mit Microsofts nicht mehr unterstützter Programmiersprache J# zu tun hat. Diese Sprache ähnelt in ihren Konzepten sehr stark APL, verwendet aber ausschließlich Zeichen des ASCII-Zeichensatzes. Dies wird von den Anhängern als gewaltiger Fortschritt angesehen, von Kritikern aber abgelehnt, da die Verständlichkeit vermindert und Selbsterklärung der Symbole nicht ausgenutzt werden.
Einzelnachweise
<references />
Literatur
- Bernard Legrand: Mastering Dyalog APL. 2009, ISBN 978-0-9564638-0-7.
- Kenneth E. Iverson: A Programming Language. Wiley, 1962, ISBN 0-471-43014-5.
- James A. Brown, Sandra Pakin, Raymnod P. Polivka: APL2 at a Glance. Prentice Hall, 1988, ISBN 0-13-038670-7.
- Hans Lochner: APL2-Handbuch. Springer Verlag, 1989, ISBN 978-3-540-50677-5.
- Wulf-Dieter Wagner: Software-Engineering mit APL2. Springer Verlag, 1992, ISBN 3-540-54406-2.
- Hanspeter Bieri und Felix Grimm: Datenstrukturen in APL2. Springer Verlag, 1992, ISBN 0-387-55747-4.
- Bernhard Legrand: Les APL étendus. Masson, Paris 1994.
Weblinks
Implementierungen
- Dyalog APL
- APL2000 (ehemals STSC, Manugistics)
- IBMs APL2
- MicroAPL
- J
- NARS2000 (Open Source)
- GNU APL (Open Souce und frei (GPL))
Periodika
Über APL
- APL Wiki
- APL-Germany e. V. – Deutsche Anwendervereinigung
- Über APL
- Conways Game of life in APL
- APL demonstration Professor Bob Spence, Imperial College London, 1975.
- The Origins of APL mit Ken Iverson und Adin Falkoff, 1974
Syntax
- APL2-Handbuch (PDF; 702 kB)