it-swarm.com.de

Warum enthalten Sprachen keine Implikation als logischen Operator?

Es mag eine seltsame Frage sein, aber warum gibt es in vielen Sprachen keine Implikation als logischer Operator (Java, C, C++, Python Haskell - obwohl als letztes benutzerdefinierte Operatoren trivial sind) füge es hinzu)? Ich finde die logische Implikation viel klarer zu schreiben (insbesondere in Asserts oder Assert-ähnlichen Ausdrücken) als die Negation mit oder:

encrypt(buf, key, mode, iv = null) {
    assert (mode != ECB --> iv != null);
    assert (mode == ECB || iv != null);
    assert (implies(mode != ECB, iv != null)); // User-defined function
}
62

Es könnte ohne Zweifel manchmal nützlich sein. Mehrere Punkte sprechen gegen einen solchen Betreiber:

  • Die Charaktere - und > sind sowohl isoliert als auch kombiniert wertvoll. Viele Sprachen verwenden sie bereits, um andere Dinge zu bedeuten. (Und viele können keine Unicode-Zeichensätze für ihre Syntax verwenden.)
  • Implikationen sind sehr kontraintuitiv, selbst für logisch denkende Menschen wie Programmierer. Die Tatsache, dass drei der vier Wahrheitstabelleneinträge true sind, überrascht viele Menschen.
  • Alle anderen logischen Operatoren sind symmetrisch, wodurch -> eine Ausnahme von der Orthogonalität.
  • Gleichzeitig gibt es eine einfache Problemumgehung: Verwenden Sie Operatoren ! und ||.
  • Implikationen werden weitaus seltener verwendet als logische and/or.

Dies ist wahrscheinlich der Grund, warum der Betreiber heute selten ist. Sicherlich könnte es häufiger werden, da neue dynamische Sprachen Unicode für alles verwenden und das Überladen von Operatoren wieder in Mode kommt.

61
Kilian Foth

Ich glaube, die Antwort liegt in den mathematischen Grundlagen . Implikation wird normalerweise als abgeleitete, nicht elementare Operation von Booleschen Algebren betrachtet und definiert. Programmiersprachen folgen dieser Konvention.

Dies ist Satz I von Kapitel II aus George Booles Eine Untersuchung der Denkgesetze (1854) :

Alle Operationen der Sprache als Argumentationsinstrument können von einem Zeichensystem ausgeführt werden, das sich aus den folgenden Elementen zusammensetzt, nämlich:

1. Wörtliche Symbole wie x, y usw., die Dinge als Subjekte unserer Vorstellungen darstellen.

2 .. Zeichen der Operation, als +, -, ×, stehen für jene Operationen des Geistes, durch die die Vorstellungen von Dingen kombiniert oder aufgelöst werden, um neue Vorstellungen zu bilden, die dieselben Elemente beinhalten.

3 .. Das Zeichen der Identität, =.

Und diese Symbole der Logik unterliegen in ihrer Verwendung bestimmten Gesetzen, die teilweise mit den Gesetzen der entsprechenden Symbole in der Wissenschaft der Algebra übereinstimmen und sich teilweise von diesen unterscheiden.

Booles Zeichen + repräsentiert die gleiche "Operation des Geistes", die wir heute sowohl als boolesches ´oder´ als auch als Vereinigung von Mengen erkennen. In ähnlicher Weise entsprechen die Vorzeichen - und × unserer booleschen Negation, dem Komplement einer Menge, dem booleschen ´und´ und dem Schnittpunkt von Mengen.

54
COME FROM

UPDATE: Diese Frage war das Thema meines Blogs im November 2015 . Danke für die interessante Frage!


Visual Basic 6 (und VBScript) hatten die Operatoren Imp und Eqv. Niemand hat sie benutzt. Beide wurden in VB.NET entfernt. Meines Wissens hat sich niemand beschwert.

Ich habe ein ganzes Jahr im Visual Basic-Compiler-Team (als Praktikant) gearbeitet und nie bemerkt, dass VB sogar diese Operatoren hatte. Wäre ich nicht der Typ gewesen, der den VBScript-Compiler geschrieben hat, und deshalb musste ihre Implementierungen testen, hätte ich sie wahrscheinlich nicht bemerkt. Wenn der Typ im Compiler-Team nichts über die Funktion weiß und es nicht weiß Verwenden Sie es, das Ihnen etwas über die Popularität und Nützlichkeit der Funktion sagt.

Sie haben C-ähnliche Sprachen erwähnt. Ich kann nicht mit C oder C++ oder Java, aber ich kann mit C # sprechen. Es gibt eine Liste von vom Benutzer vorgeschlagenen Funktionen für C #, die buchstäblich länger sind als Ihr Arm. Meines Wissens kein Benutzer hat dem C # -Team jemals einen solchen Operator vorgeschlagen, und ich habe diese Liste viele, viele Male durchgesehen.

Funktionen, die in einer Sprache vorhanden sind und nicht verwendet werden und in einer anderen Sprache nie angefordert werden, sind wahrscheinlich keine Kandidaten für moderne Programmiersprachen. Insbesondere, wenn im Budget nicht genügend Zeit, Mühe und Geld zur Verfügung stehen, um Funktionen zu erstellen, die von Personen gewünscht werden.

37
Eric Lippert

Ich kann nur raten, aber ein Grund könnte sein, dass es Problemumgehungen gibt, die recht einfach und lesbar sind. Betrachten wir Ihr Beispiel:

if (mode != ECB) assert (iv != null);

assert (mode != ECB --> iv != null);  // <-- that's only one character shorter

Wenn Sie einen Ausdruck benötigen, kann der in den meisten Sprachen verfügbare Inline-If-Operator (häufig als ternärer Operator bezeichnet) verwendet werden. Zugegeben, das ist nicht so elegant wie A --> B, aber die Anzahl der Anwendungsfälle rechtfertigt möglicherweise nicht das Hinzufügen (und Verwalten!) eines anderen Operators:

assert (mode != ECB ? iv != null : true);
19
Heinzi

Eiffel hat Implikationen

Es hat sogar noch mehr. Es hat eine Reihe von semi-strengen Operatoren sowie strenge.

Der Grund, warum Programmierer solche Dinge nicht verwenden, liegt darin, dass sie nie geschult werden, genau zu wissen, was sie sind, wie sie zu verwenden sind und wann sie zu verwenden sind - und wie sie mit ihnen zu entwerfen sind. Da sie nie geschult werden, fragen sie die Compiler-Autoren niemals danach, weshalb sich die Compiler-Leute nicht die Mühe machen, solche Mechanismen in den Compiler zu integrieren. Wenn Informatikstudenten und Shade-Tree-Programmierer eine rundere Ausbildung erhalten, werden die Compiler aufholen.

Es stellt sich heraus, dass Sie, sobald Sie eine Sprache mit solchen Booleschen Operatoren haben und wissen, wie man mit ihnen entwirft und sie verwendet, diese verwenden.

In Eiffel ist die Verwendung des Schlüsselworts "impliziert" aufgrund von Design-by-Contract aufgrund der Booleschen Schwere von Vertragsbehauptungen ziemlich prominent. Es gibt einige Verträge, die nur mit dem Operator "impliziert" ordnungsgemäß und effizient geschrieben werden können. Dies führt dann zu der Bemerkung, dass Sprachen ohne Verträge weiterhin ohne Grund sind, die Verwendung von Implikationen zu betrachten, zu trainieren und umzusetzen.

Hinzu kommt, dass die meisten Programmierer "mathematisch und logisch schwach" sind, was uns den Rest der Geschichte erzählt. Selbst wenn Sie in Ihrer Ausbildung mathematisch und logisch belastet sind, neigt man dazu, solche Dinge für unnötig oder nicht nützlich zu halten, wenn man eine Sprache wählt, die keine Konstrukte wie Implikation implementiert. Man hinterfragt selten die Sprache und gerät in eine Echokammer von: "Nun, die Compiler-Leute sehen die Notwendigkeit nicht" und "Nun, die Programmierer sehen die Notwendigkeit nicht" - endloser und teuflischer Kreis.

Stattdessen müssen die Compiler-Leute auf die Theorie zurückgreifen und eine Sprachnotation schreiben, die von der Theorie vorgeschlagen oder impliziert wird (z. B. objektorientierte Theorie), unabhängig davon, was die ungewaschenen Massen von Programmierern denken oder verlangen. Von dort aus müssen Professoren, Lehrer und andere Fachkräfte junge Mush-Köpfe auf der Grundlage der Rohtheorie und NICHT "Theorie durch die Sprachlinse" fachmännisch schulen. Wenn dies geschieht, werden die Leute plötzlich aufwachen und erkennen, was sie vermisst haben und was ihnen aufgezwungen wurde.

Im Moment gibt es so viel Theorie, die sich als objektorientiert tarnt, aber nur O-O-durch-ein-Glas-dunkel-von-[wähle deine Sprache]. Man kann die meisten "Theorie" -Bücher über O-O nicht lesen, weil sie die Theorie durch die Linse einer Sprache interpretieren wollen. Völlig falsch und falsch. Es wäre, als würde man Mathematik basierend auf meinem Taschenrechner oder meinem Rechenschieber unterrichten. NEIN - man lässt die Realität über sich selbst lehren und beschreibt dann anhand einer Notation, was man beobachtet - das nennt man "Wissenschaft". Dieser andere Brei namens O-O-basiert-auf-Sprache-X ist so verzerrt, dass er die Realität kaum darstellt.

Gehen Sie also von der Sprache weg, werfen Sie einen Blick auf die Rohtheorie und beginnen Sie erneut. Lassen Sie sich nicht von Einschränkungen, Einschränkungen und Malaufträgen einer Sprache über die Theorie informieren. Lassen Sie einfach die Realität der Theorie ihre eigene Notation diktieren und gehen Sie dann von dort aus zur Formulierung einer Sprache über.

Von dort aus werden Sie feststellen, wie Implikation und "Implikationen" nicht nur nützlich, sondern auch elegant und sehr cool sind!

Habe einen schönen!

12
Larry

Python hat einen Implikationsoperator auf eine Art versteckte Weise.

Der Operator "kleiner als oder gleich" ist überladen, um boolesche Werte zu akzeptieren. Infolgedessen kann man es als Implikationsoperator verwenden.

Beweis am Beispiel (Python-Code):

print (False <= False) # This will print True.
print (False <= True)  # This will print True.
print (True <= False)  # This will print False.
print (True <= True)   # This will print True.

Die Wahrheitstabelle des Implikationsoperators lautet:

LEFT RIGHT RESULT
F    F     T
F    T     T
T    F     F
T    T     T
7
Mackenzie

Eiffel hat einen "impliziten" Operator und ist sehr gut geeignet, um Vor- und Nachbedingungen zu schreiben. Es macht Code lesbarer, leider war das nie eine grundlegende Absicht für C-ähnliche Sprache und zu wenige Leute verwendeten Eiffel, so dass die Schönheit von "impliziert" als Operator nicht gut bekannt ist.

5
Lothar

Für mich kommt das große Problem mit Implikationen, wenn die Anfangsbedingung falsch ist; Zum Beispiel: "Wenn die Sonne grün ist, bin ich eine Fruchtfledermaus." Wahr!

In der formalen Logik funktioniert es nur, dem Wert "True" zuzuweisen, wenn die Bedingung der Implikation nicht erfüllt ist. Bei der Programmierung kann dies jedoch zu kontraintuitiven und überraschenden Ergebnissen führen.

Ich denke tatsächlich, dass das Beispiel @Heinzi oben gibt:

if (Sun.color() == "green") then assert(me.species() == "fruitbat")

Ist viel einfacher zu verstehen und weniger fehleranfällig aufgrund von Missverständnissen der Logik.

Im Zusammenhang mit Tests würde ich einfach aufhören, sobald meine Annahmen falsch wurden:

assert(Sun.color() == "green")
assert(me.species() == "fruitbat")

Aus Gründen von @Eric Lippert weiß ich als Programmierer nicht, wann ich einen impliziten Operator verwenden würde. Das Verhalten "Falsch ist wahr" scheint im Kontext der mathematischen, formalen Logik nützlich zu sein, könnte jedoch zu unerwarteten Ergebnissen in der Programmlogik führen.

...

Niemand hat das gemeinsame "?" Operator, wobei "A? B: true" dasselbe ist wie "impliziert". Aber während die formale Logik der "else" -Bedingung "true" zuweist, "?" lässt den Entwickler das explizit zuweisen.

In der formalen Logik funktioniert die Verwendung von "true", aber in der Programmierung ist die bessere Antwort eher "null" oder "void" oder "skip" oder sogar false, wenn die Bedingung falsch ist.

Ich denke, jemand müsste den Fall ansprechen, warum "impliziert" ein nützlicherer Operator ist als "?" Oder "if" -Anweisungen oder nur ein regulärer Programmablauf.

2
Rob

Schläger hat implies . Das Makro wird zu einem if Ausdruck erweitert.

1
Phil