2010-04-15 11 views
10

¿Existe un lenguaje de programación que admita la notación encadenada < b < c para ser utilizada en lugar de < by < c en sentencias condicionales?Notación de desigualdad encadenada en lenguajes de programación

Ejemplo:

  1. si (2 < x < 5)
  2. si (2 < x & & x < 5)

Primeros statementlooks mejor para mí, es más fácil de entender y el compilador podría usar la propiedad de transitividad para advertir sobre errores (por ejemplo, 5 < x < 2 daría una advertencia).

Respuesta

5

Icon hace esto, y no es parte de ningún "caso de encadenamiento" hacky especial; es parte del modelo de Icon de evaluación dirigida por objetivos modelo. Cualquier comparación tiene éxito o falla. Si tiene éxito, produce el lado derecho. Por lo tanto, puede escribir

if 0 <= i <= j < n then ... 

y funciona exactamente de la manera que usted esperaría. Pero funciona no solo para las comparaciones sino para cualquier expresión; esto significa que puede escribir sus propias funciones que "encadenan" exactamente de la misma manera. Me encanta este aspecto de Icon y deseo que más idiomas puedan incorporar la evaluación dirigida a objetivos.

N.B. En el artículo de Guido presentando Python en VHLL (mediados de la década de 1990) menciona explícitamente a Icon como fuente de inspiración en el diseño de Python.

+0

Oooh .... brillante. – outis

+0

Veo que también hay soporte experimental en Vala, mira aquí: http://live.gnome.org/Vala/Tutorial#Chained_Relational_Expressions – Davorin

11

Python hace eso.

+0

Tenga una referencia a eso ... Estoy tratando de encontrar documentación sobre él ... – tutuca

+0

@tutuca: Sólo necesitaba esta información, por lo que la referencia está aquí: https://docs.python.org/2/ reference/expressions.html # not-in. Cita: Formalmente, si _a, b, c, ..., y, z_ son expresiones y _op1, op2, ..., opN_ son operadores de comparación, luego 'a op1 b op2 c ... y opN z' es equivalente a 'a op1 b y b op2 c y ... y opN z', excepto que cada expresión se evalúa como máximo una vez. – collapsinghrung

2

Esto suena como una simple solicitud (y claramente es lo suficientemente simple que python lo implementó) pero no es necesariamente tan fácil de usar. De hecho, abre la posibilidad de que se produzcan muchos errores.

En concreto, cada vez que utilice funciones (o propiedades en el caso de C#, Compuestos absorbentes para Java)

Así

public int GetX() 
{ 
    return 4; 
} 

(2 < GetX() < 5); 

(2 < GetX() > 5); 

(5 < GetX() < 2); 

parece que sería muy simple. Pero los problemas ocurren si GetX() tiene efectos secundarios.

private int val = 10; 

public int GetCountdown() 
{ 
    return val--; 
} 

(2 < GetCountdown() < 5); 

(2 < GetCountdown() > 5); 

(5 < GetCountdown() < 2); 

En esta situación, ¿"GetCountdown()" disminuye dos o solo una vez? ¿El atajo "encadenado si alguna vez" alguna vez?

Considere las últimas declaraciones, que aproximadamente evalúa (en inglés) "Es 5 menos que algún valor que es menos de 2) que debería ser imposible, pero dependiendo de la implementación y los efectos secundarios, es posible que alguna función (Random.NextInt()) podría pasar ambas pruebas.

Por lo tanto, por ese motivo, se requeriría que cada uno de los elementos solo se evalúe una vez, el guardado en una variable local para la siguiente comparación. entonces usted entra en problemas de acceso directo.

public int GetOne() 
{ 
    return 1; 
} 

public int GetVar() 
{ 
    return -1; 
} 

(GetOne() < GetVar() < GetDBVal() < GetUserInput()) 

En general, usted querría comprobar primero las constantes y las variables b antes de hacer un hit de base de datos. Pero si dijéramos (como dijimos antes) que todos los valores deben guardarse en variables locales con anticipación, esto significa que podría estar llamando a un hit de la base de datos, y pidiendo información al usuario aunque "GetVar()" sea - 1, y entonces la primera comparación falla)

Como dije antes, claramente Python permite esta sintaxis, por lo que es claramente posible. Pero, independientemente de las implicaciones técnicas que he expuesto (todas ellas son fáciles de diseñar) significa que su código es menos claro porque la siguiente persona que lo lea no sabe si ha considerado todos o no esta. Mientras que, if(x > 2 && x < 5) { } me parece claro, sé lo que hace, y sé lo que el codificador pretende.

+5

Un buen argumento en contra de las funciones con efectos secundarios. –

+0

Bueno, "GetDataFromDB()" no tendría un "efecto secundario" per se, excepto que tomaría tiempo que sería mejor evitarlo. El propósito de esto era simplemente ilustrar que encadenar comparaciones podría tener consecuencias no deseadas porque no es tan claro como las comparaciones atómicas. – DevinB

+0

La lección que debemos sacar de esto es usar siempre funciones con efectos secundarios (considero que GetDataFromDB() tiene un efecto secundario: toca el mundo externo) como ** declaraciones **. Use solo código libre de efectos secundarios como ** expresiones **. –

Cuestiones relacionadas