Programming languages continue to evolve to facilitate specification by programmers as well as efficient execution. In the early days of computer languages, low-level machine code was prevalent. With machine code, a computer program or instructions comprising a computer program were written with machine languages or assembly languages and executed by hardware (e.g., microprocessor). These languages provided a means to control computing hardware efficiently but were very difficult for programmers to understand and develop sophisticated logic. Subsequently, languages were introduced that provided various layers of abstraction. Accordingly, programmers could write programs at a higher level with a higher-level source language, which could then be converted via a compiler or interpreter to the lower level machine language understood by the hardware. Further advances in programming have provided additional layers of abstraction to allow more advanced programming logic to be specified much quicker then ever before. However, these advances do not come without a processing cost.
Compilers and/or interpreters bear the burden of translating high-level logic into executable machine code. In general, compilers and/or interpreters are components that receive a program specified in a source programming language (e.g., C, C#, Visual Basic, Java . . . ) and convert the logic provided thereby to machine language executable by a hardware device. However, the conversion need not be done verbatim. In fact, conventional compilers can analyze the source code and generate or inject very efficient code. Programmers write code that sets forth a logical flow of operations that is intuitive and easy for humans to understand. Yet, such code, as written, is often inefficient for a computer to execute. Compilers can identify inefficiencies and improve program performance at the hardware level by eliminating unnecessary operations and/or rearranging the execution of instructions while still preserving the intended functionality. In this manner, programmers can create robust and efficient software programs.
One of the layers of abstraction provided by high level programming languages pertains to iterators and generators. Most programming languages support base types for collections of base elements (e.g., array of integers, string of characters) as well as user-defined types for arbitrary collections of elements (e.g., enumerations of elements) and more complex data structures such as trees, stacks, queues, and linked lists. A software construct (e.g., object) that represents a collection of elements often provides methods related to the collection including insertion, deletion, searching, sorting, and testing for collection membership. Iterators provide or encapsulate functionality for traversing or enumerating elements or items in a collection. In essence, iterators can be employed to access elements from collections (e.g., list, array, tree . . . ) one at a time. The iterator construct can thus be utilized to simplify the process of iterating over elements.
By way of example, suppose a class in a programming language wants to support iteration using a foreach loop construct. A programmer could specify the following:    List1 list1=. . . ;    Foreach (object obj in list1)            {DoSomething(obj);}Here, “List1” is a class for a collection of elements of type “object” and “list1” is an instantiation of the class “List1.” A foreach loop is specified such that a routine DoSomething is executed on or iterated over each object in “list1.” A compiler, such as a C# compiler, can expand the foreach code into the following code that uses a while loop construct.        
Enumerator e = list1.GetEnumerator( );While (e.MoveNext( )) {Object obj = e.Current;DoSomething(obj);}The List1 data structure on whose instance the iteration occurs must support the GetEnumerator( ) function (as well as the MoveNext Method and Current property) in order for the foreach loop to execute properly. The creator of the List1 data structure implements the GetEnumerator function, which returns an Enumerator object. The Enumerator object also implements the Current property (indicates the current object in the List1) and the MoveNext method (for moving the next object in the List1, if there is one). The object maintains its internal state to allow moving to the next item each time around the loop. This is a form of an internal state machine that keeps track of an iterator's position in the data structure.
These kinds of modifications to specified code are desirable as they vastly improve program execution performance.