Existe-t-il un mot clé ou un opérateur pour «ni»?

56

Existe-t-il un équivalent opérateur de ni ? Par exemple, ma couleur préférée n'est ni le vert ni le bleu.

Et le code serait équivalent à:

// example one
if (color!="green" && color!="blue") { 

}

// example two
if (x nor y) {
    // x is false and y is false
}
1,21 gigawatts
la source
12
Non, car nous en avons déjà oret !, et parce que les doubles négations sont rarement utilisées - la plupart des gens les trouvent particulièrement difficiles à lire.
Kilian Foth
70
@KilianFoth a raison. Néanmoins, les votes négatifs devraient être pour les mauvaises questions, pas pour les questions que nous n'aimons pas. De plus, il y a déjà trois votes pour clore la question parce qu'elle serait "basée sur une opinion", même si la question était totalement neutre et ne faisait pas l'objet de controverse (il existe ou non de tels opérateurs dans une langue exotique).
Christophe
3
Y a-t-il un nom pour cela? Oui: ni Est-ce un opérateur? Dans quelle langue? Et étant donné un langage, vous pouvez le rechercher dans la spéc / docs.
jonrsharpe
9
@Troyer Votre commentaire démontre le problème: vous avez mal compris la logique. ;) Ce n'est pas équivalent à un ni.
jpmc26
3
Dans les langues avec plus d'opérateurs, ce serait (par exemple, en python)color not in ['green', 'blue']
Izkata

Réponses:

71

Bien que les langues grand public ne disposent pas d'opérateurs NOR et NAND dédiés, certaines langues moins connues (par exemple, certaines langues de "golfing") en ont une. Par exemple, APL a et pour NOR et NAND, respectivement.

Une autre classe d'exemples peut être trouvée dans les langages de conception matérielle tels que VHDL , Verilog , etc. Les portes NAND et NOR sont très utiles dans la conception matérielle car elles sont généralement moins chères (nécessitant moins de transistors) que le circuit équivalent constitué de ET / OU / NON les portes, ce qui est l’une des raisons pour lesquelles les langages de conception de matériel ont tendance à les inclure; une autre raison est qu'ils peuvent être utiles pour certaines astuces de bidouillage.

nomadictype
la source
40
APL n’est pas un langage de golf , mais plutôt un langage orienté tableaux qui permet le développement interactif d’applications multi-paradigmes complètes superposées à la puissance industrielle.
Adám
59
@ Adám: Bingo .
Eric Duminil
6
@EricDuminil :-) Tout est vrai cependant.
Adám
20
@ EricDuminil Non, vraiment. APL n’est pas une langue de golf, c’est une langue pratique qui s’avère bonne au golf. Perl est similaire à cet égard, non?
Pavel
13
OP n'a pas réellement déclaré que l'APL était une langue «golfeuse», d'ailleurs.
Will Crawford
45

Non, il n'y a pas d' noropérateur dans un langage de programmation grand public de haut niveau.

Pourquoi ?

Principalement parce qu'il est difficile à lire:

  • il nécessite la combinaison mentale de plusieurs opérateurs (" et pas ", ou dans un style plus littéraire: " encore négatif ", " chaque faux " )
  • cela implique un implicite notsur le premier opérande, mais le lecteur ne le comprendra que plus tard
  • il est différent des langages humains, qui utilisent une négation explicite sur le premier opérande, telle que " ni x ni y ", " ni x ni y ". Donc, un lecteur pourrait confondre (x nor y)avec (x and not y)au lieu de((not x) and (not y))
  • certains lecteurs sont confondus avec la orsémantique apparente qui ne s'applique pas

Mais c'est tellement courant dans le matériel ...

norest une porte matérielle élémentaire qui peut être utilisée pour créer toutes les autres portes logiques. On pourrait donc soutenir que tous les autres opérateurs logiques sont des combinaisons et qu’il nors’agit de l’opérateur logique élémentaire le plus simple.

Cependant, ce qui est vrai pour le matériel n'est pas nécessairement vrai pour les humains. Et malgré sa popularité au niveau matériel, certains processeurs traditionnels n’offrent même pas d’ NORinstructions d’assemblage (par exemple x86 ).

Des alternatives

La lisibilité est importante. Et parfois, cela peut être amélioré par d'autres moyens.

Utilisation des opérateurs existants

Par exemple:

if x not in [1,2]    // use of 'in' or 'not in' operator instead of x!=1 and x!=2

Commande de conditions

if x==1 or x==2 
     action A
else 
     action B  

au lieu de

if x!=1 and x!=2 
    action B
else 
    action A

Utilisation de jusqu'à boucle

Certaines langues offrent également des instructions en boucle qui permettent d’exprimer des conditions avec whileou avec until, vous permettant de choisir la méthode la plus "positive". Ces instructions sont par exemple until c do ...en ruby , do until c ...en vb ou repeat ... until cen pascal et ses descendants.

Par exemple:

Until (x==1 or x==2) do
     ...

est équivalent à:

While (x!=1 and x!=2)
    ...

Faire une fonction

Maintenant, si vous préférez toujours la norsyntaxe, vous pouvez définir une fonction, mais uniquement si vous ne vous attendez pas à ce qu'un raccourci se produise:

If ( nor(x,y) )   // attention, x and y will always be evaluated
    ...  

Il y a un avantage de lisibilité de la fonction sur l'opérateur, car le lecteur comprend immédiatement que la négation s'applique à tous les arguments. Dans certaines langues, vous pouvez définir une fonction avec un nombre variable d'arguments.

Christophe
la source
5
Drôle, j’écris habituellement que lorsque while (not (x == 1 or x == 2))je trouve la x != 1 and x != 2version difficile à lire et que «x n’est ni 1 ni 2» est beaucoup plus facile à traiter que «x n’est pas 1 et x n’est pas 2».
Mael
1
@Baldrickk pouvez-vous élaborer?
Espérons-
4
@HopefullyHelpful Repeat... Untilexécute toujours le corps de la boucle au moins une fois. Si x vaut 1, le corps de la boucle est toujours exécuté, mais pas répété. La Whileboucle n'exécutera pas le corps dans ce cas.
Sina
2
@ Baldrickk oui vous avez tout à fait raison. Lorsque j'écrivais équivalent, je ne parlais que de la condition de boucle, car les opérateurs booléens étaient le sujet de la question. Merci, je vais le reformuler pour clarifier
Christophe
3
Le fait que x et y in nor(x,y)soient toujours évalués dépend de la langue et de la nor()mise en œuvre. Il existe des langages (D, Io,…) où la fonction appelée peut décider si et quand évaluer des arguments.
BlackJack
18

Le commentaire de @ KilianFoth sur la question est sur place.

Vous pouvez synthétiser à norpartir de notet or:

if (x nor y)

est exactement le même que

if (not (x or y))

L'introduction en nortant qu'opérateur distinct introduirait des redondances dans la langue, qui ne sont ni nécessaires, ni souhaitées (ou - qui ne sont ni nécessaires ni souhaitables).

De même, je ne connais pas de langue ayant un nandopérateur - probablement parce qu'il peut être synthétisé à partir de notet d' andopérateurs.

Vous pouvez, en théorie, créer une langue avec des opérateurs uniquement nandou uniquement nor. Tous and, oret notpourrait alors par synthesied d'eux. Le seul problème est que cela serait ridiculement lourd. Pour des exemples, voir la logique NOR et la logique NAND sur Wikipedia.

Mael
la source
4
Les licenciements pourraient également ne pas être nécessaires ou souhaités :)
Dave
@Dave Ce jeu de mots était destiné, heureux de vous voir remarqué ;-)
Mael
5
Les licenciements à eux seuls n'expliquent pas vraiment pourquoi norn'est pas inclus. Sinon, pourquoi les langues ont andet or? Ils sont redondants, grâce à De Morgan. En fait, vous pouvez remplacer les trois opérateurs logiques classiques ( and, or, not) en fournissant simplement nor , comme vous l' avez justement observé.
Konrad Rudolph
1
@ KonradRudolph Techniquement, tout ce dont vous avez besoin est d' un opérateur lambda . La raison pour laquelle nous en faisons plus est d’adapter le modèle mental de la plupart des programmeurs. La plupart des programmeurs pensent la logique en termes de and, oret not- parce que ce utilisent les langues humaines. Une fois que vous correspondez au modèle mental de et / ou / non, alors, ni devenir ni redondant. Leur redondance est même encodée dans leurs noms: "n (ot) et" et "n (ot) ou". Si nous avions pour eux des termes anglais distincts et préexistants, et pas seulement des termes synthétisés, vous les verrez probablement plus souvent.
RM
1
Re redondance comme argument: Il y a des langues avec plus not, and, or. Par exemple, certains dialectes BASIC (GW-BASIC, QuickBASIC,…) ont des opérateurs exclusifs ou XOR, IMP (→ NOT (x XOR y)) et une équivalence EQV (→ NOT (x) OU y).
BlackJack
11

Oui, APL et certains de ses dialectes ont ni (et nand ). Dans APL, ni est notée (depuis est ou et ~n'est pas ):

 resultExampleOne color
  :If (color'green')⍱(color'blue')
      result'warm'
  :Else
      result'cold'
  :EndIf


 resultExampleTwo(x y)
  :If xy
      result'x is false and y is false'
  :Else
      result'at least one of them is true'
  :EndIf

Essayez-le en ligne!

Adam
la source
10

Cette réponse provient du langage assembleur pour un ordinateur fabriqué au milieu des années 1960. C'est assez obscur, mais à certains égards, cela répond à votre question.

DEC (Digital Equipment Corporation) a lancé l'ordinateur PDP-6 au milieu des années 1960. Cette machine avait un total de 64 instructions qui étaient des opérations booléennes sur deux opérandes (y compris des cas dégénérés). Ces 64 instructions étaient en réalité 16 opérateurs avec 4 variantes dans chaque opérateur.

Deux des opérateurs, ANDCB et ORCB, ont respectivement implémenté NOR et NAND (à moins que je ne sois mêlé à la logique du double négatif). Vous pouvez voir la table d'opcode . La table d'opcode est en réalité pour l'ordinateur PDP-10, un successeur du PDP-6.

Si vous regardez l'instruction numérique en binaire, cela devient plus intéressant. Il s'avère que pour tous les opcodes compris entre 400 et 477 (octal), quatre bits de l'instruction elle-même fournissent une table de vérité de quatre bits à 16 opérateurs booléens possibles. Certains de ces opérateurs ignorent une ou les deux entrées. Par exemple, SETZ et SETO ignorent les deux entrées.

Les concepteurs du PDP-6 ont exploité ce fait pour implémenter toutes ces instructions avec moins de logique qu'il n'en aurait fallu pour en implémenter seulement certaines. Certaines de ces instructions apparaissent rarement, voire jamais, dans le code en langage assembleur. Mais ils étaient tous là.

Ainsi, ANDCB est l'équivalent de NOR. (encore une fois, à moins que ma logique ne soit inversée, auquel cas ORCB est l'équivalent).

Walter Mitty
la source
3

Perl a le unlessmot clé qui vous permet d'inverser les conditions:

unless ($color eq 'green' or $color eq 'blue') {
    # code
}

Bien que vous ne soyez pas un opérateur NOR, vous pouvez exprimer votre intention de la même manière.

Rory Hunter
la source
3

L' noropérateur, comme vous l'avez décrit, ne serait pas reproductible, ce qui entraînera de nombreuses bogues difficiles à détecter.

Votre "exemple 2" est essentiellement ceci:

if (false nor false) {
becomes
if (true) {

Mais essayez à nouveau avec trois variables et voyez ce qui se passe:

if (false nor false nor false) {
becomes
if ((false nor false) nor false) {
becomes
if (true nor false) {
becomes
if (false) {
Buh Buh
la source