Marc Battyani wrote:
code-movement [possible changes]
Those parts (prologue/epilog/var bindings) are under- (and badly) specified in LOOP and implementations differ on this. So let's keep it in a sane way.
I find it underspecified in Iterate as well. I want to change that state :-)
E.g. Andreas' with-*-iterator based in-hashtable and in-package has very different initialization behaviour from the old ones (see below).
It occured to me that there's another issue: iterate-pg may not work as expected, for similar reasons.
(iter (with foo = connection) (with x on-relation foo connection bar)) #) ;won't work
Reason: WITH-PG-TRANSACTION is move outside the whole Iterate form, thus foo and bar get evaluated before any other thing in Iterate(!)
My current belief is that the following order would be a better match: (let (...) (wrappers: unwind-protect and with-pg-transaction, in order of apperance (block (tagbody #))))
Currently, it's (wrappers: with-package-iterator, with-hashtable-iterator, with-pg-transaction (let # (unwind-protect (block (tagbody #)))))
Therefore (iter (with table = (foo)) (for (k v) in-hashtable table)) used to work with the old maphash based Iterate, but fails since Andreas' changes in 2004. I think this is also a result of underspecification of Iterate, together with a quite complex package and lots of feature interactions (initialization time, generators, declarations, top-level only clauses, support for PREVIOUS etc.)
As a result, simple examples (e.g. the testsuite) work, but subtle forms fail. I'm going to change that as well (1.5). At the present, one can think of two forms of body wrappers: a) around the whole body (e.g. current with-*-iterator) b) around BLOCK, but inside LET (e.g. unwind-protect) I think I'm going to provide for only variant b, as shown above.
Subtle interactions between unwind-protect clauses can still happen. I think that's a sign of limitations of Iterates design. All in all, packages needing a code-walker are not that great (they appear like a can of worms, e.g. Screamer was well, with some forms that work as expected and others that fail surprisingly (cf. primordial in Screamer). There's quite some truth when Bruno Haible expresses that CL somehow fails to be its own extension language.
LOOP's weakness is also its strength: not needing a code walker, being limited to top-level forms, having a grammar so its transformation does not require macroexpand and remains syntactic.
Regards, Jörg Höhle