Hello, I have a conceptual/style question here.
In C++ (and presumably some other languages), there is a concept called "iterator invalidation". The basic idea is that while iterating a structure, changes to the structure could break iteration, leading to a loss of memory safety. It is also undefined behavior to use an "old" iterator, or one that was created before the structure was updated. A while ago I switched my former C++ projects to Rust and found that the language's borrowing rules protect against this error: // In stdlib, oversimplified, generics removed for simplicity: mod vec { struct Vec { } struct Iter<'a> { vector: &'a Vec, //... } impl Iterator for Iter { //... } impl Vec { pub fn iter<'a>(&'a self) -> Iter<'a> { Iter { vector: self, } } } } // Test let mut v = vec![1, 2, 3]; for i in &v { if *i == 2 { v.clear(); // Yay, compile time error, no unsafety. } } So, in Nim, it is possible to modify a structure you are iterating. For some simple structures, though, this works fine. For example, the following does not crash. var s = @[1, 2, 3] for i in s: echo s if i == 2: s.setLen(0) # iteration stops, no unsafety. However, this seems fairly delicate - the iterator must be implemented in a way that expects the seq to be modified. Perhaps incidentally, this is true. So my question is: * Should I/can I ever count on an `iterator` in Nim to handle the structure being changed during iteration? * Is there any way to leverage Nim's type system or metaprogramming capabilities to create an `iterator` that forbids modifying the structure?