Iterators are a fundamental programming abstraction for traversing and modifying elements in containers in mainstream imperative languages such as C++. Iterators provide a uniform access mechanism that hides low-level implementation details of the underlying data structure. However, iterators over mutable containers suffer from well-known hazards including invalidation, aliasing, data races, and subtle side effects. Immutable data structures, as used in functional programming languages, avoid the pitfalls of mutation but rely on a very different programming model based on recursion and higher-order combinators rather than iteration. However, these combinators are not always well-suited to expressing certain algorithms, and recursion can expose implementation details of the underlying data structure. In this paper, we propose persistent iterators -- a new abstraction that reconciles the familiar iterator-based programming style of imperative languages with the semantics of persistent data structures. A persistent iterator snapshots the version of its underlying container at creation, ensuring safety against invalidation and aliasing. Iterator operations operate on the iterator-local copy of the container, giving true value semantics: variables can be rebound to new persistent values while previous versions remain accessible. We implement our approach in the form of LibFPP -- a C++ container library providing persistent vectors, maps, sets, strings, and other abstractions as persistent counterparts to the Standard Template Library (STL). Our evaluation shows that LibFPP retains the expressiveness of iterator-based programming, eliminates iterator-invalidation, and achieves asymptotic complexities comparable to STL implementations. Our design targets use cases where persistence and safety are desired, while allowing developers to retain familiar iterator-based programming patterns.
翻译:迭代器是主流命令式语言(如C++)中遍历和修改容器元素的基础编程抽象。迭代器提供统一的访问机制,隐藏了底层数据结构的实现细节。然而,可变容器的迭代器存在众所周知的缺陷,包括失效、别名化、数据竞争以及细微的副作用。函数式编程语言中使用的不可变数据结构避免了可变性的弊端,但其依赖的编程模型基于递归和高阶组合子,而非迭代。然而,这些组合子并不总能很好地表达某些算法,且递归可能暴露底层数据结构的实现细节。本文提出持久迭代器——一种新的抽象,将命令式语言中熟悉的基于迭代器的编程风格与持久数据结构的语义相协调。持久迭代器在创建时对其底层容器的版本进行快照,从而确保免受失效和别名化问题的影响。迭代器操作基于迭代器持有的容器本地副本进行,实现真正的值语义:变量可重新绑定到新的持久值,而先前版本仍可访问。我们以LibFPP库形式实现了该方法——该C++容器库提供持久向量、映射、集合、字符串及其他抽象,作为标准模板库(Standard Template Library, STL)的持久化对应物。评估表明,LibFPP保留了基于迭代器编程的表达能力,消除了迭代器失效问题,并达到了与STL实现渐近相同的复杂度。我们的设计针对需要持久性和安全性的场景,同时允许开发者保留熟悉的基于迭代器的编程模式。