Esiste una parola chiave o un operatore per "né"?


56

Esiste un operatore equivalente di ? Ad esempio, il mio colore preferito non è né verde né blu.

E il codice sarebbe equivalente a:

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

}

// example two
if (x nor y) {
    // x is false and y is false
}

12
No, perché abbiamo già ore !, e perché i doppi negativi sono usati raramente - la maggior parte delle persone li trova particolarmente difficili da leggere.
Kilian Foth,

70
@KilianFoth ha ragione. Tuttavia, i voti negativi dovrebbero riguardare domande sbagliate, non domande che non ci piacciono. Inoltre, ci sono già tre voti per chiudere la domanda perché sarebbe "basata sull'opinione", nonostante la domanda sia totalmente neutra e non controversa (o ci sono operatori di questo tipo in un linguaggio esotico o no).
Christophe,

3
C'è un nome per questo? Sì: né. È un operatore? In che lingua? E data una lingua, potresti cercarla nelle specifiche / nei documenti.
jonrsharpe,

9
@Troyer Il tuo commento dimostra il problema: hai sbagliato la logica. ;) Ciò non equivale a un né.
jpmc26,

3
Nelle lingue con più operatori, questo sarebbe (ad esempio, in pitone)color not in ['green', 'blue']
Izkata,

Risposte:


71

Sebbene le lingue tradizionali non abbiano operatori NOR e NAND dedicati, alcune lingue meno conosciute (ad esempio, alcune lingue "da golf") lo fanno. Ad esempio, APL ha e per NOR e NAND, rispettivamente.

Un'altra classe di esempi può essere trovata in linguaggi di progettazione hardware come VHDL , Verilog , ecc. Le porte NAND e NOR sono piuttosto utili nella progettazione hardware poiché sono generalmente più economiche (richiedono meno transistor) rispetto al circuito equivalente realizzato da AND / OR / NOT gates, che è uno dei motivi per cui i linguaggi di progettazione hardware tendono ad includerli; un altro motivo è che possono essere utili per alcuni trucchetti.


40
APL non è un linguaggio da golf , ma piuttosto un linguaggio orientato all'array che consente lo sviluppo interattivo di applicazioni multi-paradigma full-stack con forza industriale.
Adám,

59
@Adám: Bingo .
Eric Duminil,

6
@EricDuminil :-) È tutto vero però.
Adám,

20
@EricDuminil No, davvero. APL non è un linguaggio da golf, è un linguaggio pratico che sembra essere bravo a giocare a golf. Perl è simile a questo proposito, no?
Pavel,

13
OP non ha in realtà detto che APL fosse un linguaggio "golfistico", tra l'altro.
Will Crawford,

45

No, non esiste un noroperatore in alcun linguaggio di programmazione tradizionale di alto livello.

Perché ?

Principalmente perché è difficile da leggere:

  • richiede la combinazione mentale di più operatori (" e non ", o in uno stile più letterario: " ulteriore negativo ", " ogni falso " )
  • implica un implicito notsul primo operando, ma il lettore lo capisce solo in seguito
  • è diverso dai linguaggi umani, che usano una negazione esplicita sul primo operando, come " né x né y ", " né x né y ". Quindi un lettore potrebbe confondersi (x nor y)con (x and not y)invece di((not x) and (not y))
  • alcuni lettori sono confusi con l'apparente orsemantico che non si applica

Ma è così comune nell'hardware ...

norè un gate hardware elementare che può essere utilizzato per realizzare tutte le altre porte logiche. Quindi si potrebbe sostenere che tutti gli altri operatori logici sono combinazioni ed norè l'operatore logico elementare più semplice.

Tuttavia, ciò che è vero per l'hardware non è necessariamente vero per gli umani. E nonostante la sua popolarità a livello hardware, alcune CPU tradizionali non offrono nemmeno un NORset di istruzioni assembler (ad es. X86 ).

alternative

La leggibilità è importante. E a volte può essere migliorato con altri mezzi.

Uso di operatori esistenti

Per esempio:

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

Ordinamento delle condizioni

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

invece di

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

Uso di fino ad anello

Alcune lingue offrono anche istruzioni cicliche che consentono di esprimere le condizioni con whileo con until, permettendoti di scegliere il modo più "positivo". Queste istruzioni sono ad esempio until c do ...in rubino , do until c ...in vb o repeat ... until cin pascal e suoi discendenti.

Per esempio:

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

è equivalente a:

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

Crea una funzione

Ora, se preferisci ancora la norsintassi, potresti definire una funzione, ma solo se non prevedi che accada un collegamento:

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

Esiste un vantaggio di leggibilità della funzione rispetto all'operatore, poiché il lettore comprende immediatamente che la negazione si applica a tutti gli argomenti. In alcune lingue è possibile definire una funzione con un numero variabile di argomenti.


5
Divertente, di solito scrivo che, while (not (x == 1 or x == 2))poiché trovo x != 1 and x != 2difficile leggere la versione, e trovo che "x non è né 1, né 2" molto più facile da elaborare di "x non è 1, e x non è 2".
Mael,

1
@Baldrickk puoi elaborare?
Speriamo utile

4
@HopefullyHelpful Repeat... Untilesegue sempre il corpo del loop almeno una volta. Se x è 1, il corpo del loop viene comunque eseguito, ma non ripetuto. Il Whileloop non eseguirà il corpo in questo caso.
sina,

2
@Baldrickk sì, hai perfettamente ragione. Quando scrivo equivalente, parlavo solo della condizione del loop, poiché gli operatori booleani erano l'oggetto della domanda. Grazie, lo riformulerò per chiarire
Christophe

3
Se x e y in nor(x,y)vengono sempre valutati dipende dalla lingua e da come nor()viene implementata. Esistono lingue (D, Io, ...) in cui la funzione chiamata può decidere se e quando valutare gli argomenti.
BlackJack,

18

Il commento di KilianFoth sulla domanda è perfetto.

Puoi sintetizzare norda note or:

if (x nor y)

è esattamente lo stesso di

if (not (x or y))

L'introduzione norcome operatore separato introdurrebbe ridondanze nella lingua, che non sono né necessarie né desiderate (o - che non sono necessarie e non desiderate).

Allo stesso modo, non sono a conoscenza di alcuna lingua che abbia un nandoperatore, probabilmente perché può essere sintetizzata da note andoperatori.

In teoria, potresti creare una lingua con solo nando solo noroperatori. Tutti and, ore notpotrebbe poi da synthesied da loro. L'unico problema è che questo sarebbe ridicolmente ingombrante. Per esempi, vedere la logica NOR e la logica NAND su Wikipedia.


4
I licenziamenti potrebbero anche non essere necessari o desiderati :)
Dave,

@Dave Quel gioco di parole era previsto, felice di vederti notato ;-)
Mael

5
I licenziamenti da soli non spiegano perché nornon siano inclusi. Altrimenti, perché le lingue hanno ande or? Sono ridondanti, grazie a De Morgan. In realtà, si potrebbe sostituire tutti e tre gli operatori logici convenzionali ( and, or, not) fornendo solo nor , come ha giustamente osservato.
Konrad Rudolph,

1
@KonradRudolph Tecnicamente, tutto ciò che serve è un operatore lambda . Il motivo per cui facciamo di più è quello di abbinare il modello mentale della maggior parte dei programmatori. La maggior parte dei programmatori pensa alla logica in termini di and, ore not- perché è quello che usano la maggior parte delle lingue umane. Una volta che abbini il modello mentale di e / o / no, né & nand diventano ridondanti. La loro ridondanza è persino codificata nei loro nomi: "n (ot) e" e "n (ot) o". Se avessimo termini inglesi distinti e preesistenti per loro, e non solo quelli sintetizzati, probabilmente li vedresti più spesso.
RM

1
Re ridondanza come argomento: Ci sono lingue con più di not, and, or. Ad esempio alcuni dialetti BASIC (GW-BASIC, QuickBASIC, ...) hanno esclusivi o XOR, implicazioni IMP (→ NOT (x XOR y)) ed equivalenza EQV (→ NOT (x) OR y) come operatori aggiuntivi.
BlackJack

11

Sì, APL e alcuni dei suoi dialetti non hanno (e nand ). In APL, è indicato con (poiché è o ed ~è no ):

 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

Provalo online!


10

Questa risposta proviene dal linguaggio assemblatore per un computer realizzato a metà degli anni '60. È piuttosto oscuro, ma per alcuni aspetti risponde alla tua domanda.

DEC (Digital Equipment Corporation) ha lanciato il computer PDP-6 a metà degli anni '60. Questa macchina aveva un totale di 64 istruzioni che erano operazioni booleane su due operandi (inclusi alcuni casi degeneri). Queste 64 istruzioni erano in realtà 16 operatori con 4 varianti in ciascun operatore.

Due degli operatori, ANDCB e ORCB hanno implementato NOR e NAND rispettivamente (a meno che non mi sia confuso con la doppia logica negativa). È possibile visualizzare la tabella dei codici operativi . La tabella degli opcode è in realtà per il computer PDP-10, un successore del PDP-6.

Se guardi le istruzioni numeriche in binario, diventa più interessante. Si scopre che per tutti i codici operativi nell'intervallo 400-477 (ottale), quattro bit nell'istruzione stessa forniscono una tabella di verità a quattro bit per 16 possibili operatori booleani. Alcuni di questi operatori ignorano uno o entrambi gli ingressi. Ad esempio SETZ e SETO ignorano entrambi gli ingressi.

I progettisti del PDP-6 hanno sfruttato questo fatto per implementare tutte queste istruzioni con meno logica di quella necessaria per implementarne solo alcune. Alcune di queste istruzioni sono apparse raramente, se non mai, nel codice del linguaggio assembly. Ma erano tutti lì.

Quindi ANDCB è l'equivalente di NOR. (di nuovo, a meno che non avessi la mia logica al contrario, nel qual caso ORCB è l'equivalente).


3

Perl ha la unlessparola chiave che ti consente di invertire i condizionali:

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

Pur non essendo un operatore NOR, puoi esprimere le tue intenzioni in modo simile.


3

L' noroperatore come hai descritto non sarebbe ripetibile, il che porterà a molti bug difficili da individuare.

Il tuo "Esempio 2" è essenzialmente questo:

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

Ma riprova con tre variabili e vedi cosa succede:

if (false nor false nor false) {
becomes
if ((false nor false) nor false) {
becomes
if (true nor false) {
becomes
if (false) {
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.