This article does not cite any sources. (November 2017) (Learn how and when to remove this template message)
In computer programming, eager evaluation, also known as strict evaluation or greedy evaluation, is the evaluation strategy used by most traditional programming languages. In eager evaluation, an expression is evaluated as soon as it is bound to a variable. An opposite alternative to eager evaluation is lazy evaluation, where expressions are evaluated only when a dependent expression is evaluated depending upon a defined evaluation strategy.
The effects of eager evaluation include:
- Code that is easily understandable in terms of execution order that does not potentially change its behaviour based on a change of execution context.
- An easier debug process compared to other evaluation strategies due to the above.
- Responsibility for code performance is however shifted towards the programmer, thus requiring a careful code optimisation process.
Imperative programming languages, where the order of execution is implicitly defined by the structure of the source code, almost always use eager evaluation in order to avoid unexpected behaviour that can occur in certain contexts from out-of-order execution (e.g. when using multithreaded software, concurrent execution of code, etc.). This unexpected behaviour can result in data races, atomicity violations, and other potentially unwanted and hard to control bugs and effects.
Many modern compilers are capable of re-ordering execution to better optimize processor resources and can often eliminate unnecessary expressions from being executed entirely, if it can be determined that the results of the expressions are not visible to the rest of the program. This however should not divert the flow of a compiled program away from the evaluation strategy defined by the programming language that the compiled code is written in, with the notable exception of potential bugs introduced by the compiler. To avoid this problem, most (if not all) modern high-level languages provide constructs to allow the programmer to direct the compiler with regards to its own optimisations. As an example, using the block-level construct lock in C# allows the programmer to define a code block that is to be executed in the same order as it was defined in the source code, effectively barring the compiler from performing any re-order operations on that code block.