Scott Gargash schrieb:
I did a little more experimenting, and it's a little stronger than that. You also can't remove a mixin from anything invoked by the active mixin.
in the BEFORE part (this concerns everything that directly on indirectly).
I.e., you can't forward the "mixin delete" to an object of another class. If the mixin to be deleted is present in the call stack, it appears that the mixin can't be deleted. Not that I expected it to work, but it seems worth noting.
if you have a case that goes beyond "do not remove actvive mixins from the before part of active mixin classes"), please send an example.
It looks quite easy to give a reasonable error message, when the currently active mixin class is deleted, it will be more expensive to handle this
problem in
a friendly way.
Is the expense something that would be encountered on every method invocation, or would it only be paid when deleting a mixin?
a simple solution, not costing anything, would be to restart the mixin chain when the active mixin is removed. This would work with your example but might lead to unexpeted cases in other situations and is no big improvement to the current situation.
We have to deal with the following cases when we have e.g. a precedence order M1 M2 M3 M4, and the following happens in the BEFORE part of M2:
a chain is set to: M1 M3 M4 (your case, you want to continue with M3) b chain is set to: M1 M4 defensible M4 c chain is set to: M2 M1 M3 M4 under current semantics, continue with M1 d chain is set to: M4 M2 M3 M1 continue with M3, M4 will never by invoked
The general problem is pretty similar to the "immediate" and "logical" update view in logic languages, where the clause base is modified during the execution of a goal. The logical view says that modifications are ignored during execution and only apply to new invocations (similar to SQL), wheras the immediate view tries to give defensible semantics for the active invocations (what you are trying). It has been a while since i worked on this stuff, but it goes back to Lindholm and Richard O'Keefe (ROK) from 87, */Efficient implementation of a defensible semantics for dynamic Prolog code/* (unfortunately, could not find this fine paper on the net). In essence, this says that one can only get declarative semantics from the logical update view, which is not acceptible for programmers that want to change the dynamic structure, preferring the immediate view, which is more efficiently in terms of memory and computation. Therefore most Prolog Systems implement the dynamic update view.
So, the underlying problem is well known and not a matter of a trivial hack. The situation with xotcl mixins/filters is in some respects more complicated since we are not dealing with adding/removing clauses but we have to deal with reordering, adding or removing items to instance specific precedence chains; we have as well transitive mixin-chains.
Currently, we can even construct loops by reordering the mixins in the BEFORE part, which i consider as a programmers bug.
The most promissing approach not mentioned yet is to develop a c-level implementation of mixin/instmixin/filter/instfilter delete, which simply flags the entry in the chain as deleted.....
cheers -gustaf