Введение
Оценка короткого замыкания, минимальная оценка или оценка Маккарти (в честь Джона Маккарти) — это семантика некоторых логических операторов в некоторых языках программирования, при которой второй аргумент выполняется или вычисляется только в том случае, если первого аргумента недостаточно для определения значения выражения: когда первый аргумент функции И (AND) вычисляется как ложь, общее значение должно быть ложным; и когда первый аргумент функции ИЛИ (OR) вычисляется как истина, общее значение должно быть истинным. В языках программирования с ленивыми вычислениями (Lisp, Perl, Haskell) обычные логические операторы используют короткое замыкание. В других (Ada, Java, Delphi) доступны как операторы с коротким замыканием, так и стандартные логические операторы. Для некоторых логических операций, таких как исключающее ИЛИ (XOR), короткое замыкание невозможно, поскольку для определения результата всегда требуются оба операнда. Операторы короткого замыкания, по сути, являются конструкциями управления, а не простыми арифметическими операторами, поскольку они не являются строгими. В императивных языках (в частности, C и C++), где важны побочные эффекты, операторы короткого замыкания вводят точку последовательности: они полностью вычисляют первый аргумент, включая любые побочные эффекты, прежде чем (возможно) обрабатывать второй аргумент. ALGOL 68 использовал процедурный подход для реализации определяемых пользователем операторов и процедур короткого замыкания. Использование операторов короткого замыкания подвергалось критике как проблематичное:
Short circuit evaluation, minimal evaluation, or McCarthy evaluation (after John McCarthy) is the semantics of some Boolean operators in some programming languages in which the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression: when the first argument of the AND function evaluates to false, the overall value must be false; and when the first argument of the OR function evaluates to true, the overall value must be true. In programming languages with lazy evaluation (Lisp, Perl, Haskell), the usual Boolean operators short circuit. In others (Ada, Java, Delphi), both short circuit and standard Boolean operators are available. For some Boolean operations, like exclusive or (XOR), it is impossible to short circuit, because both operands are always needed to determine a result. Short circuit operators are, in effect, control structures rather than simple arithmetic operators, as they are not strict. In imperative language terms (notably C and C++), where side effects are important, short circuit operators introduce a sequence point: they completely evaluate the first argument, including any side effects, before (optionally) processing the second argument. ALGOL 68 used proceduring to achieve user defined short circuit operators and procedures. The use of short circuit operators has been criticized as problematic:
Определение
В любом языке программирования, реализующем короткое замыкание, выражение x и y эквивалентно условному выражению if x then y else x, а выражение x или y эквивалентно if x then x else y. В любом случае, x вычисляется только один раз. Обобщенное определение, приведенное выше, учитывает языки со слабой типизацией, которые имеют более двух значений истинности, отличных от True и False, где операторы короткого замыкания могут возвращать последнее вычисленное подвыражение. Это называется "последним значением" в таблице ниже. Для языков со строгой типизацией выражение упрощается до if x then y else false и if x then true else y соответственно, в случае булевых значений.
Формализация
Логика короткого замыкания, с побочными эффектами или без них, была формализована на основе условного выражения Хоара. Как следствие, операторы без короткого замыкания могут быть определены через логику короткого замыкания так, чтобы иметь ту же последовательность вычислений.
Снижение эффективности из-за ограничения оптимизации
Краткое замыкание может приводить к ошибкам в предсказании переходов на современных центральных процессорах (ЦП) и существенно снижать производительность. Ярким примером является высокооптимизированный код для вычисления пересечений лучей с ориентированными по осям прямоугольными областями в трассировке лучей. Некоторые компиляторы способны обнаруживать подобные ситуации и генерировать более быстрый код, однако семантика языка программирования может ограничивать возможности такой оптимизации. Примером компилятора, не способного оптимизировать в таких случаях, является виртуальная машина Hotspot (VM) Java по состоянию на 2012 год.