verdad tipos tabla superlativo superioridad sobrecarga secuencial relacion programacion oraciones operadores multiplicador lenguaje instancias ingles igualdad igual grado estructura estrictamente ejemplos desigualdad decodificador comparativos comparativo comparacion codigos asignacion arreglo adjetivos language-design boolean-operations

language design - tipos - ¿Por qué la mayoría de los lenguajes de programación tienen operadores de comparación de igualdad binaria?



tipos de comparativos (24)

En los idiomas naturales, diríamos que "un poco de color es un color primario si el color es rojo, azul o amarillo".

En cada lenguaje de programación que he visto, eso se traduce en algo como:

isPrimaryColor = someColor == "Red" or someColor == "Blue" or someColor == "Yellow"

¿Por qué no hay una sintaxis que coincida más con la oración en inglés? Después de todo, no diría que "algún color es un color primario si ese color es rojo, o ese color es azul, o ese color es amarillo".

Me doy cuenta simplemente de que isPrimaryColor = someColor == ("Red" or "Blue" or "Yellow") porque en lugar de Red Blue y Yellow podrían ser una declaración booleana, en cuyo caso se aplica la lógica booleana, pero ¿qué pasa con algo como:

isPrimaryColor = someColor ( == "Red" or == "Blue" or == "Yellow")

Como una ventaja adicional que la sintaxis permitiría una mayor flexibilidad, digamos que desea ver si un número está entre 1 y 100 o 1000 y 2000, podría decir:

someNumber ((>= 1 and <=100) or (>=1000 and <=2000))

Editar:

Respuestas muy interesantes, y punto en que debo aprender más idiomas. Después de leer las respuestas, estoy de acuerdo en que para una comparación estrictamente equitativa, algo similar a establecer membresía es una forma clara y concisa de expresar lo mismo (para idiomas que tienen soporte de idioma para listas o conjuntos concisos en línea y pruebas de membresía)

Uno de los problemas que surgieron es que si el valor a comparar es el resultado de un cálculo costoso, una variable temporal tendría que crearse (bueno, debería). El otro problema es que puede haber diferentes evaluaciones que deben verificarse, como "el resultado de un cálculo costoso debe ser primo y entre 200 y 300"

Estos escenarios también están cubiertos por lenguajes más funcionales (aunque dependiendo del idioma puede no ser más conciso), o en realidad cualquier lenguaje que pueda tomar una función como parámetro. Por ejemplo, el ejemplo anterior podría ser

MeetsRequirements(GetCalculatedValue(), f(x):x > 200, f(x):x < 300, IsPrime)


Rubí

Contenido en la lista:

irb(main):023:0> %w{red green blue}.include? "red" => true irb(main):024:0> %w{red green blue}.include? "black" => false

Rango Numérico:

irb(main):008:0> def is_valid_num(x) irb(main):009:1> case x irb(main):010:2> when 1..100, 1000..2000 then true irb(main):011:2> else false irb(main):012:2> end irb(main):013:1> end => nil irb(main):014:0> is_valid_num(1) => true irb(main):015:0> is_valid_num(100) => true irb(main):016:0> is_valid_num(101) => false irb(main):017:0> is_valid_num(1050) => true


Cª#:

if ("A".IsIn("A", "B", "C")) { } if (myColor.IsIn(colors)) { }

Usando estas extensiones:

public static class ObjectExtenstions { public static bool IsIn(this object obj, params object [] list) { foreach (var item in list) { if (obj == item) { return true; } } return false; } public static bool IsIn<T>(this T obj, ICollection<T> list) { return list.Contains(obj); } public static bool IsIn<T>(this T obj, IEnumerable<T> list) { foreach (var item in list) { if (obj == item) { return true; } } return false; } }


COBOL utiliza 88 niveles para implementar valores con nombre, grupos de valores con nombre y rangos de valores con nombre.

Por ejemplo:

01 COLOUR PIC X(10). 88 IS-PRIMARY-COLOUR VALUE ''Red'', ''Blue'', ''Yellow''. ... MOVE ''Blue'' TO COLOUR IF IS-PRIMARY-COLOUR DISPLAY ''This is a primary colour'' END-IF

Las pruebas de rango se cubren de la siguiente manera:

01 SOME-NUMBER PIC S9(4) BINARY. 88 IS-LESS-THAN-ZERO VALUE -9999 THRU -1. 88 IS-ZERO VALUE ZERO. 88 IS-GREATER-THAN-ZERO VALUE 1 THRU 9999. ... MOVE +358 TO SOME-NUMBER EVALUATE TRUE WHEN IS-LESS-THAN-ZERO DISPLAY ''Negative Number'' WHEN IS-ZERO DISPLAY ''Zero'' WHEN IS-GREATER-THAN-ZERO DISPLAY ''Positive Number'' WHEN OTHER DISPLAY ''How the heck did this happen!'' END-EVALUATE

Supongo que todo esto sucedió porque se suponía que COBOL debía emular el inglés hasta cierto punto.


Como matemático, diría que el color es primario si y solo si es miembro del conjunto {rojo, verde, azul} de los colores primarios.

Y así es exactamente como se podría decir en Delphi:

isPrimary := Colour in [clRed, clGreen, clBlue]

De hecho, empleo esta técnica muy a menudo. La última vez fue hace tres días. Implementando mi propio intérprete de lenguaje de scripting, escribí

const LOOPS = [pntRepeat, pntDoWhile, pntFor];

y luego, en unas pocas líneas,

if Nodes[x].Type in LOOPS then

La parte filosófica de la pregunta

@supercat, etc. ("En cuanto a por qué nadie ha hecho eso, no lo sé"):

Probablemente porque los diseñadores de lenguajes de programación son matemáticos (o, al menos, matemáticamente inclinados). Si un matemático necesita declarar la igualdad de dos objetos, diría

X = Y,

naturalmente. Pero si X puede ser una de varias cosas A, B, C, ..., entonces ella definirá un conjunto S = {A, B, C, ...} de estas cosas y escribirá

X ∈ S.

De hecho, es extremadamente común que ustedes (matemáticos) escriban X ∈ S , donde S es el conjunto

S = {x ∈ D; P(x)}

de objetos en algún universo D que tiene la propiedad P, en lugar de escribir P(X) . Por ejemplo, en lugar de decir "x es un número real positivo" o "PositiveReal (x)", uno diría que x ∈ ℝ⁺ .


Creo que la mayoría de la gente considera algo como

isPrimaryColor = ["Red", "Blue", "Yellow"].contains(someColor)

para ser suficientemente claro que no necesitan sintaxis adicional para esto.


Dos posibilidades

Java

boolean isPrimary = Arrays.asList("red", "blue", "yellow").contains(someColor);

Pitón

a = 1500 if 1 < a < 10 or 1000 < a < 2000: print "In range"


En Haskell, es fácil definir una función para hacer esto:

matches x ps = foldl (||) False $ map (/ p -> p x) ps

Esta función toma una lista de valores de predicados (de tipo a -> Bool ) y devuelve True si alguno de los predicados coincide con el valor.

Esto te permite algo como esto:

isMammal m = m `matches` [(=="Dog"), (=="Cat"), (=="Human")]

Lo bueno es que no tiene que ser solo igualdad, puedes usar cualquier cosa con el tipo correcto:

isAnimal a = a `matches` [isMammal, (=="Fish"), (=="Bird")]


En Perl 6 puedes hacer esto con junctions :

if $color eq ''Red''|''Blue''|''Green'' { doit() }

Alternativamente, puede hacerlo con el operador de coincidencia inteligente ( ~~ ). Lo siguiente equivale aproximadamente a python''s if value in list: sintaxis, excepto que ~~ hace mucho más en otros contextos.

if ($color ~~ qw/Red Blue Green/) { doit() }

Los parens también lo hacen válido perl 5 (> = 5.10); en Perl 6 son opcionales.


En Python puedes decir ...

isPrimaryColor = someColor in (''Red'', ''Blue'', ''Yellow'')

... lo cual me parece más legible que su sintaxis (== "Red" or == "Blue") . Hay algunas razones para agregar soporte de sintaxis para una característica de idioma:

  • Eficiencia : no hay razón aquí, ya que no hay mejora de velocidad.
  • Funcionalidad : Tampoco es una preocupación; no hay nada que puedas hacer en la nueva sintaxis que no puedas hacer en la antigua.
  • Legibilidad : la mayoría de los idiomas manejan el caso en el que está comprobando la igualdad de valores múltiples muy bien. En otros casos (por ejemplo, someNumber (> 1 and < 10) ) puede ser más útil, pero incluso así no le compra mucho (y Python le permite decir 1 < someNumber < 10 , lo que es aún más claro).

Así que no está claro que el cambio propuesto sea particularmente útil.


En python puedes hacer algo como esto:

color = "green" if color in ["red", "green", "blue"]: print ''Yay''

Se llama in operador, que comprueba la pertenencia al conjunto.


Es porque los lenguajes de programación están influenciados por las matemáticas, la lógica y la teoría de conjuntos en particular. El álgebra booleana define los operadores, ∨ de una manera que no funcionan como el lenguaje natural hablado. Tu ejemplo sería escrito como:

Let p(x) be unary relation which holds if and only if x is a primary color p(x) ⇔ r(x) ∨ g(x) ∨ b(x) or p(x) ⇔ (x=red) ∨ (x=green) ∨ (x=blue)

Como ves, es bastante similar a la notación que se usaría en el lenguaje de programación. A medida que las matemáticas proporcionan sólidos fundamentos teóricos, los lenguajes de programación se basan en las matemáticas en lugar del lenguaje natural, lo que siempre deja mucho espacio para la interpretación.

EDITAR: La declaración anterior podría simplificarse utilizando la notación de conjuntos:

p(x) ⇔ x ∈ {red, green, blue}

y de hecho, algunos lenguajes de programación, especialmente Pascal, incluían el conjunto, por lo que podría escribir:

type color = (red, green, blue, yellow, cyan, magenta, black, white); function is_primary (x : color) : boolean; begin is_primary := x in [red, green, blue] end

Pero los conjuntos como característica de lenguaje no se prendieron.

PD. Lo siento por mi imperfecto inglés.


Esto puede ser replicado en Lua con alguna magia metatable: D

local function operator(func) return setmetatable({}, {__sub = function(a, _) return setmetatable({a}, {__sub = function(self, b) return f(self[1], b) end} ) end} ) end local smartOr = operator(function(a, b) for i = 1, #b do if a == b[i] then return true end end return false end) local isPrimaryColor = someColor -smartOr- {"Red", "Blue", "Either"}

Nota: puede cambiar el nombre de -smartOr- a algo como -isEither- para que sea aún MÁS legible.


Hasta ahora, nadie ha mencionado SQL. Tiene lo que estás sugiriendo:

SELECT employee_id FROM employee WHERE hire_date BETWEEN ''2009-01-01'' AND ''2010-01-01'' -- range of values AND employment_type IN (''C'', ''S'', ''H'', ''T'') -- list of values


La pregunta es razonable y no consideraría el cambio como un azúcar sintáctico. Si el valor que se está comparando es el resultado del cálculo, sería mejor decir:

if (someComplicatedExpression ?== 1 : 2 : 3 : 5)

que decir

int temp; temp = someComplicatedExpression; if (temp == 1 || temp == 2 || temp == 3 || temp == 5)

particularmente si no había otra necesidad para la variable temporal en cuestión. Un compilador moderno probablemente podría reconocer la corta vida útil de ''temp'' y optimizarla en un registro, y probablemente podría reconocer el patrón "ver si la variable es una de ciertas constantes", pero no habría ningún daño en permitir que un programador guardar el compilador el problema. La sintaxis indicada no se compilaría en ningún compilador existente, pero no creo que sea más ambigua que (a + b >> c + d) cuyo comportamiento se define en la especificación del idioma.

En cuanto a por qué nadie ha hecho eso, no lo sé.


Los últimos ejemplos que brinde son efectivamente azúcar sintáctica, tendrían que evaluar el mismo código que el formulario más largo que, en algún momento, el código ejecutado debe comparar su valor con cada una de las condiciones.

La sintaxis de comparación de matrices, dada en varias formas aquí, más cercana y sospecho que hay otros idiomas que se acercan aún más.

El principal problema para hacer que la sintaxis se acerque más al lenguaje natural es que este último no solo es ambiguo, sino que es terriblemente ambiguo. Incluso manteniendo la ambigüedad al mínimo, aún conseguimos introducir errores en nuestras aplicaciones, ¿te imaginas cómo sería si programaras en inglés natural?


Los idiomas en las computadoras se comparan como binarios porque son todos para una máquina que usa binarios para representar información. Fueron diseñados utilizando una lógica similar y con objetivos muy similares. El idioma inglés no fue diseñado de forma lógica, diseñado para describir algoritmos, y los cerebros humanos (el hardware en el que se ejecuta) no se basan en binarios. Son herramientas diseñadas para diferentes tareas.


Me acordé de cuando comencé a aprender programación, en Basic, y en un momento escribí

if X=3 OR 4

Intenté esto como lo estás describiendo, si X es 3 o 4. El compilador lo interpretó como:

if (X=3) OR (4)

Es decir, si X = 3 es verdadero, o si 4 es verdadero. Como definió cualquier cosa que no fuera cero como verdadera, 4 es verdadera, cualquier cosa o VERDADERA es verdadera, y la expresión siempre fue verdadera. Pasé mucho tiempo pensando en eso.

No pretendo que esto agregue nada a la discusión. Solo pensé que podría ser una anécdota ligeramente divertida.


Mi conjetura sería que los idiomas están diseñados por la fuerza del hábito. Los primeros idiomas solo habrían tenido operadores de comparación binarios porque son más simples de implementar. Todos se acostumbraron a decir ( x > 0 and x < y ) hasta que los diseñadores de idiomas nunca se molestaron en apoyar la forma común en matemáticas, ( 0 < x < y ).

En la mayoría de los idiomas, un operador de comparación devuelve un tipo booleano. En el caso de 0 < x < y , si esto se interpreta como (0 < x) < y no tendría sentido, ya que < no tiene sentido comparar booleanos. Por lo tanto, un nuevo compilador podría interpretar 0 < x < y como tmp:=x, 0 < tmp && tmp < y sin romper la compatibilidad con versiones anteriores. En el caso de x == y == z , sin embargo, si las variables ya son booleanas, es ambiguo si esto significa x == y && y == z o (x == y) == z .

En C #, utilizo el siguiente método de extensión para que pueda escribir un poco de someColor.IsOneOf("Red", "Blue", "Yellow" ). Es menos eficiente que la comparación directa (lo que con la matriz, el bucle, las llamadas de Equals() y el boxeo si T es un tipo de valor), pero seguro que es conveniente.

public static bool IsOneOf<T>(this T value, params T[] set) { object value2 = value; for (int i = 0; i < set.Length; i++) if (set[i].Equals(value2)) return true; return false; }


No veo una respuesta de Objective-C todavía. Aqui hay uno:

BOOL isPRimaryColour = [[NSSet setWithObjects: @"red", @"green", @"blue", nil] containsObject: someColour];


Python en realidad te da la habilidad de hacer lo último bastante bien:

>>> x=5 >>> (1<x<1000 or 2000<x<3000) True


Solo para agregar a ejemplos de idiomas

Esquema

(define (isPrimaryColor color) (cond ((member color ''(red blue yellow)) #t) (else #f))) (define (someNumberTest x) (cond ((or (and (>= x 1) (<= x 100)) (and (>= x 10000 (<= x 2000))) #t) (else #f)))



Tendrás que bajar un poco la capa de abstracción para descubrir la razón. Las instrucciones de comparación / salto de x86 son binarias (ya que se pueden calcular fácilmente en unos pocos ciclos de reloj), y así han sido las cosas.

Si quieres, muchos idiomas ofrecen una abstracción para eso. En PHP, por ejemplo, podrías usar:

$isPrimaryColor = in_array($someColor, array(''Red'', ''White'', ''Blue''));


Icon tiene la facilidad que usted describe.

if y < (x | 5) then write("y=", y)

Me gusta más ese aspecto del icono.