Es mag eine seltsame Frage sein, aber warum gibt es in vielen Sprachen keine Implikation als logischer Operator (Java, C, C ++, Python Haskell - obwohl es als letztes trivial ist, benutzerdefinierte Operatoren hinzuzufügen)? Ich finde logische Implikationen viel klarer zu schreiben (insbesondere in Behauptungen oder assert-ähnlichen Ausdrücken) als 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
}
language-design
Maciej Piechotka
quelle
quelle
assert
Nummer 1 ist klarer als Nummer 2. Ich habe einige Zeit auf # 1 gestarrt und kann immer noch nicht erkennen, wie das Verhalten als intuitiv angesehen werden kann. (vor allem mit dem zusätzlichen!=
Spiegeln der Logik)Antworten:
Es könnte nützlich sein, manchmal zweifellos zu haben. Gegen einen solchen Betreiber sprechen mehrere Punkte:
-
und>
sind wertvoll, sowohl isoliert als auch kombiniert. Viele Sprachen benutzen sie bereits, um andere Dinge zu bedeuten. (Und viele können Unicode-Zeichensätze nicht für ihre Syntax verwenden.)true
überrascht viele Menschen.->
eine Ausnahme von der Orthogonalität darstellen würde.!
und||
.and
/ verwendetor
.Dies ist wahrscheinlich der Grund, warum der Betreiber heute selten ist. Dies könnte sicherlich häufiger vorkommen, da neue dynamische Sprachen Unicode für alles verwenden und das Überladen von Operatoren wieder in Mode kommt.
quelle
!
und||
nicht ,!
und&&
:A -> B
ist äquivalent zu!A || B
denen äquivalent zu!(A && !B)
.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 Proposition I von Kapitel II aus George Booles Eine Untersuchung der Gesetze des Denkens (1854) :
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 Zeichen - und × unserer Booleschen Negation, der Ergänzung einer Menge, der Booleschen ´und´ und der Schnittmenge von Mengen.
quelle
a || b = !(!a && !b)
(ich traf oder als abgeleiteter Operator in der Logik). 2. Der Grund, warum dies getan wird, ist in der Regel die Vereinfachung der Einführung, wie ich glaube (wir wissen, dass abgeleitete Operatoren nur Abkürzungen sind, sodass wir keinen separaten Fall für sie benötigen). @ GlenH7: Welche "egal" Bedingungen?a --> b
ist das gleiche wie!a || b
.!=
) nxor (==
) ...!(a && b)
oder NOR ableiten!(a || b)
. Zum BeispielNOT a == a NAND a
,a AND b == NOT(a NAND b)
,a OR b == (NOT a) NAND (NOT b)
. Wenn Sie jedoch nur einen NAND-Operator angeben, werden Sie in das Reich der esoterischen Sprachen versetzt (was angesichts des Benutzernamens des Antwortenden überraschend gut passt ;-)).UPDATE: Diese Frage war Gegenstand meines Blogs im November 2015 . Danke für die interessante Frage!
Visual Basic 6 (und VBScript) hatte
Imp
undEqv
Operatoren. Niemand hat sie benutzt. Beide wurden in VB.NET entfernt. meines wissens hat sich niemand beschwert.Ich arbeitete ein ganzes Jahr lang im Visual Basic-Compiler-Team (als Praktikant) und habe nie bemerkt, dass VB diese Operatoren überhaupt hatte. Wäre ich nicht der Typ gewesen, der den VBScript-Compiler geschrieben hat, und hätte daher deren Implementierungen testen müssen, hätte ich sie wahrscheinlich nicht bemerkt. Wenn der Typ im Compilerteam nichts über die Funktion weiß und sie nicht verwendet, können Sie sich über die Beliebtheit und den Nutzen der Funktion informieren.
Sie haben C-ähnliche Sprachen erwähnt. Ich kann nicht mit C oder C ++ oder Java sprechen, aber ich kann mit C # sprechen. Es gibt eine Liste der vom Benutzer vorgeschlagenen Funktionen für C #, die buchstäblich länger sind als Ihr Arm. Meines Wissens hat noch kein Benutzer dem C # -Team einen solchen Operator vorgeschlagen, und ich habe diese Liste viele Male durchgesehen.
Es ist unwahrscheinlich, dass Features, die in einer Sprache vorhanden und nicht verwendet werden und in einer anderen Sprache nicht angefordert werden, in moderne Programmiersprachen übergehen. Vor allem, wenn im Budget nicht genügend Zeit, Mühe und Geld zur Verfügung stehen, um Funktionen zu erstellen, die die Leute wirklich wollen.
quelle
[switch]
Filterparameter einfacher und leserlicher implementieren kann.EQV
. Der Operator, den ich mir oft gewünscht habe, ist "und nicht", wodurch der Operator für die rechte Hand gefördert wird, bevor er negiert wird. Somit0xABCD12345678ul ~& 0x00200000u
ergäbe 0xABCD12145678ul statt 0x12145678ul.Ich kann nur raten, aber ein Grund könnte sein, dass es Workarounds gibt, die recht einfach und lesbar sind. Betrachten wir Ihr Beispiel:
Wenn Sie einen Ausdruck benötigen, kann der Inline-If-Operator verwendet werden, der in den meisten Sprachen verfügbar ist (häufig als ternärer Operator bezeichnet). Zugegeben, dies ist nicht so elegant wie
A --> B
, aber die Anzahl der Anwendungsfälle rechtfertigt möglicherweise nicht das Hinzufügen (und Pflegen!) Eines weiteren Operators:quelle
if
Aussage ist für fast jeden viel, viel klarer.Eiffel hat Auswirkungen
Es hat eigentlich noch mehr. Es hat eine Reihe von semi-strengen Operatoren sowie streng.
Der Grund, warum Programmierer solche Dinge nicht benutzen, ist, dass sie nie genau wissen, was sie sind, wie man sie benutzt und wann man sie benutzt - und wie man mit ihnen gestaltet. Da sie nie geschult werden, fragen sie die Compiler-Autoren nie danach, weshalb sich die Compiler-Leute nicht die Mühe machen, solche Mechanismen in den Compiler einzubauen. Wenn Informatikstudenten und Schattenbaumprogrammierer eine rundere Ausbildung erhalten, werden die Compiler aufholen.
Es stellt sich heraus, dass Sie, wenn Sie eine Sprache mit solchen Booleschen Operatoren haben und wissen, wie Sie mit ihnen entwerfen und sie verwenden, diese verwenden.
In Eiffel ist die Verwendung des Schlüsselworts "implies" aufgrund von Design-by-Contract aufgrund des Booleschen Charakters von Vertragsbehauptungen eher verbreitet. Es gibt einige Verträge, die nur mit dem Operator "impliziert" ordnungsgemäß und effizient geschrieben werden können. Dies wirft dann die Bemerkung auf, dass Sprachen ohne Verträge weiterhin ohne Grund sind, die Verwendung von Implikationen zu betrachten, zu trainieren und zu implementieren.
Hinzu kommt, dass die meisten Programmierer "mathematisch-logisch-schwach" sind und uns den Rest der Geschichte erzählen. Selbst wenn Sie in Ihrer Ausbildung sehr mathematisch und logisch sind, neigen Sie dazu, solche Dinge für unnötig oder nicht nützlich zu halten, wenn Sie eine Sprache wählen, 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 Kreislauf.
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-Minds auf der Basis von Roh-Theorie und NICHT "Theorie durch die Sprachlinse" fachmännisch ausbilden. Wenn dies geschieht, werden die Menschen plötzlich aufwachen und erkennen, was ihnen gefehlt hat und was ihnen aufgezwungen wurde.
Momentan gibt es so viele Theorien, die sich als objektorientiert ausgeben, aber nur als OO-through-a-Glass-Darkly-of- [Wählen Sie Ihre Sprache]. Man kann die meisten "Theorie" -Bücher über OO nicht lesen, weil sie das, was die Theorie ist, durch die Linse einer Sprache interpretieren wollen. Völlig falsch und falsch. Es wäre, als würde man Mathe auf der Grundlage meines Taschenrechners oder meines Rechenschiebers unterrichten. NEIN - man lässt sich von der Realität etwas über sich selbst beibringen und beschreibt dann anhand einer Notation, was man beobachtet - das nennt man "Wissenschaft". Dieser andere Brei namens OO-based-on-language-X ist so verzerrt, dass er kaum die Realität darstellt.
Also, entfernen Sie sich von der Sprache, werfen Sie einen Blick auf die rohe Theorie und beginnen Sie von vorne. Lassen Sie sich nicht von Einschränkungen, Einschränkungen und Malereien einer Sprache erzählen, was die Theorie ist. Lassen Sie einfach die Realität der Theorie ihre eigene Notation diktieren und gehen Sie dann von dort zur Formulierung einer Sprache über.
Von dort werden Sie anfangen zu verstehen, wie Implikation und "Implikationen" nicht nur nützlich, sondern auch elegant und sehr cool sind!
Habe einen schönen!
quelle
Python hat einen versteckten Implikationsoperator.
Der Operator less-than-or-equals ist überladen, um boolesche Werte zu akzeptieren. Infolgedessen kann man es als Implikationsoperator verwenden.
Beweis durch Beispiel (Python-Code):
Erinnern Sie sich an die Wahrheitstabelle des Implikationsoperators:
quelle
f() implies g()
nicht auswerten,g()
wennf()
istFalse
, aber<=
wirdg()
in diesem Fall ausgewertet .did_all_possible_stuff = x.do_required_stuff() and (x.supports_optional_stuff() <= x.do_optional_stuff())
, dass es funktioniert.Eiffel hat einen "impliziten" Operator und eignet sich sehr gut zum Schreiben von Vor- und Nachbedingungen. Es macht Code lesbarer, leider war das nie eine grundlegende Bedeutung für C-ähnliche Sprache und zu wenige Leute verwendeten Eiffel, so dass die Schönheit von "impliziert" als Operator nicht gut bekannt ist.
quelle
Für mich kommt das große Problem mit impliziert, wenn die Anfangsbedingung falsch ist; Zum Beispiel: "Wenn die Sonne grün ist, dann bin ich eine Fruchtfledermaus." Wahr!
In der formalen Logik funktioniert es einfach, dem Wert "True" zuzuweisen, wenn die Bedingung der Implikation nicht erfüllt ist. Bei der Programmierung könnte dies jedoch zu kontraintuitiven und überraschenden Ergebnissen führen.
Ich denke tatsächlich, das Beispiel @Heinzi gibt oben:
Ist viel einfacher zu verstehen und weniger anfällig für Fehler aufgrund von Missverständnissen der Logik.
Im Rahmen des Testens würde ich einfach anhalten, sobald meine Annahmen falsch wurden:
Um es mit @Eric Lippert zu sagen, als Programmierer weiß ich nicht, wann ich einen impliziten Operator verwenden würde. Das Verhalten "Falsch ist Wahr" erscheint im Kontext der mathematischen, formalen Logik nützlich, 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 "?" 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 falsch, wenn die Bedingung falsch ist.
Ich denke, jemand müsste den Fall stellen, warum "impliziert" ein nützlicherer Operator ist als "?" Oder "if" -Anweisungen oder einfach nur ein regulärer Programmfluss.
quelle
Schläger hat
implies
. Das Makro wird zu einemif
Ausdruck erweitert.quelle