[linux-l] Ocml vs. Java

olafBuddenhagen at gmx.net olafBuddenhagen at gmx.net
Di Sep 27 07:19:17 CEST 2005


Hallo,

> Mag sein, aber dort gibt's Listcomprehensions, da sind sie von den
> Dogmen etwas abgegangen zugunsten von "Usability".

Ich nehme diese Äußerung jetzt mal exemplarisch als Aufhänger, um etwas
aufzuzeigen, was ich schon seit Tagen beim lesen diese Threads im Kopf
habe: Ihr redet IMHO allesamt ziemlich am Punkt vorbei.

Ob man nun etwas schreibt als

   list=[a+b for a,b in zip(liste1,liste2)]

oder

   list=array_map(function('a,b', 'return a+b;'), list1, list2);

oder

   for(i=0; i < sizeof list/sizeof list[0]; ++i) list[i]=list1[i]+list2[i];

oder was auch immer, ist doch wirklich nur ein syntaktisches Detail, und
mehr Geschmacksfrage als alles andere. (Die eine rein funktionale
allgemeine Prgrammiersprache, die ich mir mal ansatzweise reingezogen
habe, hatte sogar extrem ausgebaute Listcomprehensions -- erinnert sehr
an SQL...)

Die wesentliche Eigenschaft von funktionalen Sprachen ist, dass es
keinerlei Side Effects gibt. Es werden nur funktionale Abhängigkeiten
zwischen den Eingangswerten und dem Ergebnis festgelegt; die
Abarbeitungsreihenfolge und Repräsentation von Zwischenergebnissen ist
dagegen allein Sache des Compilers.

Zum einen hat der Compiler damit natürlich viel mehr Raum beim
Optimieren. Da im Gegensatz zu imperativen Programmiersprachen keinerlei
Vorgaben gemacht werden, kann der Compiler völlig frei entscheiden,
welche Reihenfolge der Rechenoperationen und Organization der Daten im
Speicher am effizientesten ist. (Wie gut das tatsächlich funktioniert,
weiß ich nicht. Gut optimierter und an die Hardware angepasster Code in
einer hardwarenahen Programmiersprache dürfte schwer zu übertreffen sein
-- aber solcher ist in der Praxis sehr selten...) Gerade mit zunehmender
Parallelität der Hardware, wird das immer wichtiger: So muss sich der
Compiler beim Anordnen der Befehle nur um tatsächliche logischen
Abhängigkeiten im Rechenweg kümmern, nicht um künstlich vom
Programmierer geschaffene -- was sehr weitreichende Möglichkeiten bietet
beim Umordnen von Rechenschritten, Verschachteln von Code,
auto-Vektorisierung, und automatischem Threading. Itanium freut sich ;-)

Andererseits heißt das natürlich, dass der Programmierer sich das
Festlegen der Befehlsreihenfolge und Datenorganisation spart. In dem
Sinne ist funktionale Programmierung tatsächlich "high level",
verglichen mit imperativen Sprachen (zu denen nach meinem Verständnis
auch die sogenannten "objektorientierten" Sprachen gehören). Allerdings
erfordert es auch ein wesentlich abstrakteres Denken, was nicht
Jedermanns Sache ist.

Das Problem mit rein funktionalen Sprachen ist, dass das Konzept sehr
schnell an Grenzen stößt, wenn das Problem über simples Batch-Processing
hinausgeht. Vor allem fehlt dem Compiler das Verständnis über zeitliche
Abläufe, welches einem imperativen Programm ganz automatisch mitgegeben
wird, selbst wenn der Programmierer sich garnicht bewußt Gedanken über
Optimierung macht. Hier wird also das Fehlen von Vorgaben bei der
Abarbeitungsreihenfolge zum Problem.

Es gibt zwei Möglichkeiten hier Abhilfe zu Schaffen: Einerseits gibt es
rein funktionale Sprachen, die für sich in Anspruch nehmen, dieser
Probleme irgendwie Herr zu werden. Habe allerdings keine Ahnung auf
welche Weise, und mit welchem Erfolg.

Andererseits kann man sich vom rein funktionalen Ansatz lösen, und
optional auch imperative Elemente anbieten. So erhält man ziemlich
universelle Sprachen. Lisp ist hier der Klassiker -- allerdings mit
gewissen Eigenschaften, die eher streitbar sind. OCaml scheint als
moderner Vertreter dieses Ansatzes nicht uninteressant zu sein...

-Olaf-



Mehr Informationen über die Mailingliste linux-l