Hello folks,
I would like to found out whether subclassing operations is really practical. The operation hierarchy built-in within the asdf.lisp source file is actually of two-level depth.
Has anybody ever defined an operation subclass and specialize methods on it? -- Sincerely, Dmitriy Ivanov lisp.ystok.ru
On Wed, Mar 21, 2012 at 01:53, Dmitriy Ivanov divanov11@gmail.com wrote:
Hello folks,
I would like to found out whether subclassing operations is really practical. The operation hierarchy built-in within the asdf.lisp source file is actually of two-level depth.
Has anybody ever defined an operation subclass and specialize methods on it?
There's stuff in asdf-ecl.lisp you might like to read, some of which could be ported to other lisps (e.g. via FASL concatenation and linking of any additional corresponding .a or .so)
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org "To speak algebraically, Mr. M. is execrable, but Mr. G. is (x+1)ecrable." — Edgar Alan Poe
Fare wrote on Wed, 21 Mar 2012 04:41:53 -0400 12:41:
F> There's stuff in asdf-ecl.lisp you might like to read, F> some of which could be ported to other lisps F> (e.g. via FASL concatenation and linking of any additional F> corresponding .a or .so)
Thanks, I see.
What about traverse? Has anybody specialized it? Is possible that two actions on the same component and operation type to be pushed into the plan? I mean two pairs (c . o1) and (c . o2), where o1 and o2 are instances of the same class, maybe with different slot values. -- Sincerely, Dmitriy Ivanov lisp.ystok.ru
On 3/21/12 Mar 21 -4:54 AM, Dmitriy Ivanov wrote:
Fare wrote on Wed, 21 Mar 2012 04:41:53 -0400 12:41:
F> There's stuff in asdf-ecl.lisp you might like to read, F> some of which could be ported to other lisps F> (e.g. via FASL concatenation and linking of any additional F> corresponding .a or .so)
Thanks, I see.
What about traverse? Has anybody specialized it? Is possible that two actions on the same component and operation type to be pushed into the plan? I mean two pairs (c . o1) and (c . o2), where o1 and o2 are instances of the same class, maybe with different slot values. -- Sincerely, Dmitriy Ivanov lisp.ystok.ru
I tried to do some operation specialization and found that actually it didn't work very well. The reason is in make-sub-operation --- it's very hard to get operations to propagate upstream in a way that might seem obvious: If you have a sub-type of LOAD-OP, you'd most likely want to get that sub-type on the dependencies, but this won't happen without a really substantial amount of effort rewriting depends-on, etc.
Adding entirely new operations works fine, but I have not found a comfortable way to refine existing operations. AFAICT the easiest way to get that effect is to drop new properties onto existing operation types. those properties DO get passed into the dependencies.
HtH, r
Robert Goldman wrote on Wed, 21 Mar 2012 13:32:03 -0500 22:32:
RG>> Is possible that two actions on the same component and operation RG>> type to be pushed into the plan? I mean two pairs (c . o1) and RG>> (c . o2), where o1 and o2 are instances of the same class, maybe RG>> with different slot values.
RG> I tried to do some operation specialization and found that actually RG> it didn't work very well. The reason is in make-sub-operation --- RG> it's very hard to get operations to propagate upstream in a way RG> that might seem obvious: If you have a sub-type of LOAD-OP, you'd most RG> likely want to get that sub-type on the dependencies, but this RG> won't happen without a really substantial amount of effort RG> rewriting depends-on, etc.
One approach could be making make-sub-operation generic though this sounds like an overkill.
RG> Adding entirely new operations works fine, but I have not found a RG> comfortable way to refine existing operations. AFAICT the easiest RG> way to get that effect is to drop new properties onto existing RG> operation types. those properties DO get passed into the RG> dependencies.
An object-oriented basis for handling operations is a bright idea. But it makes many things too complicated and gives no answer to theoretical problems like the above (are (c . o1) and (c . o2) the same action?). I wonder if it provides much benefit in practice.
It seems that using keyword designators like :compile-op, :load-op and the like and methods with the eql specializers would be enough to many applications. And accompanying all the methods with an additional parameter to pass operation properties (or make them accept key arguments). That is the way some old defsystem libraries are doing.
Another question I have got is the relationship between ASDF and LispWorks defsystem rules. LW definitions are quite obvious.
:caused-by If any of dependee actions are already in the current plan (as a result of other rules executing successfully, or as a result of default system behavior), they trigger successful execution of this rule, i.e. the operation on the target component.
:requires The actions that need to be performed before the rule can execute successfully. This is a list of operation-component descriptions that should be planned before the action on the target component.
In my understanding, ASDF :in-order-to is equivalent to :caused-by, and :do-first is equivalent :requires. Is this correct? -- Sincerely, Dmitriy Ivanov lisp.ystok.ru
On Thu, Mar 22, 2012 at 02:05, Dmitriy Ivanov divanov11@gmail.com wrote:
An object-oriented basis for handling operations is a bright idea. But it makes many things too complicated and gives no answer to theoretical problems like the above (are (c . o1) and (c . o2) the same action?). I wonder if it provides much benefit in practice.
CL evolved before programming language people started insisting on clean semantics. When each and every CONS is stateful, not to mention objects, the meaning of "the same" becomes moot. See the classic hbaker essay on equality.
It seems that using keyword designators like :compile-op, :load-op and the like and methods with the eql specializers would be enough to many applications. And accompanying all the methods with an additional parameter to pass operation properties (or make them accept key arguments). That is the way some old defsystem libraries are doing.
I have read about them, but I have no working experience with old defsystem libraries.
Another question I have got is the relationship between ASDF and LispWorks defsystem rules. LW definitions are quite obvious.
:caused-by If any of dependee actions are already in the current plan (as a result of other rules executing successfully, or as a result of default system behavior), they trigger successful execution of this rule, i.e. the operation on the target component.
:requires The actions that need to be performed before the rule can execute successfully. This is a list of operation-component descriptions that should be planned before the action on the target component.
In my understanding, ASDF :in-order-to is equivalent to :caused-by, and :do-first is equivalent :requires. Is this correct?
Sounds about right.
I would even rename the ASDF ones to match the LispWorks name, if I were sure to fix all the references (Are there any beyond ASDF and POIU?).
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Schemer: "Buddha is small, clean, and serious." Lispnik: "Buddha is big, has hairy armpits, and laughs." — Nikodemus Siivola
Fare wrote on Thu, 22 Mar 2012 03:37:18 -0400 11:37:
F>> LW definitions are quite obvious. F>> :caused-by... F>> :requires... F> F> I would even rename the ASDF ones to match the LispWorks name, F> if I were sure to fix all the references (Are there any beyond ASDF F> and POIU?).
Then do not forget to - rename component-depends-on to operation-caused-by and - add generic operation-requires :-) -- Sincerely, Dmitriy Ivanov lisp.ystok.ru
On 3/22/12 Mar 22 -2:37 AM, Faré wrote:
On Thu, Mar 22, 2012 at 02:05, Dmitriy Ivanov divanov11@gmail.com wrote:
Another question I have got is the relationship between ASDF and LispWorks defsystem rules. LW definitions are quite obvious.
:caused-by If any of dependee actions are already in the current plan (as a result of other rules executing successfully, or as a result of default system behavior), they trigger successful execution of this rule, i.e. the operation on the target component.
:requires The actions that need to be performed before the rule can execute successfully. This is a list of operation-component descriptions that should be planned before the action on the target component.
In my understanding, ASDF :in-order-to is equivalent to :caused-by, and :do-first is equivalent :requires. Is this correct?
Sounds about right.
I would even rename the ASDF ones to match the LispWorks name, if I were sure to fix all the references (Are there any beyond ASDF and POIU?).
Is this really feasible?
While I agree the old names are not ideal, the collateral damage of changing them seems extensive.
depends-on and in-order-to are exposed through the defsystem grammar, and could be used all over the place.
Benefits: mildly tidier naming; Costs: potentially extensive breakage.
I really do mean "mildly" there, too. I don't think "caused-by" is so much clearer that it's worth anything. Either way you need to read the documentation to understand the meaning of :in-order-to and :do-first, or :caused-by and :requires. And the asymmetry of the passive voice in the former and the active voice in the latter seems odd enough to not help with clarity.
Best, Robert