Allergiehinweis: Es folgen neun Zeilen Code in Python:
def f(n): def fp(f, t): if f == t: return f else: d = ((t - f) >> 1) + f return fp(f, d) * fp(d + 1, t) return fp(1, n) print(f(100))
Ich hatte vor einigen Tagen viel Spaß mit ein paar Menschen, die beim Anblick dieses kleinen Python-Quelltextes auch nach längerem Nachdenken nicht erraten konnten, was zum hackenden Henker hier überhaupt berechnet wird. Dabei ist das gar nicht mal so schlimm ausgedrückt, wenn man einmal davon absieht, dass sich die Funktionsnamen f
und fp
genau so wenig selbst erklären wie die Variablennamen f
, t
und d
und damit jeden hilfreichen semantischen Kontext zerstören. Es ist darüber hinaus in einer Weise ausgedrückt, die hoffentlich jeder Mensch vermeiden würde, wenn man es nicht wirklich so machen muss (um zum Beispiel die Rekursionstiefe gering zu halten, die gegenüber direkter rekursiver Formulierung von O(n) auf O(log n) schrumpt, weil der Aufrufstack in Python nun einmal wegen einer für uns Normalsterbliche unverständlichen Weisheit der Sprachdesigner auf 1000 begrenzt ist). Ich hoffe, die haben jetzt wenigstens verstanden, dass »lesbarere« Programmiersprachen nur dann zu lesbarerem Code führen, wenn sich darin auch lesbare Gedanken ausdrücken. Und das gilt weit über Programmiersprachen hinaus in der gesamten menschlichen Kommunikation, ja, auch in der politischen Kommunikation: Je unmittelbarer der Ausdruck und je klarer der Gedanke ist, desto besser und schneller kann er von anderen aufgefasst werden.
(Wer sich denkt: »Bei einem Sortieralgorithmus hätte ich die Vorgehensweise ja verstanden, aber doch nicht bei einem Produkt, da ist das ja nur sinnlos und verwirrend«, hat vermutlich schon verstanden, was hier berechnet wird.)
Auch Code ist Kommunikation. Es ist so gut wie sicher, dass irgendwann einmal ein anderer Programmierer in den Code schauen wird, wenn es um eine nichttriviale Anwendung geht. Sei es, um einen lästigen Fehler zu beseitigen, sei es, um eine vermisste Funktionalität zu verbauen. Oder dass man selbst hineinschauen wird. Nach meiner Erfahrung ist eigener Code nach nur einem Jahr genau so unverständlich wie fremder Code. Bei postmodernen Programmiersprachen wie Perl oder in Shellskripten kann der Code schon nach einem Monat fremd und unverständlich aussehen. Meine Festplatte ist voll mit Beispielen aus meinem eigenen Leben. Wer sich auch mal gruseln möchte: Hier ist ein schönes Beispiel in Lua, das Zahlenreihen ganzer Zahlen fortzusetzen versucht, was zumindest früher eine recht häufige Aufgabe in so genannten Intelligenztests¹ war. Es funktioniert nur mit polynominell definierten Reihen, nicht mit exponentiellen oder über Sprache oder Zifferndarstellungen defnierten Reihen, ist in der Praxis also keine Alternative zur OEIS. Warum Lua? Weil die paar Leute, denen ich damit in eine Diskussion gekommen bin, um ihnen hoffentlich ein bisschen das Zweifeln am so genannten Intelligenzquotienten zu lehren, schon Lua konnten.
(Keiner weiß, was Intelligenz ist, aber alles spricht von »Künstlicher Intelligenz«, besonders Ahnungslose sprechen sogar vom »Bewusstsein« einer solchen »Künstlichen Intelligenz«. Aber lassen wir das.)
Ein Einwand war, dass man das mit den Sprachmitteln von Python – ich habe in meinem vorsätzlich schlechten Code allerdings auch nichts anderes als nur die Sprachmittel von Python verwendet und könnte mir wegen des beschränkten Aufrufstacks sogar eine faule Ausrede aus den Fingern saugen, warum ich das so binärbaummäßig ausgeästelt habe – doch direkter und kürzer ausdrücken könnte. Meine Antwort sah so aus:
import functools f = lambda n: functools.reduce(range(1, n + 1), lambda l, r: l * r) print(f(100))
Kurz und direkt, quasi ein Einzeiler, wenn man den import
eines Moduls der Standardbibliothek mal als eine unvermeidliche Formalie betrachtet: Etwas lästig, aber dafür hat man einen recht sauberen globalen Namensraum. Und es ist so elegant (auch so ein komischer Anspruch), dass Freunde funktionaler Programmiersprachen (das bin ich selbst aus ziemlich zufälligen Gründen nur eingeschränkt) sofort vergnügt zu hüpfen beginnen möchten. Schönstes und reinstes Python, viel gelobt für seine Lesbarkeit. Rekursion gibt es auch nicht mehr. Das ist also viel nachvollziehbarer, weil man nicht erst Rekursion verstanden haben muss, um Rekursion zu verstehen. Gut, dafür kann man es nicht mehr ganz so leicht in jeder beliebigen anderen Programmiersprache (COBOL zähle ich mal nicht mit) ausdrücken wie mein Eingangsbeispiel. Aber dafür ist das sogar allgemeiner, weil es nicht einfach voraussetzt, dass die Multiplikation kommutativ ist. Zufrieden? Ach, so richtig lesbar ist das immer noch nicht, und wie es denn zur Abwechslung mal mit einer ganz normalen Schleife wäre? 😁️
Nun ja, meine lieben Mitmenschen haben sich in den nächsten Stunden lieber mit der dummen Idee beschäftigt, Whitespace mit syntaktischer Bedeutung aufzuladen, wie es Python tut.
Vermutlich habe ich mich nicht unmittelbar und klar genug ausgedrückt.
Oder ist derailing inzwischen völlig normal geworden?
¹Eine recht fragwürdige Methode übrigens. Es gibt unendlich viele Möglichkeiten für das Bildungsgesetz einer Zahlenreihe, von der nur endlich viele Glieder vorliegen.