Opal (Programmiersprache)
OPAL (Optimized Applicative Language) ist eine funktionale Programmiersprache, die 1986 an der TU Berlin unter der Leitung von Peter Pepper entwickelt wurde. Die Sprache diente dort vor allem als Testumgebung. Anfangs ging es zunächst darum, die Sprache effizient zu implementieren. Später wurde das komplette Feld funktionaler Konzepte mit einbezogen. Dazu gehören insbesondere:
- Prinzipien des Software-Engineering
- Integration formaler Spezifikation
- parallele Programmierung
Im Gegensatz zu anderen funktionalen Sprachen wie Haskell ist OPAL nicht standardisiert. Das erlaubt den Entwicklern, viel mit diversen Merkmalen, die sie für interessant erachten, zu experimentieren.
Der grobe Aufbau eines OPAL-Programms
[Bearbeiten | Quelltext bearbeiten ]OPAL-Programme (Strukturen, siehe auch Algebraische Struktur) bestehen aus einem Signaturteil (Dateiendung .sign
) und einem Implementationsteil (Dateiendung .impl
). Im Signaturteil werden die Sorten sowie die Definitions- und Wertebereiche aller Funktionen beschrieben. Hierzu wird das Schlüsselwort FUN
gebraucht:
FUNf:nat**nat->nat
deklariert beispielsweise eine Funktion f, deren Definitionsbereich ein Tupel aus zwei Werten vom Typ nat
(für natürliche Zahlen) und deren Wertebereich ebenfalls die Sorte nat
darstellt. Das Schlüsselwort FUN
darf auch im Implementationsteil stehen, solche Funktionen können dann aber nur in der jeweiligen Struktur verwendet werden.
Im Quellcode werden die Funktionen mit dem Schlüsselwort DEF
implementiert (siehe Beispiele). Ebenfalls in der Implementation wird mit dem Wort DATA
ein selbstdefinierter Datentyp beschrieben, dessen Signatur in der .sign
-Datei mittels TYPE
auch global bekanntgegeben werden kann.
Beispiele
[Bearbeiten | Quelltext bearbeiten ]Fibonacci
[Bearbeiten | Quelltext bearbeiten ]Ein Beispiel für eine Implementierung der Fibonaccifunktion unter Verwendung einer Lambda-Abstraktion:
DEFfibo==\\n. IFn=0THEN0 IFn=1THEN1 IFn>=2THENfibo(n-1)+fibo(n-2)FI
Eine effizientere Implementierung der obigen Folge unter Verwendung von Dijkstra-IF sowie Overloading.
FUNfib:nat->nat DEFfib(x)== IFx=0THEN0 IFx=1THEN1 IFx>1THENfib(2,1,1,x) FI FUNfib:nat**nat**nat**nat->nat --idx:momentanerIndex --p1:fib(idx) --p2:fib(idx-1) --max:derIndexdeszuberechnendenFolgengliedes --Beispiel:fib(6)->fib(2,1,1,6)->fib(3,2,1,6)->fib(4,3,2,6)-> --fib(5,5,3,6)->fib(6,8,5,6)=>8 DEFfib(idx,p1,p2,max)== IFidx<maxTHENfib(idx+1,p1+p2,p1,max) IFidx=maxTHENp1 FI
Quicksort
[Bearbeiten | Quelltext bearbeiten ]Ein Beispiel für eine Implementierung des Quicksortalgorithmus:
FUNsort:seq[nat]->seq[nat] DEFsort(<>)==<> --DieleereSequenz(geschriebenals<>)istbereitssortiert DEFsort(a::R)== LET Small==(_<a)|R --SeiSmalldieSequenzR,gefiltertmitderFunktion"< a".SmallbestehtdamitausallenElementeninR,diekleinersindalsa --SmallentstehtausderApplikationderFunktion"|"(Filter)aufdieArgumente"(_ < a)",einerFunktionnat->bool,undderSequenz"R" --OpalerlaubtdiePrefix-,Infix-undPostfix-Notation,sowiedieVergabevonIdentifikatorenausSonderzeichen. --Dero.a.Ausdruckistidentischzu"| ( _ < a, R)" Medium==a::(_=a)|R --MediumenthältdasersteElementaundalleElementeinR,diegleichasind Large==(_>a)|R --LargeistdanndieSequenz,diealleZahlenausRenthält,diegrößeralsasind IN sort(Small)++Medium++sort(Large) --DasResultatistdieKonkatenationderihrerseitssortiertenSequenzSmall,MediumunddersortiertenSequenzLarge.
Selectionsort
[Bearbeiten | Quelltext bearbeiten ]Ein Beispiel für eine Implementierung des Selectionsortalgorithmus:
FUNssort:seq[nat]->seq[nat] DEFssort(<>)==<> DEFssort(liste)== LET minimum==min(liste) restliste==cut(minimum,liste) IN minimum::ssort(restliste) FUNcut:nat**seq[nat]->seq[nat] DEFcut(x,a::A)== IFa=xTHENA ELSEa::cut(x,A)FI FUNmin:seq[nat]->nat DEFmin(a::A)==minHelp(a,A) FUNminHelp:nat**seq[nat]->nat DEFminHelp(a,<>)==a DEFminHelp(a,A)== IFa<ft(A)THENminHelp(a,rt(A)) ELSEminHelp(ft(A),rt(A))FI
Insertionsort
[Bearbeiten | Quelltext bearbeiten ]Ein Beispiel für eine Implementierung des Insertionsortalgorithmus:
FUNisort:seq[nat]->seq[nat] DEFisort(<>)==<> DEFisort(a::A)==ainsertisort(A) FUNinsert:nat**seq[nat]->seq[nat] DEFxinsert<>==x::<> DEFxinsert(a::A)== IFx<=aTHENx::(a::A) ELSEa::(xinsertA) FI
Mergesort
[Bearbeiten | Quelltext bearbeiten ]Ein Beispiel für eine Implementierung des Mergesortalgorithmus:
FUNmsort:seq[nat]->seq[nat] DEFmsort(<>)==<> DEFmsort(a::<>)==a::<> DEFmsort(liste)== LET i==#(liste)/2 (links,rechts)==split(i,liste) IN msort(links)mergemsort(rechts) FUNmerge:seq[nat]**seq[nat]->seq[nat] DEF<>merge<>==<> DEFamerge<>==a DEF<>mergea==a DEF(a::A)merge(b::B)== IFa<=bTHENa::(Amerge(b::B)) ELSEb::(Bmerge(a::A)) FI
Beispiele für Datentypen
[Bearbeiten | Quelltext bearbeiten ]Während in der Theorie zwischen verschiedenen Formen von Datentypen unterschieden wird, hat OPAL nur ein Konstrukt, um eigene Typen zu definieren.
Ein Beispiel für eine Implementierung eines Produkttyps
DATApoint3D==point3D(x:real,y:real,z:real)
... eines Summentyps
DATAobject3D==cube(width:real,height:real,length:real,location:point3D) cylinder(height:real,radius:real,location:point3D) sphere(radius:real,location:point3D)
... eines Aufzählungstyps
DATAtraffic_light==red yellow green
Datentypdeklarationen (TYPE) ersetzt der OPAL-Compiler intern durch die sogenannte „induzierte Signatur". Das Schlüsselwort DATA
fügt auch Implementierungen der Funktionen hinzu, die dem Programmierer dann die Möglichkeit geben, Werte der selbstdefinierten Sorte zu erzeugen, auf die einzelnen Elemente der Datenstruktur zuzugreifen und zwischen Varianten zu unterscheiden:
Z. B. die induzierte Signatur für den Summentyp
--Sorte SORTobject3D --Konstruktorfunktionen FUNcube:real**real**real**point3D->object3D FUNcylinder:real**real**point3D->object3D FUNsphere:real**point3D->object3D --Selektorfunktionen FUNwidthheightlengthradius:object3D->real FUNlocation:object3D->point3D --Diskriminatorfunktionen FUNcube?:object3D->bool FUNcylinder?:object3D->bool FUNsphere?:object3D->bool
Literatur
[Bearbeiten | Quelltext bearbeiten ]- Peter Pepper: Funktionale Programmierung in OPAL, ML, HASKELL und GOFER. Springer-Verlag, 1999, ISBN 3-540-64541-1
Weblinks
[Bearbeiten | Quelltext bearbeiten ]- Webseite des OPAL-Projektes @1 @2 Vorlage:Toter Link/projects.uebb.tu-berlin.de (Seite nicht mehr abrufbar, festgestellt im April 2021. Suche in Webarchiven)
- Bibliotheca Opalica Dokumentation der OPAL-API@1 @2 Vorlage:Toter Link/projects.uebb.tu-berlin.de (Seite nicht mehr abrufbar, festgestellt im April 2021. Suche in Webarchiven)
- Quelltextarchiv des OPAL-Projekts auf dem GitHub der TU Berlin
- Übersicht OPAL im Wiki von Freitagsrunde.org – Dort findet sich u. a. die Opalix Live-CD
- Opal-Programme online schreiben und ausführen @1 @2 Vorlage:Toter Link/opal.gehaxelt.in (Seite nicht mehr abrufbar, festgestellt im April 2021. Suche in Webarchiven)