Speaking about iterators and quirks, there's one in the iterator interface too: The step operation uses `+=, which is fairly logical for the iterator implementor but not for users; the only way to explicitly step an iterator is like this:
iter->`+= (1);
Clumsy syntax, and it invites to make the mistake of using the operator += directly:
iter += 1;
That won't work since it normally copies the iterator instead of changing it destructively. (Remember that a += b is equivalent to a = a + b except that a is evaluated only once. Hence there's no relation between the operator += and the lfun `+=.)
We ought to fix this somehow. I can see two alternatives:
1. Add a global step_iterator function to accompany get_iterator. It'd be used like this
step_iterator (iter, 1);
and do an lfun call to `+= (which would work even if it's static).
Actually, the function could be used to make an lfun call to `+= in any object, so perhaps it should be called "destructive_add" or something like that, but that'd be just as unintuitive in the iterator context as iter->`+=(1).
2. Rename `+= to "step" in the iterator interface, so that one can do
iter->step (1);
instead.
The necessary compatibility goo to cope with iterators that only define `+= is complicated, though: A #pike 7.4 directive in the file where the iterator is defined should be enough. That means that the compiler has to automatically add an alias "step" for `+= in any class that seems to be an iterator. Messy.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-09-04 13:43: Subject: foreach problem
I was bit yesterday by a bug/misfeature in foreach regarding iterators. After getting the index and/or value from the iterator, it increments it before executing the loop code. I.e. the following will throw an error:
String.Iterator iter = String.Iterator ("foo"); foreach (iter; int idx;) if (idx != iter->index()) error ("wtf?\n");
I consider it a bug and intend to change foreach so that the iterator is incremented after the loop instead.
Unfortunately that change can have nasty effects in code that expects foreach to behave like this. I can either change it in 7.5 only and fix some #pike 7.4 compatibility goo, or I can "ignore" the compat issue and fix it in both 7.4 and 7.5. I'm actually inclined to do the latter, under the assumption that there still is very little code that use iterators this way (Grubbas new compiler is the only example I know). If it stays as it is in 7.4 it can be cumbersome to update code to 7.5.
Not sure though if we can get away with pulling a stunt like that this long after the 7.4 release. Does anyone know of more code that depends on this foreach quirk?
/ Martin Stjernholm, Roxen IS