Trying to identify what's breaking my system in the syntax-case branch, I found a bunch of around methods in ASDF.
IIRC once upon a time we had removed all the :AROUND methods on exported generic functions, on the grounds that they could unpredictably interact with programmers' extensions.
I think we experimented with using a bespoke method combination method to allow ourselves to have our own around methods and "arounder" methods for programmers.
Even more vaguely, I think I remember that the method-combination extension didn't work reliably on all implementations, so it was stripped out. But I thought when that happened, we tried to excise the use of method combination in ASDF.
Am I hallucinating this?
I'd be grateful to anyone whose memory of this stuff is better.
thanks, r
On Fri, Jun 6, 2014 at 5:46 PM, Robert P. Goldman rpgoldman@sift.info wrote:
Trying to identify what's breaking my system in the syntax-case branch, I found a bunch of around methods in ASDF.
IIRC once upon a time we had removed all the :AROUND methods on exported generic functions, on the grounds that they could unpredictably interact with programmers' extensions.
I think we experimented with using a bespoke method combination method to allow ourselves to have our own around methods and "arounder" methods for programmers.
Even more vaguely, I think I remember that the method-combination extension didn't work reliably on all implementations, so it was stripped out. But I thought when that happened, we tried to excise the use of method combination in ASDF.
Am I hallucinating this?
I'd be grateful to anyone whose memory of this stuff is better.
At some point during ASDF1 days (aa52ad2 from 2008-09-09 by csr21), a new asdf:around method combination was introduced so that ASDF's own :around methods would override any user-provided :around method, all the while allowing such user-provided :around method. This was removed in the lead up to ASDF2 (826b12b0 aka 1.636 from 2010-03-15 by me), for better portability to implementations that didn't support the "long" method combination format (I believe CLISP and ABCL at the time, though they added them since, possibly others).
So we *are* using the regular :around method combination, but in one case, I've split a gf in two: perform became perform and perform-with-restarts.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Down to Gehenna or up to the Throne, He travels the fastest who travels alone. — Rudyard Kipling
Faré wrote:
On Fri, Jun 6, 2014 at 5:46 PM, Robert P. Goldman rpgoldman@sift.info wrote:
Trying to identify what's breaking my system in the syntax-case branch, I found a bunch of around methods in ASDF.
IIRC once upon a time we had removed all the :AROUND methods on exported generic functions, on the grounds that they could unpredictably interact with programmers' extensions.
I think we experimented with using a bespoke method combination method to allow ourselves to have our own around methods and "arounder" methods for programmers.
Even more vaguely, I think I remember that the method-combination extension didn't work reliably on all implementations, so it was stripped out. But I thought when that happened, we tried to excise the use of method combination in ASDF.
Am I hallucinating this?
I'd be grateful to anyone whose memory of this stuff is better.
At some point during ASDF1 days (aa52ad2 from 2008-09-09 by csr21), a new asdf:around method combination was introduced so that ASDF's own :around methods would override any user-provided :around method, all the while allowing such user-provided :around method. This was removed in the lead up to ASDF2 (826b12b0 aka 1.636 from 2010-03-15 by me), for better portability to implementations that didn't support the "long" method combination format (I believe CLISP and ABCL at the time, though they added them since, possibly others).
So we *are* using the regular :around method combination, but in one case, I've split a gf in two: perform became perform and perform-with-restarts.
I was wondering about the :AROUND methods for OUTPUT-FILES and INPUT-FILES, which are exported and which we invite programmers to provide methods for.
I don't think this is necessarily a big deal: we explain pretty carefully the contract for these functions (I need to check on the discussion in the manual). But we *could* add a wrapper function around OUTPUT-FILES (resp. INPUT-FILES) and put the :AROUND logic in that, and have ASDF internally call the wrapper function instead of OUTPUT-FILES (resp. INPUT-FILES).
Would this be a worthwhile clean-up?
thanks,
r
On Sat, Jun 7, 2014 at 4:02 PM, Robert P. Goldman rpgoldman@sift.info wrote:
I was wondering about the :AROUND methods for OUTPUT-FILES and INPUT-FILES, which are exported and which we invite programmers to provide methods for.
I don't think this is necessarily a big deal: we explain pretty carefully the contract for these functions (I need to check on the discussion in the manual). But we *could* add a wrapper function around OUTPUT-FILES (resp. INPUT-FILES) and put the :AROUND logic in that, and have ASDF internally call the wrapper function instead of OUTPUT-FILES (resp. INPUT-FILES).
Would this be a worthwhile clean-up?
But we don't invite programmers to redefine methods for existing classes, or at their own risk.
Why would these particular functions be special and require that there be a blank slate for :around methods?
If any actual programmer comes up with a need for more extension points, *then* extension points can be provided.
In addition to the perform-with-restarts issue, the development of ASDF2 and ASDF3 already led to defining plenty of new extension points so that the various extensions used at ITA (most notably POIU and ASDF-DEPENDENCY-GROVEL) could be written without overriding ASDF internals. The advantage of letting actual clients drive the definition of extension points is that you then know that your extension points make sense and have at least one client that'll test the functionality.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Faré's Second Law of Dissent: I am Right, whence it follows that all who disagree with me are either (1) evil, (2) stupid or (3) crazy. (The alternatives are not mutually exclusive.) This universal law is valid for all values of "me", including "you".
Faré wrote:
But we don't invite programmers to redefine methods for existing classes, or at their own risk.
Why would these particular functions be special and require that there be a blank slate for :around methods?
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:
1. A set of pathnames 2. 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?
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.
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.
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.
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.
Thanks for the explanation, r
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.