Por que as linguagens não incluem implicação como um operador lógico?

59

Pode ser uma pergunta estranha, mas por que não há implicação como um operador lógico em muitas linguagens (Java, C, C ++, Python Haskell - embora como último operador tenha definido o usuário é trivial adicioná-lo)? Eu acho que a implicação lógica é muito mais clara para escrever (particularmente em expressões assertivas ou assertivas) e depois negação com 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
}
    
por Maciej Piechotka 18.01.2013 / 13:48
fonte

9 respostas

61

Pode ser útil ter algumas vezes, sem dúvida. Vários pontos argumentam contra tal operador:

  • Os caracteres - e > são valiosos, isolados e combinados. Muitas línguas já as usam para significar outras coisas. (E muitos não podem usar conjuntos de caracteres unicode para sua sintaxe).
  • A implicação é muito contra-intuitiva, mesmo para pessoas de mentalidade lógica, como programadores. O fato de três das quatro entradas da tabela verdade serem true surpreende muitas pessoas.
  • Todos os outros operadores lógicos são simétricos, o que tornaria -> uma exceção à ortogonalidade.
  • Ao mesmo tempo, há uma solução fácil: use os operadores ! e || .
  • A implicação é usada muito menos que o lógico and / or .

É provavelmente por isso que o operador é raro hoje em dia. Certamente, isso pode se tornar mais comum, já que novas linguagens dinâmicas usam o Unicode para tudo e a sobrecarga do operador se torna mais elegante novamente.

    
por 18.01.2013 / 14:00
fonte
54

Acredito que a resposta esteja nas fundações matemáticas . A implicação é geralmente considerada e definida como uma operação derivada, não elementar, de álgebras booleanas. As linguagens de programação seguem esta convenção.

Esta é a Proposição I do Capítulo II da Uma Investigação das Leis do Pensamento (1854) de George Boole :

All the operations of Language, as an instrument of reasoning, may be conducted by a system of signs composed of the following elements, viz.:

1st. Literal symbols, as x, y, &c., representing things as subjects of our conceptions.

2nd. Signs of operation, as +, −, ×, standing for those operations of the mind by which the conceptions of things are combined or resolved so as to form new conceptions involving the same elements.

3rd. The sign of identity, =.

And these symbols of Logic are in their use subject to definite laws, partly agreeing with and partly differing from the laws of the corresponding symbols in the science of Algebra.

O sinal de Boole + representa a mesma "operação da mente" que hoje reconhecemos tanto como o booleano "or" como a união de conjuntos. Da mesma forma, os sinais - e × correspondem à nossa negação booleana, complemento de um conjunto, booleano "e" e interseção de conjuntos.

    
por 18.01.2013 / 15:03
fonte
37

ATUALIZAÇÃO: essa pergunta foi assunto do meu blog em novembro de 2015 . Obrigado pela pergunta interessante!

O Visual Basic 6 (e o VBScript) tinham operadores Imp e Eqv . Ninguém os usou. Ambos foram removidos no VB.NET; Pelo que sei, ninguém reclamou.

Trabalhei na equipe de compiladores do Visual Basic (como estagiário) por um ano inteiro e nunca percebi que o VB tinha essas operadoras. Se eu não fosse o cara que escrevia o compilador VBScript e, portanto, tivesse que testar suas implementações, provavelmente não os teria notado. Se o cara na equipe de compiladores não souber sobre o recurso e não usá-lo, isso indica algo sobre a popularidade e a utilidade do recurso.

Você mencionou idiomas semelhantes ao C. Eu não posso falar com C ou C ++ ou Java, mas posso falar com C #. Há uma lista de recursos sugeridos pelo usuário para C # literalmente mais longos que o seu braço. Que eu saiba, nenhum usuário jamais propôs um operador desse tipo para a equipe de C #, e passei por essa lista muitas e muitas vezes.

Recursos que existem e que não são usados em um idioma, e nunca são solicitados em outro, é improvável que os candidatos o transformem em linguagens de programação modernas. Particularmente, quando não há tempo e esforço suficiente e dinheiro disponível no orçamento para fazer recursos que as pessoas fazem querem.

    
por 20.01.2013 / 01:12
fonte
19

Eu só posso adivinhar, mas uma razão pode ser que existem soluções alternativas que são bastante simples e legíveis. Vamos considerar o seu exemplo:

if (mode != ECB) assert (iv != null);

assert (mode != ECB --> iv != null);  // <-- that's only one character shorter

Se você precisar de uma expressão, o operador inline-if disponível na maioria dos idiomas (geralmente chamado de operador ternário) pode ser usado. Concedido, isso não é tão elegante quanto A --> B , mas o número de casos de uso pode não justificar a adição (e manutenção!) De outro operador:

assert (mode != ECB ? iv != null : true);
    
por 18.01.2013 / 13:57
fonte
11

Eiffel tem implicação

Na verdade, tem ainda mais. Tem vários operadores semi-rigorosos, bem como rigorosos.

A razão pela qual os programadores não usam essas coisas é porque nunca são treinados para saber exatamente o que são, como usá-los e quando usá-los - e também como projetar com eles. Porque eles nunca são treinados, eles nunca pedem pelos escritores do compilador, e é por isso que o pessoal do compilador não se incomoda em colocar tais mecanismos no compilador. Quando os estudantes de Ciência da Computação e os programadores do Shade-tree começarem a ter uma educação mais completa, os compiladores começarão a recuperar o atraso.

Acontece que, uma vez que você tenha uma linguagem com esses operadores booleanos e saiba como projetar com eles e usá-los, use-os.

Em Eiffel, o uso da palavra-chave "implica" é bastante proeminente por causa do Projeto por Contrato, devido à natureza booleana das asserções contratuais. Existem alguns contratos que só podem ser escritos de forma adequada e eficiente com o operador "implica". Isto então implora o comentário de que as línguas sem contratos estão mais longe, sem causa, para olhar, treinar e implementar o uso da implicação.

Acrescente a isso que a maioria dos programadores são "math-and-logic-weak" nos conta o restante da história. Mesmo que você seja de matemática e lógica em sua educação, quando se escolhe uma linguagem que não implemente construtos, como implicação, então tende-se a pensar que tais coisas são desnecessárias ou inúteis. Um raramente questiona a linguagem e entra em uma câmara de eco de: "Bem, os caras do compilador não vêem a necessidade" e "Bem, os programadores não vêem a necessidade" - círculo infinito e vicioso.

Em vez disso, as pessoas que compilarão precisam voltar à teoria, escrever uma notação de linguagem que seja sugerida ou implícita pela teoria (por exemplo, Teoria Orientada a Objetos), independentemente do que as massas não lavadas de programadores pensam ou solicitam. A partir daí, professores, professores e outros profissionais precisam habilmente treinar mentes jovens com base na teoria bruta e NÃO na "teoria através da lente da linguagem". Quando isso acontece, as pessoas acordam de repente e percebem o que estão perdendo e o que foi impingido a elas.

Neste momento - existe tanta teoria por aí que se disfarça como Orientada a Objetos, mas é apenas O-O-através de um vidro-escuro-de- [escolha sua língua]. Não se pode ler a maioria dos livros de "teoria" sobre O-O porque eles querem interpretar o que a teoria é através das lentes de alguma linguagem. Totalmente falso e incorreto. Seria como ensinar matemática com base na minha calculadora ou minha régua de cálculo. Ninguém permite que a realidade ensine sobre si mesma e então usa uma notação para descrever o que se observa - isso é chamado de "ciência". Este outro mash chamado O-O-based-on-language-X é tão distorcido que mal representa a realidade.

Então, afaste-se da linguagem, dê uma olhada na teoria bruta e comece novamente. Não permita que limitações, restrições e trabalhos de pintura de uma linguagem lhe digam qual é a teoria. Simplesmente deixe que a realidade da teoria dite sua própria notação e então passe de lá para a formulação de uma linguagem.

A partir daí, você começará a entender como implicação e "implicação" não são apenas úteis, mas também elegantes e muito legais!

Tenha um ótimo!

    
por 13.05.2014 / 03:28
fonte
7

O Python tem um operador de implicação de uma maneira oculta.

O operador less-than-or-isals é sobrecarregado para aceitar valores booleanos. Como resultado, pode-se usá-lo como um operador de implicação.

Prova por exemplo (código Python):

print (False <= False) # This will print True.
print (False <= True)  # This will print True.
print (True <= False)  # This will print False.
print (True <= True)   # This will print True.

Lembre-se de que a tabela verdade do operador de implicação é:

LEFT RIGHT RESULT
F    F     T
F    T     T
T    F     F
T    T     T
    
por 15.07.2014 / 10:21
fonte
5

Eiffel tem um operador "implica" e é muito bom escrever pré e pós-condições. Torna o código mais legível, infelizmente isso nunca foi uma intenção fundamental para linguagem C e pouquíssimas pessoas usaram eiffel, então a beleza de "implica" como operador não é bem conhecida.

    
por 06.11.2013 / 09:45
fonte
2

Para mim, o grande problema com implies vem quando a condição inicial é falsa; por exemplo: "Se o sol é verde, então eu sou um morcego frutífero." Verdade!

Na lógica formal, apenas trabalha para atribuir "True" ao valor quando a condição da implicação não é satisfeita. Mas na programação, isso pode levar a resultados contraintuitivos e surpreendentes.

Eu realmente acho que o exemplo @Heinzi dá acima:

if (sun.color() == "green") then assert(me.species() == "fruitbat")

É muito mais fácil de entender e menos propenso a erros devido à má compreensão da lógica.

No contexto de testes, eu apenas pararia no momento em que minhas suposições se tornassem falsas:

assert(sun.color() == "green")
assert(me.species() == "fruitbat")

Então, para o ponto de @Eric Lippert, como programador eu não sei quando usaria um operador implícito. O comportamento "Falsa é Verdadeira" parece útil no contexto da lógica matemática e formal, mas pode levar a resultados inesperados na lógica do programa.

...

Ninguém mencionou o comum "?" operador, onde "A? B: true" é o mesmo que "implica". Mas enquanto a lógica formal é verdadeira para a condição "else", "?" permite que o desenvolvedor atribua isso explicitamente.

Na lógica formal, o uso de "true" funciona, mas na programação, se a condição for falsa, a melhor resposta é mais como "null" ou "void" ou "skip", ou até mesmo falsa.

Acho que alguém teria que argumentar porque "implies" é um operador mais útil do que "?", ou instruções "if" ou apenas fluxo de programa regular.

    
por 01.05.2014 / 16:45
fonte
1

Raquete tem implies . É macro-expande para uma expressão if .

    
por 02.05.2014 / 17:11
fonte