Warum unterscheiden Python und Ruby nicht zwischen dem Deklarieren und Zuweisen eines Werts zu Variablen?

8

Zwei der beliebtesten dynamisch typisierten Skriptsprachen, Python und Ruby, unterscheiden in der Syntax nicht zwischen der Deklaration einer Variablen und der Zuweisung eines Werts.

Das heißt, in beiden Sprachen nwürde es so aussehen , eine Variable zu deklarieren und ihr einen Wert zuzuweisen:

n = 10

Und das spätere Zuweisen eines neuen Werts zur Variablen würde genauso aussehen.

Dies schafft zwei Hauptprobleme:

  1. Ein Tippfehler im Namen einer Variablen beim Ändern ihres Werts würde eine neue Variable erstellen und Fehler verursachen.

  2. Dies macht die Absichten des Codes weniger klar. Schwer zu wissen, wo eine Variable zuerst deklariert und verwendet wird, kann den Code verwirrender machen.

Was ich nicht verstehe, ist, warum diese Sprachen kein varSchlüsselwort für die Deklaration haben, um zwischen einer Deklaration und einer Zuweisung zu unterscheiden. Dies macht die Sprache nicht weniger dynamisch und ich sehe keine Nachteile.

Was ist der Vorteil, wenn eine Variable nicht explizit definiert werden muss?

Aviv Cohn
quelle
@Akash Das scheint überhaupt nichts mit der Frage zu tun zu haben, es bleibt gleichermaßen gültig, wenn es durchlaufen wird s/variable/name/g.

Antworten:

4

Als Benutzer (und nicht als Designer) von Python gibt es drei Gründe, warum ich mit diesen Entscheidungen zufrieden bin:

Hauptsächlich liest es sich besser. Natürlich muss ich mich bewusst dafür entscheiden, beim Schreiben eine neue Variable einzuführen , aber Code wird weitaus häufiger gelesen als geschrieben. Viel Code ist einfach in dem Sinne, dass Kontrollfluss und Verschachtelung keinen Einfluss auf die Bedeutung und Existenz von Variablen haben. Wenn ich lese

it = Snark()
message = "A letter, not signed"
if random.random() > 0.5:
    hunt(it)
    message += " (by the Knave)"
return [it, message]

dann ist es mir normalerweise egal, welche (wenn überhaupt) Erwähnung eines Namens ihn zuerst einführt, es ist mir nur wichtig, dass er da ist und was damit passiert.

Beachten Sie, dass ein signifikanter Teil des Pseudocodes dieselbe Konvention verwendet (keine Deklaration, implizite Einführung durch Zuweisung) und Python häufig nur halb im Scherz als ausführbarer Pseudocode beschrieben wird. Vier zusätzliche Zeichen für jede lokale Variable fühlen sich für meine verwöhnten Augen im Kontext von Python wie eine erhebliche Unordnung an, insbesondere wenn es sich nicht so anfühlt, als würde es einen Mehrwert bringen (siehe unten). Dies würde von einem :=Bediener wie in Go verringert .

Zweitens bin ich noch nicht auf einen Tippfehler gestoßen (aufgrund dieser speziellen Funktion), der sich auch nicht auf eine andere klare Weise gezeigt hat. Vielleicht werde ich es mir in ein paar Jahren anders überlegen, wenn ich auf solche Fehler gestoßen bin, aber bis jetzt ist es ganz unten auf meiner Liste der Dinge, die Fehler verursachen. Es gibt eine ganze Reihe von Fragen zu UnboundLocalErrorund es ist etwas schwierig, Anfängern zu erklären, aber die Häufigkeit und Beliebtheit dieser Fragen im Vergleich zu anderen Fallstricken (veränderbare Standardparameter, Referenzsemantik, Klassen- und Instanzvariablen) zeigt, dass es sich um ein seltenes Problem handelt.

Endlich die Absichtssache ... Entschuldigung, aber ich kann diese nicht wirklich verstehen. Beim Lesen und Schreiben von Python ist immer klar: Was Sie zuweisen, ist als lokal gedacht, sofern nicht laut und ausdrücklich etwas anderes erklärt wird. Keine Frage. Da (zumindest in Python) eine Variable entweder für die gesamte Funktion lokal oder überhaupt nicht ist , können Sie keinen kniffligen Code haben, der eine lokale Variable in einem Zweig und eine globale in einem anderen verwendet. Sie sehen einen Namen zugewiesen? Sie wissen sofort, dass es von Anfang an immer lokal war. Nun, es sei denn, der Code ist auf eine ganz besondere Weise gebrochen (und wirft den gefürchteten UnboundLocalErrorzur Laufzeit, wenn Sie diese Fälle eingeben ).


quelle
Hier ist ein Beispiel für einen Fehler in PHP, der durch fehlende Deklarationen aus einem praktischen Fall verursacht wurde: $a = [1, 2, 3]; foreach ($a as $k => &$v) $v++; foreach ($a as $k => $v) echo "$k => $v\n";
Alexander Gelbukh
@AlexanderGelbukh Ich kenne PHP nicht gut genug, um die Ursache zu identifizieren. Würde es Ihnen etwas ausmachen, das zu erklären?
Bitte sehen Sie dies meine Antwort . Wie Sie sehen, war es für eine ganze Reihe von Menschen, einschließlich mir, unerwartet, so dass ich viel experimentieren musste. Stellen Sie sich nun vor, wie viele falsche Programme es aufgrund eines solchen Fehlers gibt.
Alexander Gelbukh
1
@AlexanderGelbukh Beachten Sie, dass der von Ihnen beschriebene Fehler auf eine Interaktion mehrerer PHP-Funktionen (hauptsächlich Referenzen) zurückzuführen ist und IIUC in anderen Sprachen ohne Deklarationen nicht auf diese Weise auftreten kann. Was das Schreiben / Debuggen betrifft: Beachten Sie, dass die meisten Debugging-Strategien (von Low-Tech-Debuggern bis hin zu ausgefallenen zeitreisenden Debuggern) einen erheblichen Teil des Lesens des zu debuggenden Codes beinhalten.
1
Stimmen Sie voll und ganz zu: Lesbarkeit ist äußerst wichtig. Sie stimmen zu, dass das Verhindern von Fehlern wichtig ist. Sie stimmen diesen Erklärungen nicht zu, um Fehler zu vermeiden. Ich bin damit nicht einverstanden, dass Erklärungen die Lesbarkeit beeinträchtigen. Vielleicht können wir uns darauf einigen, nicht zuzustimmen :-)
Alexander Gelbukh
-3

Es ist nicht so, dass das Definieren einer Variablen dasselbe ist wie das Zuweisen einer Variablen - es ist so, dass die Variablen überhaupt nicht definiert sind. Es heißt Dynamic Typing .

Sie können keine dynamisch typisierte Sprache haben, mit der Sie eine Variable definieren können, da dies die dynamische Typisierung ist .

Die Entscheidung, dies zu tun, ändert die Art des Parsers vollständig und führt zu einer völlig anderen Art von Sprache. Der Hauptunterschied zum Endbenutzer besteht normalerweise darin, dass sich Ihre Parameter beim Definieren einer Funktion als beliebiger Typ herausstellen ("Ententypisierung"), was sowohl ein Segen ist, da dies Ihren Code viel einfacher macht, als auch Ein Fluch, der eine Vielzahl neuer Möglichkeiten bietet, wie Ihr Code fehlschlagen kann.

Ich bin kein Compiler-Experte, aber ich denke, es stimmt auch, dass Dynamic Typing erhebliche Auswirkungen auf den OOP-Geschmack hat, den Sie in einer Sprache erhalten.

Andy Jones
quelle
3
Sie sind im Irrtum. Für JavaScript im strengen Modus müssen Sie Variablen verwenden, bevor Sie sie verwenden können. Es wird jedoch dynamisch typisiert. Eins hat nichts mit dem anderen zu tun. Dynamische Typisierung bedeutet, dass Ihre Variable einen Wert eines beliebigen Typs enthalten kann. Es hat nichts damit zu tun, ob Sie es definieren müssen oder nicht. Ebenso würde eine statisch typisierte Sprache mit Typinferenz die Verwendung von Variablen ermöglichen, ohne dass diese definiert werden müssen. Diese beiden Dinge sind orthogonal.
back2dos