Evaluación de cortocircuito
# Evaluación de cortocircuito

La evaluación de corto-circuito, evaluación mínima, o evaluación McCarthy (por el científico John McCarthy) denota la semántica de algunos operadores booleanos en algunos lenguajes de programación en los cuales el segundo argumento no se ejecuta o evalúa si el primer argumento de la función AND evalúa y el resultado es falso, el valor total tiene que ser falso; y cuando el primer argumento de la función OR evalúa y el resultado es verdadero, el valor total tiene que ser verdadero. En algunos lenguajes de programación, como Lisp, los operadores booleanos usuales son corto-circuito. En otros (Java, Ada), tanto los corto-circuito y los operadores booleanos están disponibles. Para algunos operadores booleanos, como XOR, no le es posible evaluar por corto-circuito, porque ambos operadores están obligados a determinar el resultado.

La expresión de corto-circuito x Sand y (usando Sand para denotar la variedad de corto-circuito) es equivalente a la sentencia condicional if x then y else false; la expresión x Sor y es equivalente a if x then true else y.

Los operadores corto-circuito son estructuras de control en vez de simples operadores aritméticos, al igual que no son strict. ALGOL 68 usó "Proceduring" para lograr operadores y procedimientos de corto-circuito definidos por los usuarios.

En lenguajes aproximados o imprecisos, los cuales tienen más de dos valores de verdad Verdadero y Falso, los operadores corto-circuito podrían devolver la última subexpresión evaluada, de esta manera x Sor y y x Sand y son equivalentes a if x then x else y y if x then y else x respectivamente (sin evaluar x dos veces). Esto es llamado "el último valor" en la tabla de abajo.

En lenguajes que emplean una evaluación perezosa por defecto, como Haskell, todas las funciones son efectivamente de "corto-circuito", y no son necesarios operadores especiales de corto-circuito.

## Soporte en lenguajes comunes de programación

Operadores booleanos en varios lenguajes :

| Lenguaje | Operadores ansiosos | Operadores de corto-circuito | Tipo de resultado |
| - | - | - | - |
| ABAP | none | and, or | $Boolean^1$ |
| Ada, Eiffel | and, or | and then, or else | Boolean |
| ALGOL 68 | and, &, ∧; or, ∨ | andf , orf | Boolean |
| $C^2$ | none | &&, ||, ? | Numeric (&&,||), opnd-dependent (?) |
| $C++^3$ | &, | | &&, ||, ? | Boolean (&&,||), opnd-dependent (?) |
| Go, OCaml, Haskell | none | &&, || | Boolean |
| C#, Java, MATLAB R | &, | | &&, || | Boolean |
| ColdFusion | none | AND, OR, &&, || | Boolean |
| Erlang | and, or | andalso, orelse | Boolean |
| Fortran | .and., .or. | | Boolean |
| JavaScript | none | &&, || | Last value |
| Lisp, Lua, Scheme | none | and, or | Last value |
| Modula-2 | none | AND, OR | Boolean |
| Oberon | none | &, OR | Boolean |
| Pascal | and, $or^4$ | and_then, $or_else^5$ | Boolean |
| Perl, Ruby | &, | | &&, and, ||, or | Last value |
| PHP | none | &&, and, ||, or | Boolean |
| Python | none | and, or | Last value |
| Smalltalk | &, | | and:, or: | Boolean |
| Standard ML | | andalso, orelse | Boolean |
| Visual Basic .NET | And, Or | AndAlso, OrElse | Boolean |
| VB Script, VB Classic, VBA | And, Or | Select Case | Numeric |

$^1ABAP$ en realidad no posee una distinción de los tipos de booleanos. $^2$ C, antes de C99, en realidad no tenía una distinción de los tipos de booleanos; los operadores lógicos devuelven 0 (para Falso) o 1 (para Verdadero). $^3$ Cuando es sobrecargado, los operadores && y || son ansiosos y pueden devolver cualquier tipo. $^4$ ISO Pascal permite pero no requiere corto-circuito. $^5$ ISO-10206 extendió a Pascal el soporte a and_then and or_else.

## Uso común

### Evitando los efectos colaterales de ejecución en las expresiones secundarias

Ejemplo común.

Considere el siguiente ejemplo usando lenguaje Lenguaje C:

En este ejemplo, la evaluación de corto-circuito garantiza que myfunc(b) nunca será llamado. Esto es debido a que la evaluación de a es falso. Esta característica permite la programación de dos constructores. Inicialmente si se revisa la primera subexpresión, sin importar si es necesario un costo computacional y el proceso evaluado es falso, uno puede eliminar el costo computacional en el segundo argumento. Luego permite una construcción donde la primera expresión garantiza una condición sin la cual la segunda expresión pueda causar un error de ejecución run-time error. Ambos están ilustrados en el siguiente fragmento de código C donde una evaluación mínima previene una desferenciación a un apuntador a null y un desbordamiento de memoria.

## Posibles problemas

### Segunda condición sin verificar dirige a un efecto colateral no ejecutado

A pesar de estos beneficios una evaluación mínima puede causar problema para los programadores que no se den cuenta (o se olviden) que está pasando. Por ejemplo, en el código

Si myfunc(b) pretende realizar alguna operación requerida sin tener en cuenta si do_something es ejecutado, tal como la asignación de recursos al sistema, y expressionA es evaluado como Falso, entonces myfunc(b) no se ejecutará lo cual puede causar problemas. Algunos lenguajes de programación tales como Java, tienen dos operadores, uno que emplea la evaluación mínima y el otro que no, para evitar este problema

Problemas con las declaraciones incumplidas de efectos secundarios pueden ser resueltos fácilmente con el estilo de programación adecuada, es decir, no usando efectos colaterales en las declaraciones booleanas, así como usando valores con efectos colaterales en las evaluaciones tiende generalmente a producir un código opaco y propenso a errores.

Desde que las evaluaciones mínimas son parte de las definiciones de las operaciones semánticas y no (opcional) de una optimización, muchos estilos de codificación se basan en él como un constructor condicional conciso, tal como el lenguaje Perl:

### Eficiencia de la codificación

Si ambas expresiones usadas como condiciones son simples variables booleanas, puede ser mucho más rápido de evaluar las dos condiciones usadas en las operaciones booleanes de una vez, como si requiriera un simple ciclo de cálculo, en contraposición a uno o dos ciclos usados en las evaluaciones de los circuitos cortos (dependiendo del valor del primero). La diferencia en términos de eficiencia computacional entre estos dos casos depende fuertemente del compilador y del esquema de optimización utilizado; con la correcta optimización estos serán capaces de ejecutarse a la misma velocidad, así como serán compilados a un código máquina idéntico.

Un corto-circuito puede llevar a errores en predictor de saltos en los modernos unidaded centrales de procesamiento, y reducir dramáticamente el desempeño (un ejemplo claro es un rayo altamente optimizado con el eje de la caja del código de intersección alineado en el trazado de rayos alineado trazado de rayos). Algunas compilaciones pueden detectar tales casos y emitir una codificación más rápida, pero no siempre es posible debido a violaciones de segmento del lenguaje C. Un código altamente optimizado debería emplear otras formas de hacer esto (como el manual de uso del código de máquina).

