Minimal evaluation
Encyclopedia
Short-circuit evaluation, minimal evaluation, or McCarthy evaluation denotes the semantics of some Boolean operators in some programming language
s in which the second argument is only executed or evaluated if the first argument does not suffice to determine the value of the expression: when the first argument of the
, Ada
), both short-circuit and standard Boolean operators are available. For some Boolean operations, like XOR, it is not possible to short-circuit, because both operands are always required to determine the result.
The short-circuit expression
Short-circuit operators are, in effect, control structures rather than simple arithmetic operators, as they are not strict
. ALGOL 68
used "proceduring" to achieve user defined short-circuit operators & procedures.
In loosely-typed languages which have more than the two truth-values
In languages that use lazy evaluation
by default (like Haskell
), all functions are effectively "short-circuit", and special short-circuit operators are unnecessary.
1 ABAP does not actually have a distinct boolean type.
2 C, before C99
, did not actually have a distinct boolean type; logical operators returned 0 (for false) or 1 (for true).
3 ISO Pascal allows but does not require short-circuiting.
4 ISO-10206 Extended Pascal supports
Consider the following example using C language
:
In this example, short-circuit evaluation guarantees that
if
, have two operators, one that employs minimal evaluation and one that does not, to avoid this problem.
Problems with unperformed side effect statements can be easily solved with proper programming style, i.e. not using side effects in boolean statements, as using values with side effects in evaluations tends to generally make the code opaque and error-prone.
Since minimal evaluation is part of an operator's semantic definition and not an (optional) optimization, many coding styles rely on it as a succinct (if idiomatic) conditional construct, such as these Perl idioms:
scheme used; with proper optimization they will execute at the same speed, as they will get compiled to identical machine code.
Short-circuiting can lead to errors in branch prediction on modern processors, and dramatically reduce performance (a notable example is highly optimized ray with axis aligned box intersection code in ray tracing
). Some compilers can detect such cases and emit faster code, but it is not always possible due to possible violations of the C standard. Highly optimized code should use other ways for doing this (like manual usage of assembly code).
Programming language
A programming language is an artificial language designed to communicate instructions to a machine, particularly a computer. Programming languages can be used to create programs that control the behavior of a machine and/or to express algorithms precisely....
s in which the second argument is only executed or evaluated 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 some programming languages (Lisp), the usual Boolean operators are short-circuit. In others (JavaJava (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
, Ada
Ada (programming language)
Ada is a structured, statically typed, imperative, wide-spectrum, and object-oriented high-level computer programming language, extended from Pascal and other languages...
), both short-circuit and standard Boolean operators are available. For some Boolean operations, like XOR, it is not possible to short-circuit, because both operands are always required to determine the result.
The short-circuit expression
x Sand y
(using Sand
to denote the short-circuit variety) is equivalent to the conditional expression if x then y else false
; the expression x Sor y
is equivalent to if x then true else y
.Short-circuit operators are, in effect, control structures rather than simple arithmetic operators, as they are not strict
Strict function
A strict function in the denotational semantics of programming languages is a function f where f\left = \perp. The entity \perp, called bottom, denotes an expression which does not return a normal value, either because it loops endlessly or because it aborts due to an error such as division by...
. ALGOL 68
ALGOL 68
ALGOL 68 isan imperative computerprogramming language that was conceived as a successor to theALGOL 60 programming language, designed with the goal of a...
used "proceduring" to achieve user defined short-circuit operators & procedures.
In loosely-typed languages which have more than the two truth-values
True
and False
, short-circuit operators may return the last evaluated subexpression, so that x Sor y
and x Sand y
are actually equivalent to if x then x else y
and if x then y else x
respectively (without actually evaluating x
twice). This is called "Last value" in the table below.In languages that use lazy evaluation
Lazy evaluation
In programming language theory, lazy evaluation or call-by-need is an evaluation strategy which delays the evaluation of an expression until the value of this is actually required and which also avoids repeated evaluations...
by default (like Haskell
Haskell (programming language)
Haskell is a standardized, general-purpose purely functional programming language, with non-strict semantics and strong static typing. It is named after logician Haskell Curry. In Haskell, "a function is a first-class citizen" of the programming language. As a functional programming language, the...
), all functions are effectively "short-circuit", and special short-circuit operators are unnecessary.
Support in common programming languages
Language | Eager operators | Short-circuit operators | Result type | ||
---|---|---|---|---|---|
ABAP ABAP ABAP , is a high-level programming language created by the German software company SAP... |
none | and , or |
Boolean1 | ||
Ada Ada (programming language) Ada is a structured, statically typed, imperative, wide-spectrum, and object-oriented high-level computer programming language, extended from Pascal and other languages... , Eiffel Eiffel (programming language) Eiffel is an ISO-standardized, object-oriented programming language designed by Bertrand Meyer and Eiffel Software. The design of the language is closely connected with the Eiffel programming method... |
and , or |
and then , or else |
Boolean | ||
ALGOL 68 ALGOL 68 ALGOL 68 isan imperative computerprogramming language that was conceived as a successor to theALGOL 60 programming language, designed with the goal of a... |
and , & , ∧ ; or , ∨ | Boolean | |||
C C (programming language) C is a general-purpose computer programming language developed between 1969 and 1973 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system.... 2 |
none | && ,
|
,
|
Numeric (&& ,
|
), opnd-dependent ( ) |
C++ C++ C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell... |
&,
|
&& ,
|
,
|
Boolean (&& ,
|
), opnd-dependent ( ) |
Go Go (programming language) Go is a compiled, garbage-collected, concurrent programming language developed by Google Inc.The initial design of Go was started in September 2007 by Robert Griesemer, Rob Pike, and Ken Thompson. Go was officially announced in November 2009. In May 2010, Rob Pike publicly stated that Go was being... , Objective Caml Objective Caml OCaml , originally known as Objective Caml, is the main implementation of the Caml programming language, created by Xavier Leroy, Jérôme Vouillon, Damien Doligez, Didier Rémy and others in 1996... , Haskell Haskell (programming language) Haskell is a standardized, general-purpose purely functional programming language, with non-strict semantics and strong static typing. It is named after logician Haskell Curry. In Haskell, "a function is a first-class citizen" of the programming language. As a functional programming language, the... |
none | && ,
|
Boolean | ||
C#, Java Java (programming language) Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities... , MATLAB MATLAB MATLAB is a numerical computing environment and fourth-generation programming language. Developed by MathWorks, MATLAB allows matrix manipulations, plotting of functions and data, implementation of algorithms, creation of user interfaces, and interfacing with programs written in other languages,... R R (programming language) R is a programming language and software environment for statistical computing and graphics. The R language is widely used among statisticians for developing statistical software, and R is widely used for statistical software development and data analysis.... |
& ,
|
&& ,
|
Boolean | ||
ColdFusion ColdFusion In computing, ColdFusion is the name of a commercial rapid application development platform invented by Jeremy and JJ Allaire in 1995. ColdFusion was originally designed to make it easier to connect simple HTML pages to a database, by version 2 it had... |
none | AND , OR , && ,
|
Boolean | ||
Erlang | and , or |
andalso , orelse |
Boolean | ||
Fortran Fortran Fortran is a general-purpose, procedural, imperative programming language that is especially suited to numeric computation and scientific computing... |
.and. , .or. |
Boolean | |||
JavaScript JavaScript JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. It is a multi-paradigm language, supporting object-oriented, imperative, and functional programming styles.... |
none | && ,
|
Last value | ||
Lisp, Lua, Scheme | none | and , or |
Last value | ||
Modula-2 | none | AND , OR |
Boolean | ||
Oberon Oberon (programming language) Oberon is a programming language created in 1986 by Professor Niklaus Wirth and his associates at ETH Zurich in Switzerland. It was developed as part of the implementation of the Oberon operating system... |
none | & , OR |
Boolean | ||
Pascal Pascal (programming language) Pascal is an influential imperative and procedural programming language, designed in 1968/9 and published in 1970 by Niklaus Wirth as a small and efficient language intended to encourage good programming practices using structured programming and data structuring.A derivative known as Object Pascal... |
and , or 3 |
and_then , or_else 4 |
Boolean | ||
Perl Perl Perl is a high-level, general-purpose, interpreted, dynamic programming language. Perl was originally developed by Larry Wall in 1987 as a general-purpose Unix scripting language to make report processing easier. Since then, it has undergone many changes and revisions and become widely popular... , Ruby Ruby (programming language) Ruby is a dynamic, reflective, general-purpose object-oriented programming language that combines syntax inspired by Perl with Smalltalk-like features. Ruby originated in Japan during the mid-1990s and was first developed and designed by Yukihiro "Matz" Matsumoto... |
& ,
|
&& , and ,
|
, or |
Last value | |
PHP PHP PHP is a general-purpose server-side scripting language originally designed for web development to produce dynamic web pages. For this purpose, PHP code is embedded into the HTML source document and interpreted by a web server with a PHP processor module, which generates the web page document... |
none | && , and ,
|
, or |
Boolean | |
Python Python (programming language) Python is a general-purpose, high-level programming language whose design philosophy emphasizes code readability. Python claims to "[combine] remarkable power with very clear syntax", and its standard library is large and comprehensive... |
none | and , or |
Last value | ||
Smalltalk Smalltalk Smalltalk is an object-oriented, dynamically typed, reflective programming language. Smalltalk was created as the language to underpin the "new world" of computing exemplified by "human–computer symbiosis." It was designed and created in part for educational use, more so for constructionist... |
& ,
|
and: , or: |
Boolean | ||
Standard ML Standard ML Standard ML is a general-purpose, modular, functional programming language with compile-time type checking and type inference. It is popular among compiler writers and programming language researchers, as well as in the development of theorem provers.SML is a modern descendant of the ML... |
andalso , orelse |
Boolean | |||
Visual Basic .NET Visual Basic .NET Visual Basic .NET , is an object-oriented computer programming language that can be viewed as an evolution of the classic Visual Basic , which is implemented on the .NET Framework... |
And , Or |
AndAlso , OrElse |
Boolean | ||
VB Script VBScript VBScript is an Active Scripting language developed by Microsoft that is modeled on Visual Basic. It is designed as a “lightweight” language with a fast interpreter for use in a wide variety of Microsoft environments... , VB Classic Visual Basic Visual Basic is the third-generation event-driven programming language and integrated development environment from Microsoft for its COM programming model... , VBA Visual Basic for Applications Visual Basic for Applications is an implementation of Microsoft's event-driven programming language Visual Basic 6 and its associated integrated development environment , which are built into most Microsoft Office applications... |
And , Or |
Select Case |
Numeric |
1 ABAP does not actually have a distinct boolean type.
2 C, before C99
C99
C99 is a modern dialect of the C programming language. It extends the previous version with new linguistic and library features, and helps implementations make better use of available computer hardware and compiler technology.-History:...
, did not actually have a distinct boolean type; logical operators returned 0 (for false) or 1 (for true).
3 ISO Pascal allows but does not require short-circuiting.
4 ISO-10206 Extended Pascal supports
and_then
and or_else
.Avoiding the execution of second expression's side effects
Usual example.Consider the following example using C language
C (programming language)
C is a general-purpose computer programming language developed between 1969 and 1973 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system....
:
In this example, short-circuit evaluation guarantees that
myfunc(b)
is never called. This is because a
evaluates to false. This feature permits two useful programming constructs. Firstly, if the first sub-expression checks whether an expensive computation is needed and the check evaluates to false, one can eliminate expensive computation in the second argument. Secondly, it permits a construct where the first expression guarantees a condition without which the second expression may cause a run-time error. Both are illustrated in the following C snippet where minimal evaluation prevents both null pointer dereference and excess memory fetches:Untested second condition leads to unperformed side effect
Despite these benefits, minimal evaluation may cause problems for programmers who do not realize (or forget) it is happening. For example, in the codeif
myfunc(b)
is supposed to perform some required operation regardless of whether do_something
is executed, such as allocating system resources, and expressionA
evaluates as false, then myfunc(b)
will not execute, which could cause problems. Some programming languages, such as JavaJava (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
, have two operators, one that employs minimal evaluation and one that does not, to avoid this problem.
Problems with unperformed side effect statements can be easily solved with proper programming style, i.e. not using side effects in boolean statements, as using values with side effects in evaluations tends to generally make the code opaque and error-prone.
Since minimal evaluation is part of an operator's semantic definition and not an (optional) optimization, many coding styles rely on it as a succinct (if idiomatic) conditional construct, such as these Perl idioms:
Code efficiency
If both expressions used as conditions are simple boolean variables, it can be actually faster to evaluate both conditions used in boolean operation at once, as it always requires a single calculation cycle, as opposed to one or two cycles used in short-circuit evaluation (depending on the value of the first). The difference in terms of computing efficiency between these two cases depends heavily on compiler and optimizationCompiler optimization
Compiler optimization is the process of tuning the output of a compiler to minimize or maximize some attributes of an executable computer program. The most common requirement is to minimize the time taken to execute a program; a less common one is to minimize the amount of memory occupied...
scheme used; with proper optimization they will execute at the same speed, as they will get compiled to identical machine code.
Short-circuiting can lead to errors in branch prediction on modern processors, and dramatically reduce performance (a notable example is highly optimized ray with axis aligned box intersection code in ray tracing
Ray tracing (physics)
In physics, ray tracing is a method for calculating the path of waves or particles through a system with regions of varying propagation velocity, absorption characteristics, and reflecting surfaces. Under these circumstances, wavefronts may bend, change direction, or reflect off surfaces,...
). Some compilers can detect such cases and emit faster code, but it is not always possible due to possible violations of the C standard. Highly optimized code should use other ways for doing this (like manual usage of assembly code).