External iterator give you an iterator to step over 1:

for (Iterator iter = list.iterator(); iter.hasNext(); ) {
  Object obj = iter.next();
  // Operate on obj
}

Instead, internal iterator require you to pass a callback to run over a collection 1:

list.foreach(elem => /* do something */)

External iterator is the primary paradigm in C++ and Rust.

Pros and Cons

External iterator gives user more flexibility and explicit control on how to use the iterator. 2 On the other hand, they are often not linking-friendly and requires to inline tons-of library code to be efficient. 3 4

Internal iterator are often easier to implement. For languages that support generators, we can implement external iterator using a convenient syntax as if we are implementing internal iterator.

  • Iterators and Traversables
    • It is hard to have a bulk operation sharing an external iterator API and that is why the author want to distinguish “iterator” and “traversable”
  • pull parser vs push parser - can be seen an instance of this problem
  • generators - can be used to implement external iterators with a convenient syntax

Footnotes

  1. java - External Iterator vs Internal Iterator - Stack Overflow 2

  2. Neal Gafter’s blog: Internal Versus External Iterators

  3. optimization - Why would external iteration require lots of code inlining relative to internal iteration? - Programming Language Design and Implementation Stack Exchange

  4. graydon2 | The Rust I Wanted Had No Future