Warum ist x < y < z
es in Programmiersprachen nicht allgemein verfügbar?
Daraus schließe ich
- Obwohl dieses Konstrukt in der Grammatik einer Sprache trivial zu implementieren ist und Wert für Sprachbenutzer schafft,
- Der Hauptgrund dafür, dass dies in den meisten Sprachen nicht vorhanden ist, liegt in seiner Bedeutung im Verhältnis zu anderen Merkmalen und in der mangelnden Bereitschaft der Leitungsgremien der Sprachen, dies zu tun
- ärgern Benutzer mit möglicherweise brechenden Änderungen
- zu bewegen, um die Funktion zu implementieren (dh: Faulheit).
Einführung
Ich kann aus der Perspektive eines Pythonisten zu dieser Frage sprechen. Ich bin ein Benutzer einer Sprache mit dieser Funktion und möchte die Implementierungsdetails der Sprache studieren. Darüber hinaus bin ich ein wenig mit dem Prozess des Wechsels von Sprachen wie C und C ++ vertraut (der ISO-Standard wird vom Komitee geregelt und nach Jahr versioniert), und ich habe sowohl Ruby als auch Python dabei beobachtet, wie sie wichtige Änderungen umsetzen.
Dokumentation und Implementierung von Python
In der Dokumentation / Grammatik sehen wir, dass wir eine beliebige Anzahl von Ausdrücken mit Vergleichsoperatoren verketten können:
comparison ::= or_expr ( comp_operator or_expr )*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="
| "is" ["not"] | ["not"] "in"
und in der Dokumentation heißt es weiter:
Vergleiche können beliebig verkettet werden, z. B. x <y <= z ist äquivalent zu x <y und y <= z, außer dass y nur einmal ausgewertet wird (aber in beiden Fällen wird z überhaupt nicht ausgewertet, wenn x <y gefunden wird falsch sein).
Logische Äquivalenz
So
result = (x < y <= z)
ist logisch äquivalent in Bezug auf die Auswertung von x
, y
und z
, mit der Ausnahme, dass y
zweimal ausgewertet wird:
x_lessthan_y = (x < y)
if x_lessthan_y: # z is evaluated contingent on x < y being True
y_lessthan_z = (y <= z)
result = y_lessthan_z
else:
result = x_lessthan_y
Auch hier besteht der Unterschied darin, dass y nur einmal mit ausgewertet wird (x < y <= z)
.
(Beachten Sie, dass die Klammern völlig unnötig und überflüssig sind, aber ich habe sie zum Nutzen derjenigen verwendet, die aus anderen Sprachen stammen, und der obige Code ist rechtmäßig für Python.)
Untersuchen des analysierten abstrakten Syntaxbaums
Wir können untersuchen, wie Python verkettete Vergleichsoperatoren analysiert:
>>> import ast
>>> node_obj = ast.parse('"foo" < "bar" <= "baz"')
>>> ast.dump(node_obj)
"Module(body=[Expr(value=Compare(left=Str(s='foo'), ops=[Lt(), LtE()],
comparators=[Str(s='bar'), Str(s='baz')]))])"
Wir können also sehen, dass es für Python oder eine andere Sprache nicht schwierig ist, das zu analysieren.
>>> ast.dump(node_obj, annotate_fields=False)
"Module([Expr(Compare(Str('foo'), [Lt(), LtE()], [Str('bar'), Str('baz')]))])"
>>> ast.dump(ast.parse("'foo' < 'bar' <= 'baz' >= 'quux'"), annotate_fields=False)
"Module([Expr(Compare(Str('foo'), [Lt(), LtE(), GtE()], [Str('bar'), Str('baz'), Str('quux')]))])"
Und im Gegensatz zu der gegenwärtig akzeptierten Antwort ist die ternäre Operation eine generische Vergleichsoperation, die den ersten Ausdruck, eine Iteration spezifischer Vergleiche und eine Iteration von Ausdrucksknoten benötigt, um nach Bedarf ausgewertet zu werden. Einfach.
Fazit zu Python
Ich persönlich finde die Bereichssemantik recht elegant, und die meisten mir bekannten Python-Experten würden die Verwendung der Funktion fördern, anstatt sie als schädlich zu betrachten. Die Semantik wird in der bekannten Dokumentation (wie oben erwähnt) ganz klar angegeben.
Beachten Sie, dass Code viel mehr gelesen als geschrieben wird. Änderungen, die die Lesbarkeit von Code verbessern, sollten aufgegriffen und nicht durch das Hervorrufen von allgemeinen Gespenstern von Angst, Unsicherheit und Zweifel außer Acht gelassen werden .
Warum ist x <y <z in Programmiersprachen nicht allgemein verfügbar?
Ich denke, es gibt eine Zusammenführung von Gründen, die sich um die relative Bedeutung des Merkmals und den relativen Impuls / die Trägheit der Änderung drehen, die die Gouverneure der Sprachen zulassen.
Ähnliche Fragen können zu anderen, wichtigeren Sprachmerkmalen gestellt werden
Warum ist Mehrfachvererbung in Java oder C # nicht verfügbar? Auf beide Fragen gibt es hier keine gute Antwort . Vielleicht waren die Entwickler zu faul, wie Bob Martin behauptet, und die angegebenen Gründe sind lediglich Ausreden. Und Mehrfachvererbung ist ein ziemlich großes Thema in der Informatik. Es ist sicherlich wichtiger als die Verkettung von Operatoren.
Es gibt einfache Problemumgehungen
Die Verkettung von Vergleichsoperatoren ist elegant, aber keineswegs so wichtig wie die Mehrfachvererbung. Und so wie Java und C # Schnittstellen als Workaround haben, so hat auch jede Sprache mehrere Vergleiche - Sie verketten die Vergleiche einfach mit booleschen "und" s, was leicht genug funktioniert.
Die meisten Sprachen werden vom Ausschuss geregelt
Die meisten Sprachen werden vom Komitee entwickelt (anstatt wie Python einen vernünftigen gütigen Diktator für das Leben zu haben). Und ich spekuliere, dass dieses Thema einfach nicht genug Unterstützung fand, um es aus den jeweiligen Ausschüssen herauszuholen.
Können sich die Sprachen ändern, die diese Funktion nicht anbieten?
Wenn eine Sprache x < y < z
ohne die erwartete mathematische Semantik auskommt, wäre dies eine bahnbrechende Veränderung. Wenn es das überhaupt nicht zulassen würde, wäre es fast trivial hinzuzufügen.
Veränderungen brechen
In Bezug auf die Sprachen mit aktuellen Änderungen: Wir aktualisieren Sprachen mit aktuellen Verhaltensänderungen, aber Benutzer mögen dies in der Regel nicht, insbesondere Benutzer von Funktionen, die möglicherweise fehlerhaft sind. Wenn sich ein Benutzer auf das frühere Verhalten von verlässt x < y < z
, würde er wahrscheinlich lautstark protestieren. Und da die meisten Sprachen von Komitees verwaltet werden, bezweifle ich, dass wir viel politischen Willen bekommen würden, eine solche Änderung zu unterstützen.