Here's a new version of the Lists-as-arrays patch. It's rebased up to HEAD, and I also realized that I could fix the problem with multiple evaluation of the List arguments of foreach etc. by using structure assignment. So that gets rid of a large chunk of the semantic gotchas that were in the previous patch. You still have to be careful about code that deletes list entries within a foreach() over the list --- but nearly all such code is using list_delete_cell, which means you'll have to touch it anyway because of the API change for that function.
Previously, the typical logic for deletion-within-a-loop involved either advancing or not advancing a "prev" pointer that was used with list_delete_cell. The way I've recoded that here changes those loops to use an integer list index that gets incremented or not. Now, it turns out that the new formulation of foreach() is really strictly equivalent to for (int pos = 0; pos < list_length(list); pos++) { whatever-type item = list_nth(list, pos); ... } which means that it could cope fine with deletion of the current list element if we were to provide some supported way of not incrementing the list index counter. That is, instead of code that looks more or less like this: for (int pos = 0; pos < list_length(list); pos++) { whatever-type item = list_nth(list, pos); ... if (delete_cur) { list = list_delete_nth_cell(list, pos); pos--; /* keep loop in sync with deletion */ } } we could write, say: foreach(lc, list) { whatever-type item = lfirst(lc); ... if (delete_cur) { list = list_delete_cell(list, lc); foreach_backup(lc); /* keep loop in sync with deletion */ } } which is the same thing under the hood. I'm not quite sure if that way is better or not. It's more magical than explicitly manipulating a list index, but it's also shorter and therefore less subject to typos. regards, tom lane
reimplement-List-as-array-4.patch.gz
Description: reimplement-List-as-array-4.patch.gz