¿Por qué los idiomas no incluyen la implicación como un operador lógico?

59

Puede ser una pregunta extraña, pero ¿por qué no hay implicaciones como operador lógico en muchos idiomas (Java, C, C ++, Python Haskell, aunque como último operador tiene operadores triviales, es trivial agregarlo)? Me parece que las implicaciones lógicas son mucho más claras de escribir (especialmente en afirmaciones o expresiones de tipo afirmación) luego negación con o:

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
}
    
pregunta Maciej Piechotka 18.01.2013 - 13:48

9 respuestas

61

Podría ser útil tener a veces, sin duda. Varios puntos argumentan contra tal operador:

  • Los caracteres - y > son valiosos, tanto de forma aislada como combinada. Muchos idiomas ya los usan para significar otras cosas. (Y muchos no pueden usar conjuntos de caracteres Unicode para su sintaxis).
  • La implicación es muy poco intuitiva, incluso para personas con mentalidad lógica como los programadores. El hecho de que tres de las cuatro entradas de la tabla de verdad sean true sorprende a muchas personas.
  • Todos los demás operadores lógicos son simétricos, lo que haría de -> una excepción a la ortogonalidad.
  • Al mismo tiempo, hay una solución sencilla: usar los operadores ! y || .
  • La implicación se usa mucho menos que la lógica and / or .

Probablemente esta sea la razón por la cual el operador es raro hoy en día. Ciertamente, podría volverse más común, ya que los nuevos lenguajes dinámicos usan Unicode para todo y la sobrecarga del operador vuelve a estar más de moda.

    
respondido por el Kilian Foth 18.01.2013 - 14:00
54

Creo que la respuesta está en los fundamentos matemáticos . La implicación generalmente se considera y define como una operación derivada, no elemental, de álgebras booleanas. Los lenguajes de programación siguen esta convención.

Esta es la Proposición I del Capítulo II de Una investigación de las Leyes del Pensamiento (1854) :

  

Todas las operaciones del lenguaje, como un instrumento de razonamiento, se pueden llevar a cabo mediante un sistema de signos compuesto por los siguientes elementos, a saber:

     

1er. Símbolos literales, como x, y, & c., Que representan las cosas como sujetos de nuestras concepciones.

     

2do. Los signos de operación, como +, -, ×, representan aquellas operaciones de la mente mediante las cuales las concepciones de las cosas se combinan o resuelven para formar nuevas concepciones que involucran los mismos elementos.

     

3er. El signo de identidad, =.

     

Y estos símbolos de la lógica en su uso están sujetos a leyes definidas, en parte de acuerdo con y en parte difieren de las leyes de los símbolos correspondientes en la ciencia del álgebra.

El signo de Boole + representa la misma "operación de la mente" que hoy reconocemos como el "o" booleano y la unión de conjuntos. De manera similar, los signos - y × corresponden a nuestra negación booleana, complemento de un conjunto, ´y´ e intersección de conjuntos booleanos.

    
respondido por el COME FROM 18.01.2013 - 15:03
37

ACTUALIZACIÓN: esta pregunta fue el tema de mi blog en noviembre de 2015 . Gracias por la interesante pregunta!

Visual Basic 6 (y VBScript) tenían operadores Imp y Eqv . Nadie los usó. Ambos fueron removidos en VB.NET; que yo sepa, nadie se quejó.

Trabajé en el equipo del compilador de Visual Basic (como pasante) durante un año completo y nunca noté que VB incluso tenía esos operadores. Si no hubiera sido el tipo que escribía el compilador de VBScript, y por lo tanto tuve que probar sus implementaciones, probablemente no las habría notado. Si el usuario del equipo de compilación no conoce la característica y no la usa, eso le dice algo sobre la popularidad y la utilidad de la característica.

Usted mencionó los lenguajes tipo C No puedo hablar con C o C ++ o Java, pero puedo hablar con C #. Hay una lista de funciones sugeridas por el usuario para C # literalmente más larga que su brazo. Que yo sepa, ningún usuario ha propuesto tal operador al equipo de C #, y he revisado esa lista muchas, muchas veces.

Las características que existen y no se utilizan en un idioma, y que nunca se solicitan en otro son candidatos poco probables para convertirse en lenguajes de programación modernos. Particularmente cuando no hay suficiente tiempo, esfuerzo y dinero disponible en el presupuesto para hacer las funciones que la gente quiere .

    
respondido por el Eric Lippert 20.01.2013 - 01:12
19

Solo puedo adivinarlo, pero una razón podría ser que existen soluciones que son bastante simples y legibles. Consideremos tu ejemplo:

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

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

Si necesita una expresión, se puede usar el operador inline-if disponible en la mayoría de los idiomas (a menudo llamado operador ternario). Por supuesto, esto no es tan elegante como A --> B , pero la cantidad de casos de uso podría no justificar agregar (y mantener) a otro operador:

assert (mode != ECB ? iv != null : true);
    
respondido por el Heinzi 18.01.2013 - 13:57
11

Eiffel tiene implicaciones

En realidad tiene aún más. Tiene una serie de operadores semi-estrictos, así como estrictos.

La razón por la que los programadores no usan tales cosas es porque nunca están capacitados para saber exactamente qué son, cómo usarlos y cuándo usarlos, así como cómo diseñar con ellos. Debido a que nunca están capacitados, nunca lo piden a los escritores del compilador, razón por la cual la gente del compilador no se molesta en poner tales mecanismos en el compilador. Cuando los estudiantes de informática y los programadores de Shade-tree comiencen a recibir una educación más completa, los compiladores comenzarán a ponerse al día.

Resulta que una vez que tienes un lenguaje con dichos operadores booleanos y sabes cómo diseñar con ellos y usarlos, entonces los usas.

En Eiffel, el uso de la palabra clave "implica" es bastante importante debido al diseño por contrato debido a la naturaleza booleana de las aserciones de contrato. Hay algunos contratos que solo se pueden escribir de manera adecuada y eficiente con el operador "implica". Esto luego hace que se comente que los idiomas sin contrato están más lejos sin causa para analizar, capacitar e implementar el uso de la implicación.

Agregue a esto que la mayoría de los programadores son "matemáticos y lógicos débiles" nos dicen el resto de la historia. Incluso si tiene un alto nivel de matemática y lógica en su educación, cuando uno elige un lenguaje que no implementa construcciones tales como implicaciones, entonces uno tiende a pensar que tales cosas son innecesarias o no útiles. Rara vez se cuestiona el lenguaje y se mete en una cámara de eco de: "Bueno, los compiladores no ven la necesidad" y "Bueno, los programadores no ven la necesidad": círculo infinito y vicioso.

En lugar de eso, la gente del compilador necesita hacer una copia de seguridad de la teoría, escribir una notación de lenguaje sugerida o implícita por la teoría (por ejemplo, la teoría orientada a objetos) independientemente de lo que piensen o pidan las masas sucias de programadores. A partir de ahí, los profesores, los maestros y otros profesionales deben capacitar de manera experta a jóvenes fanáticos de la mente basados en la teoría cruda y NO en la "teoría a través del lenguaje". Cuando esto suceda, las personas se despertarán repentinamente y se darán cuenta de lo que se han estado perdiendo y lo que se les ha impuesto.

Ahora mismo, hay tanta teoría que se enmascara como Orientada a Objetos, pero es solo O-O-through-a-glass-darkly-of- [pick-your-language]. Uno no puede leer la mayoría de los libros de "teoría" en O-O porque quieren interpretar lo que es la teoría a través de la lente de algún lenguaje. Totalmente falso e incorrecto. Sería como enseñar la matemática en mi calculadora o mi regla de cálculo. NO: uno permite que la realidad enseñe sobre sí mismo y luego usa una notación para describir lo que uno observa, lo que se denomina "ciencia". Esta otra mezcla llamada O-O-based-on-language-X está tan inclinada que apenas representa la realidad.

Entonces, aléjate del lenguaje, observa la teoría en bruto y comienza de nuevo. No permita que las limitaciones, restricciones y trabajos de pintura de un idioma le digan qué es la teoría. Simplemente deje que la realidad de la teoría dicte su propia notación y luego continúe con la formulación de un lenguaje.

¡A partir de ahí, comenzarás a ver cómo la implicación y "implica" no solo son útiles, sino también elegantes y geniales!

¡Que tengas uno genial!

    
respondido por el Larry 13.05.2014 - 03:28
7

Python tiene un operador de implicación de una manera oculta.

El operador menor a igual está sobrecargado para aceptar valores booleanos. Como resultado, uno puede usarlo como un operador de implicación.

Prueba de ejemplo (código de 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.

Recuerde que la tabla de verdad del operador implicado es:

LEFT RIGHT RESULT
F    F     T
F    T     T
T    F     F
T    T     T
    
respondido por el Mackenzie 15.07.2014 - 10:21
5

Eiffel tiene un operador "implica" y es muy bueno para escribir antes y después de las condiciones. Hace que el código sea más legible, desafortunadamente nunca fue una intención fundamental para el lenguaje como C y muy pocas personas usaron eiffel, por lo que la belleza de "implica" como operador no es bien conocida.

    
respondido por el Lothar 06.11.2013 - 09:45
2

Para mí, el gran problema con implica cuando la condición inicial es falsa; por ejemplo: "Si el sol es verde, entonces soy un murciélago frutero". ¡Cierto!

En la lógica formal, solo funciona asignar "Verdadero" al valor cuando no se cumple la condición de la implicación. Pero en la programación, eso podría llevar a resultados contraintuitivos y sorprendentes.

Realmente creo que el ejemplo que @Heinzi da arriba:

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

Es mucho más fácil de entender y menos propenso a errores debido a una mala interpretación de la lógica.

En el contexto de las pruebas, solo detuve el momento en que mis suposiciones se volvieron falsas:

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

Entonces, para el punto de @Eric Lippert, como programador no sé cuándo usaría un operador implica. El comportamiento de "Falso es verdadero" parece útil en el contexto de la lógica matemática y formal, pero podría llevar a resultados inesperados en la lógica del programa.

...

Nadie ha mencionado el común "?" operador, donde "A? B: verdadero" es lo mismo que "implica". Pero mientras que la lógica formal asigna verdadero a la condición "else", "?" le permite al desarrollador asignar eso explícitamente.

En la lógica formal, el uso de "verdadero" funciona, pero en la programación, si la condición es falsa, entonces la mejor respuesta es más como "nulo" o "vacío" o "saltar", o incluso tal vez falso.

Creo que alguien tendría que argumentar por qué "implica" es un operador más útil que "?", o las declaraciones "if", o simplemente el flujo regular del programa.

    
respondido por el Rob 01.05.2014 - 16:45
1

Racket tiene implies . Se macro-expande a una expresión if .

    
respondido por el Phil 02.05.2014 - 17:11

Lea otras preguntas en las etiquetas