Comment 3 for bug 515807

Revision history for this message
Faré (fahree) wrote :

I think delegating the PERFORM methods is disgusting and defeats the whole dependency model of ASDF. The correct was of delegating an operation is to customize COMPONENT-DEPENDS-ON, so it does the right thing. In the case of LOAD-OP, this right thing could be a a :LOAD-OP-SHOULD initarg to CL-SOURCE-FILE, or some other specialization of COMPONENT-DEPENDS-ON ((O LOAD-OP) (C ...)).

Note that this delegation through COMPONENT-DEPENDS-ON used to be impossible with ASDF 1 and up to ASDF 2.26 due to TRAVERSE systematically propagating all operations downward the component tree. But happily ASDF 2.27 fixed that deep conceptual bug and now it is both possible and desirable.

That said, we should be careful about how to treat "don't compile" files on ECL and other implementations with a compile-and-link model rather than a load-and-dump model. On such implementations, shall we fall back to compiling, or should we link an object for a file that contains a single (LOAD-FROM-STRING #.(READ-FILE-STRING "foo.lisp")) form?

As for the benefits of the delegation model, an important one is decoupling the strategy used by a required system from the strategy used by the requiring system: requiring systems shouldn't have to know the proper strategy for each and every of their direct and indirect required systems, as they currently do. Instead, each system author, who knows best about his system (or should), should be the one to pick the most appropriate strategy for his system. At the same time, there should be sensible implementation-dependent defaults, i.e. system-wide LOAD-FASL-OP on ECL and compile-and-link implementations vs LOAD-OP on load-and-dump implementations; and the end-user should be able to override this default and/or individual system strategies, and if you want to enforce a compile-and-link model like XCVB does, you might for a system-wide LOAD-FASL-OP everywhere.

As for copying slots of OPERATION, that's a tricky topic indeed.

ASDF 1 used to have this ugly (MAKE-SUB-OPERATION o c dep-o dep-c) horror to copy these properties. With ASDF 2.27, I have much simplified it into a (FIND-OPERATION o sub-o) analog to FIND-COMPONENT that preserves the properties; FIND-OPERATION in turn calls a hash-consing MAKE-OPERATION variant of MAKE-INSTANCE for operations using the *OPERATIONS* cache, which is already a much cleaner model.

Most importantly, though, ASDF 3 inherits from ASDF 1 a crucial problem with respect to operations and their slots: COMPONENT-OPERATION-TIME drops all slot information and considers that an operation has been done if any operation of the same type has been done before. This essentially means that slots are supposed not to matter at all as to the semantics of the operation.

Going forward to ASDF 3, this means that either operation slots should be entirely deprecated (my preferred solution so far), or that we should be strict about only storing hash-cons'ed operations as keys in the COMPONENT-OPERATION-TIMES tables. e.g. operations would have a hidden slot "canonical version" which when initialized links to the canonical version for use in such table, and we should then have a protocol for canonicalizing the initarg list. Ouch.

In practice, several systems in the wild use operation slots to carry important build information (SLIME and GBBopen come to mind). At the same time, these systems do it in a way that would work fine if you moved the slots to the components instead of the operation — otherwise these systems would be utterly broken already. But we have to fix these client systems before we may fix ASDF.