On Sat, Jun 7, 2014 at 7:13 PM, Robert P. Goldman rpgoldman@sift.info wrote:
I guess what seems funny about OUTPUT-FILES is that the main methods have a return type that is *different* from the return type of the generic function.
The main method should return two values:
- A set of pathnames
- A boolean that indicates whether the :AROUND method should translate
the pathnames.
Then the :AROUND method translates this so that only a single value -- a set of possibly-translated pathnames -- is returned.
This strikes me as odd: what would you describe the signature of OUTPUT-FILES as being?
Actually, the toplevel :AROUND method *does* return two values, and the second is always T (see action.lisp line 274 as of 3.1.2).
The return signature is: (values (list-of pathname-designator) &optional boolean)
So neatness might argue that there be a POSSIBLY-TRANSLATED-OUTPUT-FILES (with a better name, of course), and an OUTPUT-FILES (behaving as now), with the former calling the latter, and each having a simpler signature.
That said, I don't see the need to break code for neatness.
The problem with that approach is that OUTPUT-FILES is an interface both for providers and consumers. Many extensions expect to call OUTPUT-FILES, and many extensions expect to define methods on OUTPUT-FILES. It might be a design mistake that the same function name be used in these two cases, which doesn't leave much room to interpose functionality between the two. But if that's the case (of which I'm not convinced), then that's a mistake that was made in the original ASDF, and can't be fixed without massive backward incompatibility. Happily, the :AROUND method is a good enough solution to this issue, at least so far.
As for "why these particular functions?" it's because (a) they are exported and (b) we have invited programmers to define new methods for them. Doing (b) correctly arguably requires more understanding if you have to know that there are existing :AROUND methods whose behavior must be preserved. If the :AROUND method was refactored to the previously proposed P-T-O-F, the extending programmer's job would be simpler. That said, the existing contract for methods is simple enough that I'm not going to worry about it.
You can't do that without breaking backward compatibility, or at least having a long and painful transition period. I'm not sure this is warranted, though you have an actual case for making such a change, the earlier you start the transition period the better.
I believe that it's OK to have to look at existing methods and not override them without reproducing functionality and sending a feature request for an extension point.
Also ((o operation) (c component)) vs ((o t) (c t)) usually leaves enough space for an :AROUND method already.
I'm going to drop this into my email archive as "interesting, but unimportant." I can return to it someday when tidying up unbroken code is the only thing I worry about, i.e., never.
The canonical term for that in jargon file is "in my copious free time".
As for "actual extension points," I have occasionally added new methods for these generic functions, but only simple ones. The only case I can think of that might be a problem with the existing contract would be one where there are multiple output-files, but only some of them are to be translated.
To date, I have never written an extension that had > 1 output-file, much less one that sent them to different places, so this is only a hypothetical. Perhaps an operation that built some data structure and an index.... But I can't see why those would go in different directories.
In these cases, you can explicitly call apply-output-translations on those outputs that need be translated but not the others, and return T as the second value.
Thanks for the explanation, r
Regards,
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Not all Law is created equal before Man. Some Law causes least conflict and least perverse incentives. By definition we call it Natural Law.