C'est peut-être une question étrange, mais pourquoi n'y a-t-il aucune implication en tant qu'opérateur logique dans de nombreux langages (Java, C, C ++, Python Haskell - bien que le dernier ait eu des opérateurs définis par l'utilisateur, il est trivial de l'ajouter)? Je trouve que l'implication logique est beaucoup plus claire à écrire (en particulier dans les assertions ou les expressions semblables à des assertions), puis la négation avec ou:
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
la source
la source
assert
n ° 1 est plus clair que le n ° 2. Cela fait un certain temps que je regarde la N ° 1 et je ne vois toujours pas comment son comportement pourrait être considéré comme intuitif. (surtout avec le!=
renversant la logique)Réponses:
Il pourrait être utile d'avoir parfois, sans aucun doute. Plusieurs points plaident contre un tel opérateur:
-
et>
sont précieux, à la fois isolément et combinés. Beaucoup de langues les utilisent déjà pour signifier autre chose. (Et beaucoup ne peuvent pas utiliser de jeux de caractères unicode pour leur syntaxe.)true
surprennent beaucoup de monde.->
une exception à l'orthogonalité.!
et||
.and
/or
.C'est probablement pourquoi l'opérateur est rare aujourd'hui. Cela pourrait certainement devenir plus courant, car les nouveaux langages dynamiques utilisent Unicode pour tout et la surcharge d'opérateurs redevient à la mode.
la source
!
et||
, not!
et&&
:A -> B
est équivalent à!A || B
ce qui est équivalent à!(A && !B)
.Je crois que la réponse réside dans les fondements mathématiques . L'implication est généralement considérée et définie comme une opération dérivée, et non élémentaire, des algèbres de Boole. Les langages de programmation suivent cette convention.
Voici la proposition I du chapitre II de George Boole dans Une enquête sur les lois de la pensée (1854) :
Le signe de Boole + représente le même "fonctionnement de l'esprit" que nous reconnaissons aujourd'hui à la fois comme le "booléen" ou "l'union des ensembles". De la même manière, les signes - et × correspondent à notre négation booléenne, complément d’un ensemble, booléen ´ et´ et à l’intersection d’ensembles.
la source
a || b = !(!a && !b)
(j'ai rencontré ou en tant qu'opérateur dérivé en logique). 2. La raison pour laquelle c'est fait, c'est généralement pour simplifier l'induction, ce qui est une preuve, à mon avis (nous savons que les opérateurs dérivés ne sont que des raccourcis, nous n'avons donc pas besoin d'avoir des arguments séparés à leur place). @ GlenH7: Quelles conditions "ne vous inquiétez pas"?a --> b
est le même que!a || b
.!=
) nxor (==
) ...!(a && b)
ou NOR!(a || b)
. Par exemple,NOT a == a NAND a
,a AND b == NOT(a NAND b)
,a OR b == (NOT a) NAND (NOT b)
. Mais fournir uniquement un opérateur NAND vous place dans le domaine des langages ésotériques (ce qui convient étonnamment bien, étant donné le nom d'utilisateur du répondeur ;-)).MISE À JOUR: Cette question a été le sujet de mon blog en novembre 2015 . Merci pour la question intéressante!
Visual Basic 6 (et VBScript) avait
Imp
etEqv
opérateurs. Personne ne les utilisait. Les deux ont été supprimés dans VB.NET; à ma connaissance, personne ne s'est plaint.J'ai travaillé sur l'équipe du compilateur Visual Basic (en tant que stagiaire) pendant un an et je n'ai jamais remarqué que VB avait même ces opérateurs. Si je n'avais pas été le type qui a écrit le compilateur VBScript et que j'ai donc dû tester leurs implémentations, je ne les aurais probablement pas remarqués. Si le membre de l' équipe de compilation ne connaît pas la fonctionnalité et ne l'utilise pas, cela vous dit quelque chose sur la popularité et l'utilité de la fonctionnalité.
Vous avez mentionné les langues de type C. Je ne peux pas parler en C, C ++ ou Java, mais je peux parler en C #. Il existe une liste de fonctionnalités suggérées par les utilisateurs pour C # littéralement plus longues que votre bras. À ma connaissance, aucun utilisateur n'a jamais proposé un tel opérateur à l'équipe C # et j'ai parcouru cette liste à maintes reprises.
Les fonctionnalités existantes et non utilisées dans une langue et qui ne sont jamais demandées dans une autre sont des candidats improbables à intégrer les langages de programmation modernes. En particulier , lorsqu'il n'y a pas assez de temps et d' efforts et d' argent disponible dans le budget pour faire que les gens caractéristiques font défaut.
la source
[switch]
paramètres de filtre.EQV
. L'opérateur que j'ai souvent souhaité serait "et non", ce qui encouragerait l'opérateur de droite avant de le nier. Ainsi, vous0xABCD12345678ul ~& 0x00200000u
obtiendrez 0xABCD12145678ul plutôt que 0x12145678ul.Je peux seulement deviner, mais l'une des raisons pourrait être qu'il existe des solutions de contournement assez simples et lisibles. Considérons votre exemple:
Si vous avez besoin d'une expression, vous pouvez utiliser l'opérateur inline-if disponible dans la plupart des langues (souvent appelé opérateur ternaire). Certes, cela n’est pas aussi élégant que
A --> B
, mais le nombre de cas d’utilisation pourrait ne pas justifier l’ajout (et le maintien!) D’un autre opérateur:la source
if
déclaration est beaucoup, beaucoup plus claire pour à peu près tout le monde.Eiffel a des implications
Il en a encore plus. Il a un certain nombre d'opérateurs semi-stricts ainsi que stricts.
La raison pour laquelle les programmeurs n'utilisent pas de telles choses est parce qu'ils ne sont jamais formés pour savoir exactement ce qu'ils sont, comment les utiliser et quand les utiliser - ainsi que comment concevoir avec eux. Parce qu'ils ne sont jamais formés, ils ne le demandent jamais aux rédacteurs du compilateur, c'est pourquoi les compilateurs ne se donnent pas la peine d'insérer de tels mécanismes dans le compilateur. Lorsque les étudiants en informatique et les programmeurs Shade-tree commenceront à recevoir une éducation plus complète, les compilateurs commenceront à se mettre à niveau.
Il s'avère qu'une fois que vous avez un langage avec de tels opérateurs booléens et que vous savez concevoir avec eux et les utiliser, vous les utilisez.
Dans Eiffel, l’utilisation du mot-clé "implique" est assez importante en raison de la conception par contrat en raison de la nature booléenne des assertions de contrat. Certains contrats ne peuvent être écrits correctement et efficacement qu'avec l'opérateur "implique". Cela nous amène à dire que les langues sans contrat sont en outre sans raison d’examiner, de former et de mettre en œuvre l’utilisation de l’implication.
Ajoutez à cela que la plupart des programmeurs sont "faibles en maths et en logique" nous dit le reste de l'histoire. Même si vous avez beaucoup de math et de logique dans votre éducation, quand on choisit un langage qui ne met pas en œuvre des constructions telles que l'implication, on a tendance à penser que de telles choses sont inutiles ou inutiles. On met rarement en doute le langage et on entre dans une chambre d'écho de: "Les compilateurs ne voient pas la nécessité" et "Les programmeurs ne voient pas la nécessité" - cercle vicieux et sans fin.
Au lieu de cela, les compilateurs doivent sauvegarder la théorie, écrire une notation de langage suggérée ou implicite par la théorie (par exemple, la théorie orientée objet), indépendamment de ce que les masses non-lavées de pensées pensent ou demandent. À partir de là, les professeurs, enseignants et autres professionnels doivent former de manière experte de jeunes esprits fondés sur la théorie brute et non sur une "théorie à travers le prisme du langage". Lorsque cela se produit, les gens se réveillent soudainement et réalisent ce qui leur manque et ce qui leur a été imposé.
À l'heure actuelle - il y a tellement de théories qui se font passer pour des objets orientés, mais qui ne sont que de simples mots-clés. On ne peut pas lire la plupart des livres "théoriques" sur OO car ils veulent interpréter la théorie à travers le prisme d'une langue. Totalement faux et incorrect. Ce serait comme enseigner ma calculatrice basée sur les mathématiques ou ma règle de diapositive. NON - on permet à la réalité d'enseigner soi-même et on utilise ensuite une notation pour décrire ce que l'on observe - c'est ce qu'on appelle "la science". Cette autre composition appelée OO-based-on-language-X est tellement biaisée qu'elle représente à peine la réalité.
Alors, éloignez-vous de la langue, jetez un coup d'œil à la théorie brute et recommencez. Ne laissez pas les limitations, les contraintes et les travaux de peinture d’une langue vous expliquer la théorie. Laissez simplement la réalité de la théorie dicter sa propre notation, puis passez à la formulation d’un langage.
A partir de là, vous commencerez à comprendre comment l'implication et "implique" est non seulement utile, mais élégant et très cool!
Avoir un grand!
la source
Python a un opérateur d'implication de manière cachée.
L'opérateur inférieur à ou égal est surchargé pour accepter les valeurs booléennes. En conséquence, on peut l'utiliser comme opérateur d'implication.
Preuve par exemple (code Python):
Rappelez-vous que la table de vérité de l'opérateur d'implication est:
la source
f() implies g()
ne devrait pas évaluerg()
sif()
estFalse
, mais<=
évalueg()
dans ce cas.did_all_possible_stuff = x.do_required_stuff() and (x.supports_optional_stuff() <= x.do_optional_stuff())
à travailler.Eiffel a un opérateur "implique" et c'est très agréable pour écrire des pré-conditions et des post-conditions. Cela rend le code plus lisible, malheureusement cela n’a jamais été une intention fondamentale pour le langage C et trop peu de gens utilisent eiffel, donc la beauté de "implique" en tant qu’opérateur n’est pas bien connue.
la source
Pour moi, le gros problème avec implique vient lorsque la condition initiale est fausse; par exemple: "Si le soleil est vert, alors je suis une batte de fruits." Vrai!
En logique formelle, il suffit d'assigner "True" à la valeur lorsque la condition de l'implication n'est pas remplie. Mais en programmation, cela pourrait conduire à des résultats contre-intuitifs et surprenants.
En fait, je pense que l'exemple donné par @Heinzi ci-dessus:
Est beaucoup plus facile à comprendre et moins sujet aux erreurs en raison d’une mauvaise compréhension de la logique.
Dans le contexte des tests, je m'arrêterais au moment où mes hypothèses deviendraient fausses:
Donc, au point de @Eric Lippert, en tant que programmeur, je ne sais pas quand j'utiliserais un opérateur implique. Le comportement "False is True" semble utile dans le contexte de la logique mathématique formelle, mais pourrait conduire à des résultats inattendus dans la logique de programme.
...
Personne n'a mentionné le commun "?" opérateur, où "A? B: true" est identique à "implique". Mais alors que la logique formelle assigne vrai à la condition "else", "?" laisse le développeur assigner cela explicitement.
En logique formelle, l’utilisation de "vrai" marche, mais en programmation, si la condition est fausse, la meilleure réponse est plutôt "nulle" ou "vide" ou "ignorer", voire même fausse.
Je pense que quelqu'un devrait expliquer pourquoi "implique" est un opérateur plus utile que "?", Ou "if", ou simplement un déroulement de programme normal.
la source
La raquette a
implies
. Il macro-étend à uneif
expression.la source