¿Cuándo es mala la evaluación de cortocircuito?

12

Para ser un poco más claro, afirmaré que he pasado mucho tiempo con diferentes idiomas. Pero hasta ahora ha sido o lo usará todo el tiempo o no lo soportará en absoluto.

Ahora el trabajo me tiene comenzando en proyectos que requieren VB.net y veo que lo proporciona en ambos sentidos en términos de AND y ANDALSO . El primero no tiene corto circuito, y el segundo sí.

¿Entonces esto me lleva a preguntarme por qué? Como configurarlo de esta manera parece implicar que surgiría con bastante frecuencia que uno querría cambiar de modo. Pero no puedo pensar en ninguna situación en la que sería malo usar Short Circuit .

Sé que esto podría entrar en una opción más, así que si necesito poner esto en otro lugar, solo díganme dónde.

Aunque espero que haya al menos una respuesta oficial, en cuanto a por qué tener ambas opciones sería mejor que siempre hacer Cortocircuito , cuando esté disponible.

Kit Ramos
fuente

Respuestas:

5

Algunos términos en una expresión lógica pueden tener efectos secundarios. A veces es necesario asegurarse de que todos los efectos secundarios sucedan en el orden establecido, y que ninguno se omita y es el resultado de la evaluación el que guía la lógica:

if not (PushAirPlane(thrust) and TurnAirplane(vector)), SimulateCrash(severity)

En otros casos, no desea evaluar ninguno de los términos restantes si una evaluación anterior devuelve falso.

if IsAirborne() and not (PushAirPlane(thrust) and TurnAirplane(vector)), SimulateCrash(severity)

Algunos habrán / habrán argumentado que confiar en el comportamiento de cortocircuito en el segundo ejemplo es una mala forma, pero eso está entrando en el estilo de codificación y los sistemas de creencias. Hay muchos fragmentos de código muy buenos en el mundo que se basan en casi todas las características que proporciona un lenguaje, y así son las cosas.

ANDALSO de VB es crujiente y parece ser un intento de hacer que la práctica sea más aceptable.

Como JimmyJames señala en su respuesta, puede haber implicaciones de rendimiento medibles en torno a la evaluación de cortocircuito. Los lenguajes que no proporcionan el mecanismo, siempre evalúan todos los términos de la expresión, mientras que los que sí lo hacen, pueden generar declaraciones de ramificación adicionales. De cualquier manera, mucho depende de la cantidad de pasos de procesamiento necesarios para evaluar cada uno de los términos y también de las arquitecturas del compilador y la CPU. Normalmente no le importarían tales cosas hasta que tenga un cuello de botella medido en el código y necesite averiguar cómo aliviarlo. Cualquier regla de hacer o no con respecto a permitir la evaluación de cortocircuito en su código tendría aproximadamente la misma probabilidad de causar un código más lento y la optimización temprana puede ser una pérdida total de tiempo, por lo que siempre mida y luego optimice.

jwdonahue
fuente
44
Aunque de hecho es correcto, no es un gran diseño.
Robert Harvey
2
@RobertHarvey, no puedo escribir un sistema de control que no tenga efectos secundarios y no puedo controlar el sistema correctamente si no reacciono a los resultados. En otras palabras, supéralo;).
jwdonahue
77
No, pero puede asignar los resultados de esas funciones de efectos secundarios a variables booleanas, verificar esas variables en su ifcondición y aún cortocircuito. Estoy de acuerdo en que es, de alguna manera, una distinción estilística, pero tiene la virtud de hacer que las cosas sean claras como el cristal.
Robert Harvey,
3
@jwdonahue Está bien usar "palabras grandes" si el riesgo de confusión es bajo. El riesgo de confusión y la falta de matices particulares de un bloque de código como este es extremadamente alto y puede ser catastrófico para la lógica. Nunca es bueno hacer que el desarrollador de lectura piense mucho.
jpmc26
55
"Algunos términos en una expresión lógica pueden tener efectos secundarios". Si bien esta declaración inicial es correcta, creo que esta respuesta falla al no señalar que confiar en los efectos secundarios es malo . Mucho peor, de hecho, que confiar en la evaluación de cortocircuito para evitar evaluaciones espurias. Lo que sugiere esta respuesta puede ser una mala forma.
Aroth
20

Aparentemente, su pregunta no se trata de que el cortocircuito sea bueno o malo en general, sino de por qué VB.NET proporciona operadores con y sin él. Con esto en mente, la respuesta a

¿Cuándo es mala la evaluación de cortocircuito?

es simplemente: cuando viola la compatibilidad con versiones anteriores .

Bien, ahora puede decir que VB.NET no es muy compatible con versiones anteriores de VB6 o VBA, sin embargo, al menos ciertas partes del lenguaje lo son. La decisión de Microsoft de mantener la antigua semántica AND y OR (sin cortocircuito) hizo que fuera menos probable que ocurriera una gran categoría de errores al portar viejos programas VB a VB.NET.

Por otro lado, los diseñadores de lenguaje VB.NET probablemente compartieron su opinión sobre los cortocircuitos como algo bueno. Cuando recuerdo correctamente, las primeras versiones preliminares de VB.NET proporcionaron operadores AND u OR con cortocircuito, pero los comentarios del desarrollador deben haber sido tan malos que MS retiró esta decisión antes de que apareciera VB.NET 1.0. Entonces, los diseñadores decidieron implementarlo en términos de nuevas palabras clave ANDALSOy ORELSEcomo una compensación entre la compatibilidad y la utilidad hacia atrás.

En mi humilde opinión, fue una buena decisión. Tuve que portar varios programas antiguos en la última década, y no tener que hacer un análisis de impacto pesado para cada expresión lógica, incluyendo AND y / u OR (juego de palabras) hizo que esa tarea fuera mucho más fácil y más económica. Por otro lado, cada vez que tengo que escribir una nueva expresión lógica en VB.NET, mi elección predeterminada para los operadores son las formas de cortocircuito, que es a lo que estoy acostumbrado desde C, C ++, C #, etc., y permite yo escribir varios modismos en forma más concisa (incluso si ANDALSO necesita 4 caracteres más para escribir).

Si no está convencido, le recomiendo leer el excelente artículo de Joel Spolsky sobre los auriculares marcianos , que explica por qué las primeras decisiones de diseño en el desarrollo de software no se pueden revocar fácilmente después de que el componente o lenguaje o API en juego haya alcanzado una base de usuarios de cierto tamaño .

Doc Brown
fuente
Ok, esto califica como una diatriba y el enlace a Martian Headsets no parece estar relacionado en absoluto.
jwdonahue
66
@jwdonahue: No tengo idea de por qué piensas que esto es una diatriba, todo lo contrario. Y el artículo sobre Martian Headsets trata sobre por qué algunas decisiones de diseño en el desarrollo de software tomadas hace varias décadas no se pueden revocar fácilmente después de que el componente o lenguaje o API en juego haya alcanzado una base de usuarios de cierto tamaño. ¿No es la analogía realmente tan difícil de entender? VB6 fue muy popular en el pasado, y estoy seguro de que todavía cientos de miles de empresas en el mundo tienen aplicaciones de misión crítica que se ejecutan en VB6 o VBA.
Doc Brown
No entiendo cómo encaja realmente el artículo sobre "los marcianos". Lo que es necesario para garantizar la interoperabilidad entre X e Y (por ejemplo, tuercas y tornillos) es tener estándares separados para X e Y, de modo que una tuerca en el peor de los casos acomode un tornillo ligeramente peor que el especificado, y viceversa. Uno debe tratar de escribir las especificaciones para evitar hacer que las tuercas o tornillos sean innecesariamente caros, o tener una cantidad innecesaria de pendiente entre tuercas y tornillos, pero la especificación de ambas mitades por separado hace posible garantizar la interoperabilidad de manera mucho más confiable que tratar de tener una especificación servir a ambos lados
supercat
3
@supercat: se trata de tener billones de tuercas (o líneas de código VB6) existentes y en uso, y ahora los tornillos (o en este caso el compilador VB) serán reemplazados por una generación más nueva. Si las tuercas existentes se ajustan solo a pernos no métricos, no es económico hacer que los pernos más nuevos solo sean métricos.
Doc Brown
tl; dr: VB es un dialecto de BASIC, un lenguaje que data de 1964, y en BASIC la Andoperación no hace corto circuito, ni lo hace en SQL (1974), ni FORTRAN (1956), ni Pascal (1970).
Ben
3

¿Cuándo es mala la evaluación de cortocircuito?

Se vuelven malas , tan pronto como comienza a confiar en los efectos secundarios de las expresiones que espera ejecutar en la evaluación de un resultado general booleano.

πάντα ῥεῖ
fuente
1

Advertencia : Esto es un poco esotérico, ya que en casi todos los casos, los desarrolladores no deberían preocuparse por eso. Pero ... puede haber un impacto en el rendimiento debido a la evaluación condicional, ya que crea ramificaciones en la ejecución. Una operación sin cortocircuito no se ramifica y es más predecible.

La razón por la que esto rara vez importa es que el costo suele ser pequeño y también suele ser mayor que el costo de evaluar la segunda (o tercera, etc.) condición. Esto solo importará en rutinas computacionalmente costosas cuando se requiera un alto rendimiento y aún así podría no importar.

JimmyJames
fuente
Creo que hasta ahora solo puedes optimizar una declaración lógica, eventualmente tienes que tomar ramas.
jwdonahue
@jwdonahue No entiendo tu punto. Lo siento.
JimmyJames
Estamos hablando de lógica combinatoria aquí. Evaluación de cortocircuito o no, tiene uno o más términos que deben evaluarse según el resultado de un término anterior. Por lo tanto, la ramificación está involucrada.
jwdonahue
1
@jwdonahue Por supuesto, pero cada cortocircuito es una rama adicional. En ciertos escenarios, ejecutar dos expresiones (por ejemplo) es más rápido que verificar el resultado de la primera antes de ejecutar la segunda, incluso si a menudo ocurre que la segunda es irrelevante. De nuevo, esto rara vez es importante. El caso que alguien me planteó para esto fue para cosas como la multiplicación de matrices en las que tienes muchas evaluaciones simples.
JimmyJames
1
Actualicé mi respuesta con crédito para usted.
jwdonahue
0

Pascal no definió si AND y OR utilizan la evaluación de cortocircuito o no, dándote lo peor de ambos mundos.

C y C ++ tienen operaciones bit a bit & y | que en la práctica le brindan operaciones sin cortocircuito. Y los compiladores son libres de evaluar lo que quieran si no hay una diferencia observable.

gnasher729
fuente
@Dupuplicator: Como se señaló, Pascal no definió si AND / OR usa la evaluación de cortocircuito. Eso significa "no saber".
supercat