Mal ein Beispiel:
Code: Alles auswählen
def f(x, y):
erg = x+y
return erg
reduce(f, range(10))
Das ist ja nichts weiter als ein eigener Nachbau von operator.add, aber darum solls nicht gehen.
Der Interpreter sieht das ganze nun so, wie es ist. (bzw kompiliert, gebytekompiliert, weiß der Henker wie).
Er sieht es absolut.
Logisch gesehen ist aber folgendes zu erkennen:
Code: Alles auswählen
# Teil des Programmes.
# def: Ab hier ist es *kein* Teil des Programmes mehr
def f(x, y):
# Eine Subroutine, dh ein eigenes Programm, Bereich ist abgeschlossen.
erg = x + y
# Teil des Programmes
# Tätigkeit des *Interpreters* wird ausgelöst.
return erg
# Wieder Teil des eigentlichen Programmes
# Ausführung einer Tätigkeit
reduce(f, range(10))
Was ich damit ausdrücken will: Durch Verwendung von def wird quasi ein eigenes Unterprogramm geöffnet. Das ist aus Sicht des Interpreters natürlich eine Tätigkeit. Aber für das Programm praktisch irrelevant. Ist dem Programm ja egal, ob da nun direkt lambda: x+y oder operator.add oder was auch immer steht. Oder ob man den Code zwanzigmal wiederholen muss. Das Programm würde das gleiche machen. Es ist eine Vereinfachung (Zentralisierung) durch den Interpreter, aber für die einzelnen Abschnitte des Codes macht es (außer bei eventuellen Wiederholungen) keinen Unterschied. Würde man "def" als eine Funktion betrachten, würde die Dinge tun (nämlich Funktion verfügbar machen aus einem Unterprogramm), die eigentlich nur den Interpreter was angingen, im Großen und Ganzen für das Programm aber egal sein können (sofern man es verkraften könnte, zigmal zu copy & pasten). Eine Funktion als eine Tätigkeit *im Programm* Ist nur der Funktionskörper. *Wie* der Wert nun das eigentliche Programm erreicht, ist egal. Das macht *der Interpreter*, mittel des Return Statements.
Statements tun also bei der Betrachtung Dinge, die für den Interpreter (und den genervten Programmierer) wichtig sind, aber für die eigentlichen Funktionen des Programmes nicht relevant sind (da man den Programmcode ja auch als kompletten (aber sehr großen Block) ohne Statements schreiben könnte, zb so:)
Gleiches gilt hier für for, man könnte rein theoretisch auch ohne for arbeiten, indem man 10mal hinternander a+= i schreibt und zwischendrin i immer hochzählt. Das Ergebnis ist das gleiche, und so für das Programm irrelevant. Dagegen macht eben diese Codelogik an sich etwas aus, und ist auf die eine oder andere Art und Weise Teil des Programmes.
`if` und `for` sind in C *Funktionen*!? Wäre mir neu.
Öhm... Nein, aber ihr Aufruf sieht ähnlich aus, vergessen wir das lieber
Aber warum muss es den geben?
Weil Statements Dinge durch den Interpreter tun, aber nicht (wie Funktionen (nicht als Funktionen, aber als das Stück Programmcode, das xyz tut)) etwas für die Sprache. Es sind Zugriffe auf Features der Sprache, die aber für die reine Logik nicht existieren müssen. So meinte ich das auch mit den "Daten". Gut, heute möchte sicherlich keiner mehr Assembler schreiben, aber es würde rein theoretisch funktionieren. Die eigentliche Logik bleibt unberührt von Statements. Oder ohne Klassen arbeiten, geht heute noch recht gut. Trotzdem ist es per "class" möglich. Weil es ein Feature der Sprache ist, nicht aber, weil ein Objekt jetzt unbedingt nur Logik gehören müsste.
Es kommt zu "überflüssigem" wie dem ``a if c else b`` weil das in anderen Sprachen schon vom "normalen" `if` abgedeckt wird. Ausdrücke sind Konstrukte, die zu einem Ergebnis ausgewertet werden. Damit ist das Konstrukt per Definition ein Ausdruck. Es ist ja überhaupt nicht an Zuweisungen gebunden -- man kann es überall verwenden, wo ein Wert bzw. eben ein Ausdruck erwartet wird.
Achso, naja gut. Überflüssig habe ich übringens nur genutzt, um nicht andauerend die gleichen Wörter wiederholen zu müssen. Sowas mag ich selbst nicht gern lesen, drum wollt ichs euch ersparen.
Wieso sollte es keine Objekte geben, die "Interna" der Sprache repräsentieren? Und wieso muss man irgendwo aufhören?
Sollen nicht, klar kann man das machen. Oder man macht es anders. In Python hat man wenn man will Zugriff auf Internas. Auch lernt man mit der Zeit viele Dinge, die man eher nicht braucht oder die gut zu wissen sind, bzw schön für das Verständnis der Sprache (globals(), locals() (wobei ich das gerne in Komvination mit pdb nutze), type und dessen Verwendung zur Klassenerzeugung, ...), aber man muss nichts benutzen (oder sollte sogar nicht). Würde man das class Statement entfernen, und jeder müsste sich über type() seine Klassen erzeugen, wäre das unschön, aber möglich. Man muss nur wissen, wie Metaklassen genau funktionieren. Genauso wäre das doch mit Exceptions: Ich könnte raise verwenden *oder* eine Methode auf das Exception Objekt. Will ich aber nicht (wi wohl Io, wenn du es anmerkst, das ich bisher nicht kenne) jemanden zwanghaft mit Sprachinterna's "belästigen", kann ich auch einfach raise verwenden. Oder würdest du ernsthaft Klassen über type() erzeugen? (Wobei ich nicht bezweifle, das Methoden auf ein Exception Objekt auch eine Schöne Sache sein können)
Und in Python gibt's doch auch eine Menge (magische) Methoden, die in die Bedeutung von Statements eingreifen.
Richtig, ich könnte die aber theoretisch auch direkt aufrufen.
... man kann nur keine neue Syntax einführen.
Was auch gut so ist