Pode ser uma pergunta estranha, mas por que não há implicação como operador lógico em muitas linguagens (Java, C, C ++, Python Haskell - embora, como a última tenha definido os usuários, os operadores definidos sejam triviais para adicioná-lo)? Acho a implicação lógica muito mais clara para escrever (particularmente em afirmações ou expressões semelhantes a afirmações) 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
}
language-design
Maciej Piechotka
fonte
fonte
assert
número 1 é mais claro que o número 2. Eu olho para o número 1 por algum tempo e ainda não consigo ver como seu comportamento pode ser considerado intuitivo. (especialmente com o extra de!=
inversão da lógica)Respostas:
Pode ser útil ter algumas vezes, sem dúvida. Vários pontos argumentam contra esse operador:
-
e>
são valiosos, tanto isolados quanto combinados. Muitos idiomas já os usam para significar outras coisas. (E muitos não podem usar conjuntos de caracteres unicode para sua sintaxe.)true
surpreendentes para muitas pessoas.->
uma exceção para a ortogonalidade.!
e||
.and
/or
.Provavelmente é por isso que hoje o operador é raro. Certamente isso poderia se tornar mais comum, à medida que novas linguagens dinâmicas usam o Unicode para tudo e a sobrecarga do operador se torna mais elegante novamente.
fonte
!
e||
, not!
e&&
:A -> B
é equivalente ao!A || B
que é equivalente a!(A && !B)
.Eu acredito que a resposta está nos fundamentos matemáticos . A implicação é geralmente considerada e definida como uma operação derivada, e não elementar, de álgebras booleanas. As linguagens de programação seguem esta convenção.
Esta é a Proposição I do Capítulo II de Uma Investigação das Leis do Pensamento de George Boole (1854) :
O sinal de Boole + representa a mesma "operação da mente" que hoje reconhecemos como o booleano "ou" e a união de conjuntos. Da mesma forma, os sinais - e × correspondem à nossa negação booleana, complemento de um conjunto, 'b' e 'interseção de conjuntos.
fonte
a || b = !(!a && !b)
(eu conheci ou como operador derivado na lógica). 2. A razão pela qual isso é feito é geralmente simplificar as provas que eu acredito (sabemos que os operadores derivados são apenas atalhos, portanto não precisamos ter argumentos separados para eles). @ GlenH7: O que "não me importo" condições?a --> b
é o mesmo que!a || b
.!=
) nxor (==
) ...!(a && b)
ou NOR!(a || b)
. Por exemplo,NOT a == a NAND a
,a AND b == NOT(a NAND b)
,a OR b == (NOT a) NAND (NOT b)
. Porém, fornecer apenas um operador NAND o coloca no domínio das línguas esotéricas (o que se encaixa surpreendentemente bem, dado o nome de usuário do respondente ;-)).ATUALIZAÇÃO: Esta questão foi o assunto do meu blog em novembro de 2015 . Obrigado pela pergunta interessante!
Visual Basic 6 (e VBScript) tinha
Imp
eEqv
operadores. Ninguém os usou. Ambos foram removidos no VB.NET; que eu saiba, ninguém reclamou.Trabalhei na equipe do compilador do Visual Basic (como estagiário) por um ano inteiro e nunca percebi que o VB ainda tinha esses operadores. Se eu não tivesse sido o cara escrevendo o compilador VBScript e, portanto, tivesse que testar suas implementações, provavelmente não as teria notado. Se o cara da equipe do compilador não souber sobre o recurso e não o usar, isso informará sobre a popularidade e a utilidade do recurso.
Você mencionou idiomas do tipo C. 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 esse operador à equipe de C #, e eu examinei essa lista muitas e muitas vezes.
Recursos que existem e não são usados em um idioma e nunca são solicitados em outro são candidatos improváveis para torná-lo em linguagens de programação modernas. Particularmente quando não há bastante tempo e esforço e dinheiro disponível no orçamento para fazer características que as pessoas não querem.
fonte
[switch]
parâmetros de filtro.EQV
. O operador que eu sempre desejei seria "e não", o que promoveria o operador do lado direito antes de negá-lo. Assim,0xABCD12345678ul ~& 0x00200000u
produziria 0xABCD12145678ul em vez de 0x12145678ul.Só posso adivinhar, mas um motivo pode ser que existem soluções alternativas que são bastante simples e legíveis. Vamos considerar o seu exemplo:
Se você precisar de uma expressão, o operador embutido se 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:fonte
if
afirmação é muito, muito mais clara para quase todos.Eiffel tem implicações
Na verdade, tem ainda mais. Tem um número de operadores semi-estritos, bem como estrito.
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á-las e quando usá-las - e também como projetar com elas. Como eles nunca são treinados, nunca pedem isso aos escritores do compilador, e é por isso que o pessoal do compilador não se preocupa em colocar esses mecanismos no compilador. Quando os estudantes de Ciência da Computação e os programadores da Shade-tree começarem a ter uma educação mais abrangente, os compiladores começarão a se atualizar.
Acontece que uma vez que você tenha uma linguagem com esses operadores booleanos e saiba como projetar com eles e usá-los, use-os.
Na Eiffel, o uso da palavra-chave "implica" é bastante proeminente por causa do projeto por contrato, devido à natureza pesada de booleano das asserções de contrato. Existem alguns contratos que só podem ser escritos de forma adequada e eficiente com o operador "implica". Isso então implora o comentário de que idiomas sem contratos são ainda mais sem motivo para examinar, treinar e implementar o uso da implicação.
Acrescente a isso que a maioria dos programadores é "fraca em matemática e lógica" nos diz o restante da história. Mesmo que você tenha muita matemática e lógica em sua educação, quando alguém escolhe uma linguagem que não implementa construções como implicação, então tende a pensar que tais coisas são desnecessárias ou não são úteis. Raramente se questiona a linguagem e entra em uma câmara de eco de: "Bem, o pessoal do compilador não vê a necessidade" e "Bem, os programadores não veem a necessidade" - círculo interminável e vicioso.
Em vez disso, o pessoal do compilador precisa fazer backup da teoria, escrever uma notação de linguagem sugerida ou implícita pela teoria (por exemplo, teoria orientada a objetos), independentemente do que as massas sujas de programadores pensem ou solicitem. A partir daí, professores, professores e outros profissionais precisam treinar habilmente jovens mentes com base na teoria bruta e NÃO em "teoria através da lente da linguagem". Quando isso acontece, as pessoas de repente acordam e percebem o que estão perdendo e o que lhes foi impingido.
Agora - há muita teoria por aí que se disfarça de Orientada a Objetos, mas é apenas OO-através-de-um-vidro-escuro-de-[escolha-seu-idioma]. Não se pode ler a maioria dos livros de "teoria" sobre OO 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. NÃO - ninguém permite que a realidade ensine a si mesmo e depois usa uma notação para descrever o que se observa - isso é chamado de "ciência". Esse outro mash chamado OO baseado em linguagem X é tão distorcido que mal representa a realidade.
Portanto, 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 a realidade da teoria ditar sua própria notação e depois passar daí para a formulação de uma linguagem.
A partir daí, você começará a entender como a implicação e a "implicação" não são apenas úteis, mas elegantes e muito legais!
Tem um bom!
fonte
Python tem um operador de implicação de uma maneira oculta.
O operador menor que ou igual a está sobrecarregado para aceitar valores booleanos. Como resultado, pode-se usá-lo como um operador de implicação.
Prova por exemplo (código Python):
Lembre-se de que a tabela verdade do operador de implicação é:
fonte
f() implies g()
não deve avaliarg()
sef()
éFalse
, mas<=
avaliag()
neste caso.did_all_possible_stuff = x.do_required_stuff() and (x.supports_optional_stuff() <= x.do_optional_stuff())
funcionar.Eiffel tem um operador "implica" e é muito bom para escrever pré e pós-condições. Isso torna o código mais legível, infelizmente, isso nunca foi uma intenção fundamental para a linguagem C e poucas pessoas usavam o eiffel, de modo que a beleza de "implica" como operador não é bem conhecida.
fonte
Para mim, o grande problema com implica ocorre quando a condição inicial é falsa; por exemplo: "Se o sol estiver verde, eu sou um morcego." Verdadeiro!
Na lógica formal, apenas trabalha para atribuir "Verdadeiro" ao valor quando a condição da implicação não é atendida. Mas na programação, isso pode levar a resultados contra-intuitivos e surpreendentes.
Na verdade, acho que o exemplo @Heinzi dá acima:
É muito mais fácil de entender e menos propenso a erros devido ao mal entendimento da lógica.
No contexto dos testes, eu apenas interrompi o momento em que minhas suposições se tornaram falsas:
Então, ao ponto de @Eric Lippert, como programador não sei quando usaria um operador implícito. O comportamento "Falso é verdadeiro" 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 atribui verdadeiro à condição "else", "?" permite que o desenvolvedor atribua isso explicitamente.
Na lógica formal, usar "true" funciona, mas na programação, se a condição for falsa, a melhor resposta é mais como "null" ou "void" ou "skip", ou talvez até false.
Eu acho que alguém teria que argumentar por que "implica" é um operador mais útil do que declarações "?", "If" ou apenas um fluxo regular de programa.
fonte
Raquete tem
implies
. Ele se expande para umaif
expressão.fonte