Existe uma palavra-chave ou operador para "nor"?


56

Existe um operador equivalente a nem ? Por exemplo, minha cor favorita não é verde nem azul.

E o código seria equivalente a:

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

}

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

12
Não, porque já temos ore !, e porque duplos negativos raramente são usados ​​- a maioria das pessoas os acha especialmente difíceis de ler.
Kilian Foth

70
@KilianFoth está certo. No entanto, os votos negativos devem ser feitos para perguntas ruins, não para perguntas que não gostamos. Além disso, já existem três votos para encerrar a questão, porque ela seria "baseada em opiniões", apesar de a questão ser totalmente neutra e não controversa (ou existem operadores em algum idioma exótico ou não).
Christophe

3
Existe um nome para isso? Sim: nem. É um operador? Em que língua? E, dada uma linguagem, você pode procurar isso em spec / docs.
jonrsharpe

9
@ Trojan Seu comentário demonstra o problema: você entendeu errado a lógica. ;) Isso não é equivalente a um nem.
Jpmc26

3
Em idiomas com mais operadores, este seria (por exemplo, em python)color not in ['green', 'blue']
Izkata

Respostas:


71

Embora os idiomas principais não tenham operadores NOR e NAND dedicados, alguns idiomas menos conhecidos (por exemplo, alguns idiomas "de golfe") possuem. Por exemplo, o APL possui e para NOR e NAND, respectivamente.

Outra classe de exemplos pode ser encontrada em linguagens de design de hardware, como VHDL , Verilog , etc. As portas NAND e NOR são bastante úteis no design de hardware devido ao fato de serem geralmente mais baratas (exigindo menos transistores) do que o circuito equivalente feito com AND / OR / NOT portas, que é uma das razões pelas quais as linguagens de design de hardware tendem a incluí-las; outro motivo é que eles podem ser úteis para certos truques de manipulação de bits.


40
O APL não é uma linguagem de golfe , mas uma linguagem orientada a matriz que permite o desenvolvimento interativo de aplicativos multiparadigmas de pilha completa com força industrial.
Adám 06/02/19

59
@ Adám: Bingo .
Eric Duminil

6
@EricDuminil :-) Mas é tudo verdade.
Adám 06/02/19

20
@EricDuminil Não, sério. APL não é uma linguagem de golfe, é uma linguagem prática que por acaso é boa em golfe. Perl é semelhante a este respeito, não?
Pavel

13
A OP não disse que a APL era uma linguagem de “golfe”, aliás.
Will Crawford

45

Não, não existe noroperador em nenhuma linguagem de programação convencional de alto nível.

Por quê ?

Principalmente porque é difícil ler:

  • requer a combinação mental de vários operadores (" e não ", ou em um estilo mais literário: " mais negativo ", " cada falso " )
  • implica implícito notno primeiro operando, mas o leitor só entende isso depois
  • é diferente das linguagens humanas, que usam uma negação explícita no primeiro operando, como " nem x nem y ", " nem x nem y ". Portanto, um leitor pode confundir (x nor y)com, em (x and not y)vez de((not x) and (not y))
  • alguns leitores estão confusos com a aparente orsemântica que não se aplica

Mas é tão comum em hardware ...

noré um portão de hardware elementar que pode ser usado para criar todos os outros portões lógicos. Portanto, alguém poderia argumentar que todos os outros operadores lógicos são combinações e noré o operador lógico elementar mais simples.

No entanto, o que é verdade para o hardware não é necessariamente verdadeiro para os humanos. E apesar da popularidade no nível do hardware, algumas CPUs convencionais nem oferecem um NORem seu conjunto de instruções do assembler (por exemplo, x86 ).

Alternativas

Legibilidade é importante. E, às vezes, pode ser aprimorado por outros meios.

Uso de operadores existentes

Por exemplo:

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

Ordenação de condições

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

ao invés de

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

Uso do loop até

Alguns idiomas também oferecem instruções de loop que permitem expressar condições com whileou com until, permitindo que você escolha a maneira mais "positiva". Estas instruções são por exemplo until c do ...em rubi , do until c ...em v , ou repeat ... until cem Pascal e seus descendentes.

Por exemplo:

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

é equivalente a:

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

Faça uma função

Agora, se você ainda prefere a norsintaxe, pode definir uma função, mas apenas se não espera que um atalho ocorra:

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

Há uma vantagem de legibilidade da função sobre o operador, porque o leitor imediatamente entende que a negação se aplica a todos os argumentos. Em alguns idiomas, você pode definir uma função com um número variável de argumentos.


5
Engraçado, geralmente escrevo isso porque while (not (x == 1 or x == 2))acho a x != 1 and x != 2versão difícil de ler e considero "x nem 1 nem 2" muito mais fácil de processar do que "x não é 1 e x não é 2".
Mael

11
@Baldrickk você pode elaborar?
que você

4
@HopfullyHelpful Repeat... Untilsempre executa o corpo do loop pelo menos uma vez. Se x for 1, o corpo do loop ainda será executado, mas não será repetido. O Whileloop não executará o corpo neste caso.
S6 de

2
@ Baldrickk sim, você está completamente certo. Quando escrevo equivalente, eu estava falando apenas sobre a condição do loop, pois os operadores booleanos eram o assunto da pergunta. Obrigado, eu vou reformular a esclarecer
Christophe

3
Se xey nor(x,y)são sempre avaliados depende do idioma e de como nor()é implementado. Existem idiomas (D, Io, ...) onde a função chamada pode decidir se e quando avaliar argumentos.
BlackJack 6/18

18

O comentário de @ KilianFoth sobre a questão está no local.

Você pode sintetizar nora partir de note or:

if (x nor y)

é exatamente o mesmo que

if (not (x or y))

Introduzir norcomo um operador separado introduziria redundâncias no idioma, que não são necessárias nem desejadas (ou - que não são necessárias e não desejadas).

Da mesma forma, não conheço nenhum idioma que tenha um nandoperador - provavelmente porque ele pode ser sintetizado a partir de note andoperadores.

Você poderia, em teoria, criar uma linguagem com apenas nandou apenas noroperadores. Todos and, ore notpoderia, então, por synthesied deles. O único problema é que isso seria ridiculamente pesado. Para exemplos, consulte lógica NOR e lógica NAND na Wikipedia.


4
Os despedimentos poderia também não ser necessário ou desejado :)
Dave

@ Dave Isso pun foi destinado, contente de ver você percebeu ;-)
Mael

5
Redundâncias por si só não explicam realmente por que nornão estão incluídas. Caso contrário, por que os idiomas têm ande or? Eles são redundantes, graças a De Morgan. Na verdade, você poderia substituir todos os três operadores lógicos convencionais ( and, or, not), fornecendo apenas nor , como você observou, com razão.
21978 Konrad Rudolph

11
@KonradRudolph Tecnicamente, tudo o que você precisa é de um operador lambda . A razão pela qual fazemos mais é corresponder ao modelo mental que a maioria dos programadores possui. A maioria dos programadores pensa em lógica em termos de and, ore not- porque é isso que a maioria das linguagens humanas usa. Depois de combinar o modelo mental de e / ou / não, nem & nand se tornam redundantes. Sua redundância é mesmo codificada em seus nomes: "n (ot) e" and "n (ot) ou". Se tivéssemos termos ingleses distintos e preexistentes para eles, e não apenas sintetizados, você provavelmente os veria com mais frequência.
RM

11
Re redundância como argumento: Existem línguas com mais de not, and, or. Por exemplo, alguns dialetos BASIC (GW-BASIC, QuickBASIC,…) têm IMP exclusivo ou XOR, IMP implicação (→ NÃO (x XOR y)) e EQV equivalente (→ NÃO (x) OR y) como operadores adicionais.
BlackJack

11

Sim, APL e alguns de seus dialetos têm nem (e NAND ). Em APL, nem é denotada (desde é ou e ~é não ):

 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

Experimente online!


10

Esta resposta é da linguagem assembler para um computador fabricado em meados da década de 1960. Isso é bastante obscuro, mas, em alguns aspectos, trata da sua pergunta.

A DEC (Digital Equipment Corporation) lançou o computador PDP-6 em meados da década de 1960. Esta máquina tinha um total de 64 instruções que eram operações booleanas em dois operandos (incluindo alguns casos degenerados). Essas 64 instruções eram realmente 16 operadores com 4 variantes em cada operador.

Dois dos operadores, ANDCB e ORCB implementaram NOR e NAND, respectivamente (a menos que eu esteja confuso com a lógica dupla negativa). Você pode ver a tabela opcode . A tabela opcode é realmente para o computador PDP-10, um sucessor do PDP-6.

Se você observar as instruções numéricas em binário, elas ficarão mais interessantes. Acontece que, para todos os códigos de operação no intervalo 400-477 (octal), quatro bits na própria instrução fornecem uma tabela verdade de quatro bits para 16 possíveis operadores booleanos. Alguns desses operadores ignoram uma ou ambas as entradas. Por exemplo, SETZ e SETO ignoram as duas entradas.

Os projetistas do PDP-6 exploraram esse fato para implementar todas essas instruções com menos lógica do que seria necessário para implementar apenas algumas delas. Algumas dessas instruções raramente apareceram, se é que alguma vez, no código da linguagem assembly. Mas eles estavam todos lá.

Portanto, ANDCB é o equivalente a NOR. (novamente, a menos que eu tenha minha lógica de trás para frente, caso em que ORCB é o equivalente).


3

Perl tem a unlesspalavra - chave que permite inverter condicionais:

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

Embora não seja um operador NOR, você pode expressar sua intenção de maneira semelhante.


3

O noroperador, como você descreveu, não seria repetível, o que levaria a muitos bugs difíceis de detectar.

O seu "Exemplo 2" é essencialmente este:

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

Mas tente novamente com três variáveis ​​e veja o que acontece:

if (false nor false nor false) {
becomes
if ((false nor false) nor false) {
becomes
if (true nor false) {
becomes
if (false) {
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.