[Python-de] "Funktionalitaet" von Python

Rainer Fischbach fischbach at ecs-gmbh.de
Tue Sep 3 01:28:30 EDT 2002


>Dinu Gherman schrieb:
>
>Funktionale Sprachen sind halt Ausdruck von Mathematikern, die ihre Pro-
>pleme moeglichst mathematisch zu formulieren versuchen, was voellig 
>opportun ist - nur: bekanntlich ist nicht jedes Problem in einer ge-
>schlossenen mathematischen Formel darstellbar oder auch nur entscheid-
>bar!

letzteres ist unbestreitbar wahr, doch trägt es nichts zur Frage
funktional vs. imperativ bei. Wenn etwas nicht durch eine Formel
darstellbar oder entscheidbar ist, dann gibt es auch kein kein 
sequentielles, imperatives Programm, das dies könnte! 
Jedem solchen Programm lässt sich nämlich eine berechenbare 
Funktion zuordnen, die z. B. im Lambda-Kalkül darstellbar ist. 
Das folgt aus der These von Church und ist schließlich die 
Grundlage der denotationellen Semantik von imperativen Sprachen.

Ob man sich Programme lieber als Folge von Anweisungen vorstellt 
oder als komplexe Ausdrücke hängt auch von persönlichen Prägungen ab. 
Zeitliche und räumliche Ordnung sind Grundformen und Vermögen der 
Wahrnehmung (Kant hat das in der transzendentalen Ästhetik ausgearbeitet) 
die, wie die moderne Neurologie herausgefunden hat, auch mit der Lateralität 
des Gehirns zusammenhängen. Bei den einen ist halt die eine Seite stärker 
ausgeprägt als die andere und umgekehrt. Deshalb sollte man auch nicht 
sagen, dass die eine oder andere Form an sich besser verständlich wäre. 

Sicher gibt es viele Fälle, wo die sequentielle, imperative Lösung 
recht sinnfällig, und auch solche, wo sie kaum zu vermeiden ist - 
etwa bei hardwarenahen, und/oder zeitabhängigen Aufgaben. 
Dinus Staubsauger zeigt das recht schön. Oft ist sie auch
die effizientere gegenüber der funktionalen. Trotzdem scheint mir 
in der spontanen Ablehnung applikativer Programme auch ein wenig
unhinterfragtes Vorurteil am Werk zu sein. Wer will etwa im Ernst 
behaupten, dass diese Folge von Anweisungen

z = x
z += a
z2 = y
z2 -= b
z *= z2

etwa verständlicher sei als 

z = (x + a) * (y - b)

???

Die Anhänger der reinen imperativenm Lehre müssten das jedoch tun,
wenn sie konsequent wären. Wahre Python-Adepten haben doch sicher 
auch kein Problem mit 

cstr = inter.join (strlst)

Wenn man die Liebe zum imperativ-sequentiellenm Stil durchhält,
müsste man jedoch das hier besser finden:

if strlst:
	cstr = strlst[0]
	for str in strlst[1:]
		cstr = cstr + inter + str
else:
	cstr = ''

Das ist nicht nur ziemlich schwer zu verstehen sondern auch tierisch
ineffizient, vor allem weil es eine quadratische Speicherkomplexität
hat (proportional zu len (strlsr)^2). 'join' ist so optimiert, dass 
es nicht diese riesigen Mengen von Speichermüll erzeugt wie die 
wiederholte Anweisung 'cstr = cstr + inter + str'.

Der funktionale Stil bietet eben oft den stärkeren Hebel, d. h.
die konziseren, eleganteren und ohne Zweifel auch besser
verständlichen Formulierungen von Programmen. Im Falle von
algebraischen Ausdrücken für Zahlen bestreitet das kaum jemand, 
weil fast alle in der Schule gelernt haben, mit der Algebra der 
diversen Zahlen und ihrer elementaren Operationen umzugehen. 
Die Hürde liegt für viele darin, dass sie das Gleiche nicht
für komplexere, in der Regel rekursiv definierte Operationen
(natürlich sind auch die elementaren rekursiv definiert,
aber das bleibt meist verborgen)
oder gar für Gebilde wie für Strings, Listen, Bäume etc. 
gelernt haben - alles Dinge, die eben auch ihre Algebren 
haben und deshalb einer vergleichbaren Darstellung fähig 
sind, die, wenn man sich an sie gewöhnt hat, 
eine gewisse intellektuelle Ökonomie bietet.


>Thilo Ernst schrieb (auf Dinu Gherman)
>> Zu den "wirklichen" Vorteilen funktionaler Sprachen zaehle ich weniger
>> solche Features,
>
>Naja, dass sich echte Closures, persistent speicherbar wie alle anderen
Objekte,
>gerade im Kontext von Webapplikationen _sehr_ gut machen, glaube ich Paul
G.
>unbesehen (The Other Road Ahead).  Das muss '97 echt ein unfairer
Wettbewerbs-
>vorteil  für seine Firma gewesen sein :-)
>
>> als zwei unmittelbare Konsequenzen des Fehlens von Sei-
>> teneffekten: 1. eine viel einfachere Modularisierbarkeit und 2. eine
>> viel einfachere parallele Ausfuehrung. Beides bekommt man offenbar ge-
>> schenkt, wenn man den Gurus glauben darf auch mit schnellen Compilern.
>
>Bezüglich feingranularer Parallelität hat  zwar das funktionale Dogma wohl
den
>genannten Vorteil, aber a) wer braucht die wirklich und b) wer mag dafür
schon
>immer 100% seiteneffektfrei programmieren (müssen)?
>
>Das Modularisierbarkeitsargument kaufe ich nicht. Jede lumpige imperative
>Hochsprache bietet volle Kontrolle darüber, was über Modulgrenzen
>hinweg passiert, ohne dass Compiler/Interpreter damit ein Riesenproblem
>hätten. (OK, fast jede.)
>

Dazu könnte man eine typische Frage an Radio Eriwan formulieren: 
Die Antwort heißt natürlich 'im Prinzip ja'. De facto ist das in
imperativen Programmen extrem schwierig, wenn nicht praktisch unmöglich,
weil solche Programme eben oft mit nicht-lokalen Seiteneffekten
arbeiten, die manchmal alles andere als leicht zu durchschauen sind. 
'Ein Riesenproblem' haben damit nicht die Compiler sondern die
Leute, die solche Programme entwickeln bzw. warten. Modul- oder
Klassenkonstrukte helfen dabei nicht allzu viel;  vor allem nicht,
wenn man nicht extrem diszipliniert damit umgeht.

Dinus Bemerkungen zur Modularisierbarkeit und Parallelisierbarkeit find
ich völlig richig. Ich würde nur noch hinzufügen, dass sich eine
bessere Modularisierbarkeit nicht nur aus der Seiteneffektfreiheit
sondern auch aus anderen Merkmalen des funktionalen Stils, z. B. dem
Einsatz von high-order functions ergibt. Dadurch sind Zerlegungen
möglich, die imperativ selbst unter Einsatz von oo-Sprachen nur 
mittels sehr umständlicher Workarounds imitierbar sind.

Sicher braucht man für die meisten Anwendungen heute keine 
Parallelisierbarkeit. Das ist bei typischen Desktop-Anwendungen so.
Soch wenn man sich vorstellt, dass viele Anwendungsprogramme
irgendwann auf massiv parallelen Superservern laufen, dann sieht 
das schon wieder anders aus. Dann wäre sie zumindest höchst vorteilhaft
und erwünscht. Die Leute, die vor Jahrzehnten Numeriksoftware in
FORTRAN schrieben, dachten auch nicht daran, dass der sequentielle,
imperative Ansatz einmal Schwierigkeiten bereiten könnte. Heute
leidet darunter die Effizienz von paralleler Hardware in 
berechnungsintensiven Programmen, die z. T. immer noch auf 
alte FORTRAN-Codes angewiesen sind.


>>
>> > Die Artikel von Paul Graham (www.paulgraham.com) belegen recht anschau-
>> > lich diese durch den Siegeszug der imperativen dynamischen Sprachen
aus-
>> > gelöste Sinnkrise in der Lisp-Community. Lisp wird dort z.B durch
folgen-
>> > de Argumentation "gerettet": Höheres Abstraktionsniveau erlaubt kompak-
>> > teren Code (maximalen semantischen Gehalt pro Codezeile), und Code-Kom-
>> > paktheit muss immer das übergeordnete Optimierungsziel sein. Man darf
>> > folglich in einer modernen Sprache auf kein einziges leistungsfähiges
>> > Abstraktionsmittel (wir z.B. Lisp-Makros) verzichten. (Probleme wie die
>> > Lesbarkeit und Wartbarkeit solcher "maximal-kompakten" Programme werden
>> > allerdings nicht näher betrachtet :-)
>>

Man muss sich klarmachen, dass Leute funktionale Sprachen aus
durchaus unterschiedlichen Motiven bevorzugen: 

Da ist einerseits einerseits die Fraktion, auf deren Fahne 'power' 
steht. Für sie sind vor allem Dynamik und Reflexion entscheidend.
Dass sie eine funktionale Sprache wie Lisp bevorzugt, liegt nicht
allein daran, dass funktionale Idiome eine hohe semantische Dichte
des Codes ermöglichen, sondern dass Lisp historisch zufällig die
Sprache war, die Dynamik und Reflexion auf hohem Abstraktionsniveau
(ich sehe hier von selbstmodifizierendem Assembler-Code bewusst ab) 
zuerst unterstützte. Viele Lisp-Codes sind keinesfalls 
rein applikativ sondern benutzen auch Seiteneffekte.  
Diese Fraktion wird umso weniger Schwierigkeiten haben, einmal Python 
einzusetzen (wofür es gute pragmatische Gründe gibt, denen sie sich
nicht unbedingt verschließt) je mehr und je schneller Python ihnen 
das, was sie will und braucht, in einer konsistenten und eleganten 
Weise zur Verfügung stellt. Die paar Features, die Python diesbezüglich hat, 
sind nett aber unbefriedigend und sicher ausbaufähig. Die Python-Community 
kann durch den Zustrom aus diesem Lager, dessen Bewohner typischerweise
in ihrem Leben schon mehr als ein paar dynamische Webseiten gemacht haben,
nur gewinnen.

Die andere Fraktion teilt mit der vorigen sicher auch die Vorliebe
für semantisch dichten Code, doch geht es ihr um andere Ziele:
Auf ihrer Fahne steht 'Korrektheit' und für sie hat die Freiheit
von Seiteneffekten tatsächlich einen sehr hohen Stellenwert neben
Dingen wie formaler Semantik, ausgeklügelten, statischen Typsystemen, 
automatischer Typableitung, Theorembeweisern, etc. Diese Fraktion
wird sicher nicht von Haskell oder ML lassen und Python nach ihrem
Geschmack umzubauen wäre schon wegen der divergierenden Prinzipien
kein sinnvolles Ziel. Aber man kann bei ihr wohlgestaltete 
Features klauen. Sie hat es nämlich verstanden, den funktionalen
Stil von der kryptischen Lisp-Tradition zu befreien. Z. B. die 
Offside rule, Comprehensions und sequence unpacking 
kommen aus dieser Ecke, wo man schließlich auch die Syntax 
generell an den Mainstream angenähert hat (no more lots of
insidiously silly parantheses). Schade nur, dass 
nicht konsequent geklaut wurde, weil in Haskell Comprehensions 
viel konziser sind und sequence unpacking viel eleganter 
und mächtiger ist.

Ich glaube, dass es in Zukunft immer mehr 'multi-paradigmatische'
Software geben wird, die Komponenten in unterschiedlichen Stilen
umfasst. Der Stil sollte eine Frage der Angemessenheit an die Aufgabe
und der Fähigkeiten/Neigungen der Programmierer sein. Es führt 
auch kein Weg daran vorbei, dass viele Aufgaben die in der
Lisp-Gemeinde kultivierten mehrschichtigen Ansätze 
(Zwischensprachen, dynamische Code-Generierung, etc.) 
erfordern. 

Ich kann mir Python als Basis dafür vorstellen: ein vernünftiger 
imperativer Kern mit sehr vielen (inhaltlich) lispigen Erweiterungen 
in Haskell-artiger eleganter Verpackung. Es ist ja schon eine 
Menge da und das abzurunden sollte eigentlich nicht an
ideologischen Vorbehalten scheitern. Das soll nicht heißen, 
dass Python alles Erdenkliche aufnehmen soll, sondern das,
was nötig ist, um an vielen Stellen Lisp ersetzen zu können,
ohne allzu viele schlechte Kompromisse zu erzwingen. 
Als Sprache für jedermanns/jederfrau Website ist PHP ohnehin 
kaum zu schlagen.

sl, Rainer


--
i. V. Rainer Fischbach

Senior Consultant
ECS Engineering Consulting & Solutions GmbH
Mühlstraße 3, D-92318 Neumarkt
Fon +49 (0) 9181 4764-84
Fax +49 (0) 9181 4764-50
Mobil +49 (0) 171 4141570
E-Mail: fischbach at ecs-gmbh.de
http://www.ecs-gmbh.de
--





More information about the Python-de mailing list