Ich bemühte mich zu verstehen, worum es bei diesem Prinzip geht und warum es für das Sprachdesign so wichtig ist.
Grundsätzlich heißt es, dass für jeden Ausdruck expr
in der Sprache genau das Gleiche gelten sollte wie für dieses Konstrukt:
(function () { return expr; })()
Ich habe auch gehört, dass Ruby diesem Prinzip folgt, während Python dies nicht tut. Ich verstehe nicht, warum das stimmt oder ob es überhaupt stimmt.
design
language-agnostic
Andrew
quelle
quelle
expr
wird der aktuelle Stack-Trace abgerufen.Antworten:
Ich habe noch nie zuvor von "Tennents Korrespondenzprinzip" gehört, und noch weniger davon, dass es für das Sprachdesign wichtig ist. Das googeln der Ausdrücke scheint alles zu einem Neal Gafter-Blog von 2006 zu führen, in dem festgelegt ist, was er denkt, und wie er denkt, dass es auch für Schließungen gelten sollte. Und die meisten anderen in Foren scheinen sich auf Gafters Eintrag zu beziehen.
Hier ist jedoch eine Erwähnung des "TCP" von Douglas Crockford (ein Name, den ich kenne und dem ich vertraue): http://java.sys-con.com/node/793338/ . Teils
Daher scheint der Name "Tennent's Correspondence Principle" missbraucht zu werden, und was auch immer Neal spricht, sollte möglicherweise "Gafter's Imagined and Possibly Generalized TCP" heißen ... oder so. Auf jeden Fall nicht genug, um sich hinter einem vergriffenen Vorhang zu verstecken
quelle
Ich sehe dies als Teil einer allgemeinen Regel, dass eine gut gestaltete Sprache das tut, was ein Programmierer natürlich erwarten würde. Wenn ich einen Codeblock habe, den ich in einen Closure umgestalten möchte, und diesen Block mit der entsprechenden Syntax umhülle, ohne wirklich über die einzelnen Codezeilen nachzudenken, erwarte ich, dass dieser Block im Closure dasselbe tut wie er tat Inline. Wenn in einigen Anweisungen das Schlüsselwort "this" (möglicherweise implizit) verwendet wird und die Sprache "this" innerhalb des Abschlusses als Verweis auf eine anonyme Klasse zur Darstellung verwendet, und nicht auf die Klasse, die die Methode definiert, die den Abschluss definiert, dann auf die Bedeutung von Diese Anweisungen haben sich geändert, mein Codeblock entspricht nicht mehr meiner Meinung und ich muss einen Fehler aufspüren und herausfinden, wie ich meinen Code ändern kann, damit er im Closure funktioniert.
Das Problem könnte auch mit einer IDE mit intelligenten Refactoring-Tools behoben werden, die Abschlüsse extrahieren, potenzielle Probleme erkennen und den extrahierten Code sogar automatisch anpassen können, um die Probleme zu lösen.
quelle
Claus Reinke: zu Tennents "Sprachgestaltung nach semantischen Prinzipien"
Interessante Interpretation der Prinzipien:
"Korrespondenz ist das Prinzip, das man so sagen kann
und
sollten gleichwertig sein und alles, was wir in formalen Parameterlisten tun können, sollten wir auch in Deklarationen tun können und umgekehrt. "[siehe auch Reinke unten]
RD Tennent: Sprachentwurfsmethoden basierend auf semantischen Prinzipien
"Zwei Sprachentwurfsmethoden basierend auf Prinzipien, die aus dem denotationalen Ansatz der Programmiersprachensemantik abgeleitet sind, werden durch eine Anwendung auf die Sprache Pascal beschrieben und illustriert. Die Prinzipien sind zum einen die Korrespondenz zwischen parametrischen und deklarative Mechanismen und zweitens ein Abstraktionsprinzip für Programmiersprachen, das an die Mengenlehre angepasst ist. Mehrere nützliche Erweiterungen und Verallgemeinerungen von Pascal ergeben sich aus der Anwendung dieser Prinzipien, einschließlich einer Lösung für das Array-Parameter-Problem und einer Modularisierungsmöglichkeit. "
Claus Reinke: "Über funktionale Programmierung, Sprachgestaltung und Beharrlichkeit" bei Haskell
quelle
Um die Frage zu beantworten, warum Tennents CP für das Sprachdesign so wichtig ist, möchte ich Neal Gafter zitieren :
Jeder Verstoß gegen TCP wird in Zukunft wahrscheinlich einige Programmierer verletzen, wenn er davon ausgeht, dass Closures wie Nicht-Closure-Code funktionieren, dies jedoch bei einem Verstoß gegen TCP nicht der Fall ist.
quelle
RE Python folgt diesem Prinzip nicht. Im Allgemeinen folgt es dem Prinzip. Einfaches Beispiel:
Python definiert jedoch Ausdrücke und Anweisungen separat. Da
if
Verzweigungen,while
Schleifen, destruktive Zuweisungen und andere Anweisungen inlambda
Ausdrücken überhaupt nicht verwendet werden können , gilt der Buchstabe des Tennent-Prinzips nicht für sie. Selbst wenn Sie sich darauf beschränken, nur Python-Ausdrücke zu verwenden, erhalten Sie immer noch ein Turing-Gesamtsystem. Ich sehe das also nicht als Verstoß gegen das Prinzip; oder vielmehr, wenn es gegen das Prinzip verstößt, kann möglicherweise keine Sprache, die Aussagen und Ausdrücke separat definiert, dem Prinzip entsprechen.Auch wenn der Körper des
lambda
Ausdrucks eine Stapelverfolgung aufzeichnet oder eine andere Introspektion in der VM durchführt, kann dies zu Unterschieden führen. Meiner Meinung nach sollte dies jedoch nicht als Verstoß gewertet werden. Wennexpr
und(lambda: expr)()
notwendigerweise zu demselben Bytecode kompiliert wird, dann betrifft das Prinzip wirklich Compiler, nicht Semantik; Wenn sie sich jedoch zu einem anderen Bytecode kompilieren lassen, sollten wir nicht erwarten, dass der VM-Status in jedem Fall identisch ist.Eine Überraschung ist bei der Verwendung der Verständnissyntax zu erwarten, auch wenn dies meiner Meinung nach keine Verletzung des Tennent-Prinzips darstellt. Beispiel:
Die Überraschung ist das Ergebnis der Definition des Listenverständnisses. Das obige "Überraschungs" -Verständnis entspricht diesem Code:
So gesehen ist das obige "Überraschungs" -Verständnis weniger überraschend und keine Verletzung des Tennent-Prinzips.
quelle