Hi,
ASDF does not raise an error, when the SBCL compiler produces warnings (e.g. "undefined variable", "undefined function"). Example: ======== test.asd ============= (defsystem :test :version "1.0" :components ((:file "test"))) ======== test.lisp ============ (defun foo () (+ a b)) ===============================
(asdf:load-system :test) does not signal an error.
I discovered this problem using SBCL, but I bet it can be reproduced on some other CL implementations that deffer warnings. The cause of the problem is that WITH-COMPILATION-UNIT may affect result values (warnings-p, and failure-p) of COMPILE-FILE. sbcl-help has a discussion of this WITH-COMPILATION-UNIT/COMPILE-FILE interaction: http://sourceforge.net/p/sbcl/mailman/message/32976990/
Regards, Ilya
Ilya Perminov wrote:
Hi,
ASDF does not raise an error, when the SBCL compiler produces warnings (e.g. "undefined variable", "undefined function"). Example: ======== test.asd ============= (defsystem :test :version "1.0" :components ((:file "test"))) ======== test.lisp ============ (defun foo () (+ a b)) ===============================
(asdf:load-system :test) does not signal an error.
I discovered this problem using SBCL, but I bet it can be reproduced on some other CL implementations that deffer warnings. The cause of the problem is that WITH-COMPILATION-UNIT may affect result values (warnings-p, and failure-p) of COMPILE-FILE. sbcl-help has a discussion of this WITH-COMPILATION-UNIT/COMPILE-FILE interaction: http://sourceforge.net/p/sbcl/mailman/message/32976990/
I cannot replicate this, but this may be a new behavior introduced by recent changes to SBCL, and I'm not on the latest release yet.
However, I *do* see something odd: when I make a system that loads Ilya's example test.lisp, on SBCL (my version), the compilation fails with a COMPILE-FAILED-ERROR, but on ACL 9.0, the compilation fails with a COMPILE-FILE-ERROR.
I suspect that this is because the way ASDF grabs errors in the two lisps is different, but it's a trifle unsettling, since these are both conditions defined by ASDF.
I have pushed a new testlet into test-deferred-warnings.script; please try this out.
thanks! r
"Robert P. Goldman" rpgoldman@sift.info writes:
I cannot replicate this, but this may be a new behavior introduced by recent changes to SBCL, and I'm not on the latest release yet.
Very strange. I can reproduce the problem with all the SBCL versions I have: 1.1.4, 1.1.18, 1.2.4. SBCL 1.2.4 includes the latest version of ASDF. Do you see any difference in behavior between deferred and normal warnings, i.e. (defun foo () (+ a b)) vs (defun foo () (foo 3))?
When I try to reproduce compilation of Ilya's system (renaming it undef-var, to prevent any clash) using sbcl-1.2.3.62-989a1d6-linux-x64, it "works" exactly as expected:
1- if deferred warnings are disabled (the default), then the compilation succeeds, and I get an undefined variable warning at the end of the build but that doesn't cause a build failure, because operate's with-compilation-unit doesn't catch these warnings (and can't replay those from previous sessions, anyway).
2- if deferred warnings are enabled via (uiop:enable-deferred-warnings), then the compilation fails while perform'ing a compile-op on the system, because it replays the undefined-warnings and checks that the variable still doesn't exist afterwards.
It could be argued that undefined-variable warnings, unlike undefined-function warnings, should not be deferrable, and that it's always a warning to use a special variable that wasn't declared as such. But that's not what SBCL does.
I can't explain why you have a different result, unless your setup somehow configures some conditions as uninteresting.
On the other hand, differences between compilers easily explain variations between condition reported by ASDF, since they depend both on what conditions the compiler reports, that are not portable, and on the *compile-file-warnings-behaviour* and *compile-file-failure-behaviour* values, that are also unportable. Note that unless you :force t, non-fatal warnings can disappear the second time around.
NB: Back when I first pre-released ASDF3, I wanted to enable deferred-warnings by default, but this turned out to be a community-wide coordination nightmare, and I had to bail out. If someone wants to make it happen, he'll have to make sure that it doesn't break quicklisp and then still have to convince the community and the ASDF maintainer that the change is worth it and that enough publicity is made that random users don't get badly surprised.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org The meta-Turing test counts a thing as intelligent if it seeks to apply Turing tests to objects of its own creation. — Lew Mammel, Jr.
On Wed, Oct 29, 2014 at 6:27 PM, Ilya Perminov iperminov@dwavesys.com wrote:
"Robert P. Goldman" rpgoldman@sift.info writes:
I cannot replicate this, but this may be a new behavior introduced by recent changes to SBCL, and I'm not on the latest release yet.
Very strange. I can reproduce the problem with all the SBCL versions I have: 1.1.4, 1.1.18, 1.2.4. SBCL 1.2.4 includes the latest version of ASDF. Do you see any difference in behavior between deferred and normal warnings, i.e. (defun foo () (+ a b)) vs (defun foo () (foo 3))?
Asdf-devel mailing list Asdf-devel@common-lisp.net http://mailman.common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel
Faré wrote:
When I try to reproduce compilation of Ilya's system (renaming it undef-var, to prevent any clash) using sbcl-1.2.3.62-989a1d6-linux-x64, it "works" exactly as expected:
1- if deferred warnings are disabled (the default), then the compilation succeeds, and I get an undefined variable warning at the end of the build but that doesn't cause a build failure, because operate's with-compilation-unit doesn't catch these warnings (and can't replay those from previous sessions, anyway).
Interesting. My test seems to show the build failing, on both ACL and SBCL. For SBCL:
; compiling file "/Users/rpg/lisp/asdf/test/fun-with-undefined-locals.lisp" (written 29 OCT 2014 04:59:39 PM):
; /Users/rpg/lisp/asdf/build/fasls/sbcl-1.2.0-macosx-x64/asdf/test/fun-with-undefined-locals-TMP.fasl written ; compilation finished in 0:00:00.001 ;; loading #P"/Users/rpg/lisp/asdf/build/fasls/sbcl-1.2.0-macosx-x64/asdf/test/fun-with-undefined-locals.fasl"
; file: /Users/rpg/lisp/asdf/test/fun-with-undefined-locals.lisp ; in: DEFUN FUN-WITH-UNDEFINED-LOCALS-PACKAGE::FOO ; (+ FUN-WITH-UNDEFINED-LOCALS-PACKAGE::A FUN-WITH-UNDEFINED-LOCALS-PACKAGE::B) ; ; caught WARNING: ; undefined variable: FUN-WITH-UNDEFINED-LOCALS-PACKAGE::A ; ; caught WARNING: ; undefined variable: FUN-WITH-UNDEFINED-LOCALS-PACKAGE::B ; ; compilation unit finished ; Undefined variables: ; FUN-WITH-UNDEFINED-LOCALS-PACKAGE::A FUN-WITH-UNDEFINED-LOCALS-PACKAGE::B ; caught 2 WARNING conditions ; ; compilation unit aborted ; caught 2 fatal ERROR conditions Expected error type: COMPILE-FAILED-ERROR Script succeeded Using sbcl, test-deferred-warnings.script passed
How do you distinguish between the build failing and succeeding but being followed by an error signal?
2- if deferred warnings are enabled via (uiop:enable-deferred-warnings), then the compilation fails while perform'ing a compile-op on the system, because it replays the undefined-warnings and checks that the variable still doesn't exist afterwards.
It could be argued that undefined-variable warnings, unlike undefined-function warnings, should not be deferrable, and that it's always a warning to use a special variable that wasn't declared as such. But that's not what SBCL does.
I can't explain why you have a different result, unless your setup somehow configures some conditions as uninteresting.
On the other hand, differences between compilers easily explain variations between condition reported by ASDF, since they depend both on what conditions the compiler reports, that are not portable, and on the *compile-file-warnings-behaviour* and *compile-file-failure-behaviour* values, that are also unportable. Note that unless you :force t, non-fatal warnings can disappear the second time around.
It is the "not portable" part of this that makes it seem like a maintenance nightmare, and not ASDF's job. If SBCL wants to signal warnings at oddball times, that's too bad, but I don't see that it's ASDF's job to fix that. We have to leave some fun for the SBCL maintainers ;-)
NB: Back when I first pre-released ASDF3, I wanted to enable deferred-warnings by default, but this turned out to be a community-wide coordination nightmare, and I had to bail out. If someone wants to make it happen, he'll have to make sure that it doesn't break quicklisp and then still have to convince the community and the ASDF maintainer that the change is worth it and that enough publicity is made that random users don't get badly surprised.
My experience with the deferred warnings on Allegro left me deeply dissatisfied. ACL seems to deal with deferring warnings to the right place simply through use of WITH-COMPILATION-UNIT. In particular, it correctly waits on UNDEFINED-FUNCTION warnings until the whole compilation unit has been processed, yet I don't recall delays in seeing UNDEFINED-VARIABLE references (I should check to confirm this, but I feel sure I would have noticed if undefined lexical variable warnings were deferred till the end of the build).
This suggested some conjectures:
1. AFAICT, using ASDF's deferred-warnings would have required first breaking the logic that ACL already provides, and then recreating it in ASDF.
2. If ACL can handle this sensibly w/o requiring any outside assistance from ASDF, then I don't believe that this should be ASDF's job.
3. The job of deferring warnings properly seems to involve thinking hard about which warnings should and should not be deferred. That's something that the implementation's maintainers will always be able to do better than we can, since the condition classes are poorly standardized.
4. It seems like the implementation needs to think carefully about how to defer warnings in WITH-COMPILATION-UNIT anyway.
I believe that you had a reason that you disliked W-C-U, but I'm afraid I would have to go back and recover that argument.
Best, r
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org The meta-Turing test counts a thing as intelligent if it seeks to apply Turing tests to objects of its own creation. — Lew Mammel, Jr.
On Wed, Oct 29, 2014 at 6:27 PM, Ilya Perminov iperminov@dwavesys.com wrote:
"Robert P. Goldman" rpgoldman@sift.info writes:
I cannot replicate this, but this may be a new behavior introduced by recent changes to SBCL, and I'm not on the latest release yet.
Very strange. I can reproduce the problem with all the SBCL versions I have: 1.1.4, 1.1.18, 1.2.4. SBCL 1.2.4 includes the latest version of ASDF. Do you see any difference in behavior between deferred and normal warnings, i.e. (defun foo () (+ a b)) vs (defun foo () (foo 3))?
Asdf-devel mailing list Asdf-devel@common-lisp.net http://mailman.common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel
On Wed, Oct 29, 2014 at 11:40 PM, Robert P. Goldman rpgoldman@sift.info wrote:
#P"/Users/rpg/lisp/asdf/build/fasls/sbcl-1.2.0-macosx-x64/asdf/test/fun-with-undefined-locals.fasl"
; file: /Users/rpg/lisp/asdf/test/fun-with-undefined-locals.lisp ; in: DEFUN FUN-WITH-UNDEFINED-LOCALS-PACKAGE::FOO ; (+ FUN-WITH-UNDEFINED-LOCALS-PACKAGE::A FUN-WITH-UNDEFINED-LOCALS-PACKAGE::B) ; ; caught WARNING: ; undefined variable: FUN-WITH-UNDEFINED-LOCALS-PACKAGE::A ; ; caught WARNING: ; undefined variable: FUN-WITH-UNDEFINED-LOCALS-PACKAGE::B ; ; compilation unit finished ; Undefined variables: ; FUN-WITH-UNDEFINED-LOCALS-PACKAGE::A FUN-WITH-UNDEFINED-LOCALS-PACKAGE::B ; caught 2 WARNING conditions ; ; compilation unit aborted ; caught 2 fatal ERROR conditions Expected error type: COMPILE-FAILED-ERROR Script succeeded Using sbcl, test-deferred-warnings.script passed
How do you distinguish between the build failing and succeeding but being followed by an error signal?
Nothing in ASDF should cause an error signal at the end of the W-C-U. You're discussing the behavior of a file that isn't checked in; does it have interesting handler-bind's? Does your SBCL and/or some configuration file include some interesting patch with respect to W-C-U and/or compile conditions? (Which version of SBCL is it?) I don't understand what's going on for you.
On the other hand, differences between compilers easily explain variations between condition reported by ASDF, since they depend both on what conditions the compiler reports, that are not portable, and on the *compile-file-warnings-behaviour* and *compile-file-failure-behaviour* values, that are also unportable. Note that unless you :force t, non-fatal warnings can disappear the second time around.
It is the "not portable" part of this that makes it seem like a maintenance nightmare, and not ASDF's job. If SBCL wants to signal warnings at oddball times, that's too bad, but I don't see that it's ASDF's job to fix that. We have to leave some fun for the SBCL maintainers ;-)
ASDF is a portability layer. It has to handle some non-portability in underlying implementations and provide portable abstractions. In this case, how to interpret the return values of COMPILE-FILE is de facto non-portable, with different implementations having wildly different interpretations of the CLHS regarding secondary values. ASDF thus provides the variables *compile-file-warnings-behaviour* and *compile-file-failure-behaviour* to interpret the warnings-p and failure-p return values of compile-file. It is *already* a nightmare, and ASDF has been *solving* that nightmare for a decade. Thanks, danb.
As for fine control of compiler conditions, ASDF doesn't do it, but it provides hooks in the form of uninteresting-conditions and compiler-hook. A colleague has written a portability layer for compiler conditions. I'm hoping he will clean it up and opensource it at some point.
NB: Back when I first pre-released ASDF3, I wanted to enable deferred-warnings by default, but this turned out to be a community-wide coordination nightmare, and I had to bail out. If someone wants to make it happen, he'll have to make sure that it doesn't break quicklisp and then still have to convince the community and the ASDF maintainer that the change is worth it and that enough publicity is made that random users don't get badly surprised.
My experience with the deferred warnings on Allegro left me deeply dissatisfied. ACL seems to deal with deferring warnings to the right place simply through use of WITH-COMPILATION-UNIT. In particular, it correctly waits on UNDEFINED-FUNCTION warnings until the whole compilation unit has been processed, yet I don't recall delays in seeing UNDEFINED-VARIABLE references (I should check to confirm this, but I feel sure I would have noticed if undefined lexical variable warnings were deferred till the end of the build).
One reason why I didn't include a test for undefined-variable behavior in the existing ASDF3 test/test-deferred-warnings.script is precisely that the way this is treated is highly implentation-dependent, and I didn't have the time and energy to track down the behavior on 16 implementations and figure out a portability layer or at least a conditional test.
This suggested some conjectures:
- AFAICT, using ASDF's deferred-warnings would have required first
breaking the logic that ACL already provides, and then recreating it in ASDF.
No. It doesn't require anything but suitable defaults. It might "just" be that check-deferred-warnings needs be made more clever, and/or might need to have its own separate variants of *compile-file-warnings-behaviour* and *compile-file-failure-behaviour*, and maybe also *compile-check*.
- If ACL can handle this sensibly w/o requiring any outside assistance
from ASDF, then I don't believe that this should be ASDF's job.
By definition, it's ASDF's job to put the correct W-C-U, and to emulate a system-wide W-C-U when warnings were deferred in a previous session (i.e. file "a" was previously compiled with deferred warnings, and least we forgo all intra-system incrementality, we don't want to recompile it). The implementation just can't make that stuff up out of thin air. Hopefully, we don't have to write clever handler-bind's as part of ASDF itself, but there's a possibility we might, and indeed someone should look at the undefined-variable behavior on each and every of the 16 implementations.
- The job of deferring warnings properly seems to involve thinking
hard about which warnings should and should not be deferred. That's something that the implementation's maintainers will always be able to do better than we can, since the condition classes are poorly standardized.
No. The implementation is already doing the deferring or not. ASDF's job is just to capture the relevant warnings, and either (1) effectively discard them, which it currently does with its W-C-U, unless some implementations convert them to errors at the end of W-C-U and that's a huge incrementality and portability issue that needs be solved or (2) replay them deterministically at the end of the system's compilation, which ASDF does when you enable-deferred-warnings-check.
- It seems like the implementation needs to think carefully about how
to defer warnings in WITH-COMPILATION-UNIT anyway.
No. We only need worry if some implementations convert warnings to errors at the end of W-C-U, in which case it becomes much more important to implement and deploy deferred-warnings.
I believe that you had a reason that you disliked W-C-U, but I'm afraid I would have to go back and recover that argument.
I hope the above explanations help.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Sure, we must render unto Caesar what is due to Caesar. But what is that? Any and all specie he coined that we possess, or 23 stab wounds?
Faré wrote:
On Wed, Oct 29, 2014 at 11:40 PM, Robert P. Goldman rpgoldman@sift.info wrote:
#P"/Users/rpg/lisp/asdf/build/fasls/sbcl-1.2.0-macosx-x64/asdf/test/fun-with-undefined-locals.fasl"
; file: /Users/rpg/lisp/asdf/test/fun-with-undefined-locals.lisp ; in: DEFUN FUN-WITH-UNDEFINED-LOCALS-PACKAGE::FOO ; (+ FUN-WITH-UNDEFINED-LOCALS-PACKAGE::A FUN-WITH-UNDEFINED-LOCALS-PACKAGE::B) ; ; caught WARNING: ; undefined variable: FUN-WITH-UNDEFINED-LOCALS-PACKAGE::A ; ; caught WARNING: ; undefined variable: FUN-WITH-UNDEFINED-LOCALS-PACKAGE::B ; ; compilation unit finished ; Undefined variables: ; FUN-WITH-UNDEFINED-LOCALS-PACKAGE::A FUN-WITH-UNDEFINED-LOCALS-PACKAGE::B ; caught 2 WARNING conditions ; ; compilation unit aborted ; caught 2 fatal ERROR conditions Expected error type: COMPILE-FAILED-ERROR Script succeeded Using sbcl, test-deferred-warnings.script passed
How do you distinguish between the build failing and succeeding but being followed by an error signal?
Nothing in ASDF should cause an error signal at the end of the W-C-U.
I think I'm misunderstanding the following from your previous message:
"if deferred warnings are disabled (the default), then the compilation succeeds, and I get an undefined variable warning at the end of the build but that doesn't cause a build failure, because operate's with-compilation-unit doesn't catch these warnings (and can't replay those from previous sessions, anyway)."
OK, so there's no error signal because the warning is not caught in the W-C-U. TBH, I don't understand this. When you say "caught" here, do you mean "handled"? And why should OPERATE need to catch these to avoid a spurious compilation success? Shouldn't this warning cause COMPILE-FILE's to return a non-nil warningsp?
You're discussing the behavior of a file that isn't checked in;
No, this file is checked in, and you should see these results if you run the test suite after pulling master from cl.net.
does it have interesting handler-bind's?
No, it's just Ilya's example.
Does your SBCL and/or some configuration file include some interesting patch with respect to W-C-U and/or compile conditions?
Not that I know of.
(Which version of SBCL is it?)
SBCL 1.2.0
I don't understand what's going on for you.
On the other hand, differences between compilers easily explain variations between condition reported by ASDF, since they depend both on what conditions the compiler reports, that are not portable, and on the *compile-file-warnings-behaviour* and *compile-file-failure-behaviour* values, that are also unportable. Note that unless you :force t, non-fatal warnings can disappear the second time around.
It is the "not portable" part of this that makes it seem like a maintenance nightmare, and not ASDF's job. If SBCL wants to signal warnings at oddball times, that's too bad, but I don't see that it's ASDF's job to fix that. We have to leave some fun for the SBCL maintainers ;-)
ASDF is a portability layer. It has to handle some non-portability in underlying implementations and provide portable abstractions. In this case, how to interpret the return values of COMPILE-FILE is de facto non-portable, with different implementations having wildly different interpretations of the CLHS regarding secondary values. ASDF thus provides the variables *compile-file-warnings-behaviour* and *compile-file-failure-behaviour* to interpret the warnings-p and failure-p return values of compile-file. It is *already* a nightmare, and ASDF has been *solving* that nightmare for a decade. Thanks, danb.
As for fine control of compiler conditions, ASDF doesn't do it, but it provides hooks in the form of uninteresting-conditions and compiler-hook. A colleague has written a portability layer for compiler conditions. I'm hoping he will clean it up and opensource it at some point.
NB: Back when I first pre-released ASDF3, I wanted to enable deferred-warnings by default, but this turned out to be a community-wide coordination nightmare, and I had to bail out. If someone wants to make it happen, he'll have to make sure that it doesn't break quicklisp and then still have to convince the community and the ASDF maintainer that the change is worth it and that enough publicity is made that random users don't get badly surprised.
My experience with the deferred warnings on Allegro left me deeply dissatisfied. ACL seems to deal with deferring warnings to the right place simply through use of WITH-COMPILATION-UNIT. In particular, it correctly waits on UNDEFINED-FUNCTION warnings until the whole compilation unit has been processed, yet I don't recall delays in seeing UNDEFINED-VARIABLE references (I should check to confirm this, but I feel sure I would have noticed if undefined lexical variable warnings were deferred till the end of the build).
One reason why I didn't include a test for undefined-variable behavior in the existing ASDF3 test/test-deferred-warnings.script is precisely that the way this is treated is highly implentation-dependent, and I didn't have the time and energy to track down the behavior on 16 implementations and figure out a portability layer or at least a conditional test.
This suggested some conjectures:
- AFAICT, using ASDF's deferred-warnings would have required first
breaking the logic that ACL already provides, and then recreating it in ASDF.
No. It doesn't require anything but suitable defaults. It might "just" be that check-deferred-warnings needs be made more clever, and/or might need to have its own separate variants of *compile-file-warnings-behaviour* and *compile-file-failure-behaviour*, and maybe also *compile-check*.
This still means "take code that works, break it, and then add more code to fix the breakage."
- If ACL can handle this sensibly w/o requiring any outside assistance
from ASDF, then I don't believe that this should be ASDF's job.
By definition, it's ASDF's job to put the correct W-C-U, and to emulate a system-wide W-C-U when warnings were deferred in a previous session (i.e. file "a" was previously compiled with deferred warnings, and least we forgo all intra-system incrementality, we don't want to recompile it). The implementation just can't make that stuff up out of thin air. Hopefully, we don't have to write clever handler-bind's as part of ASDF itself, but there's a possibility we might, and indeed someone should look at the undefined-variable behavior on each and every of the 16 implementations.
I'd be willing to meet the implementations halfway on this. If we can specify the information we need from the implementors to do this right, then we can ask them to provide an API that will provide that information. If they don't, then ASDF won't perform as well on that implementation.
I'm open to a volunteer to look at the undefined-variable behavior on each and every of the 16 implementations, but as Mr. Zimmerman once said "it ain't me you're lookin' for, babe."
I'm interested in shifting a lot of this "grovel over implementation internals" work to the place where it can best be done -- and more importantly, where it can best be maintained: to the implementors.
- The job of deferring warnings properly seems to involve thinking
hard about which warnings should and should not be deferred. That's something that the implementation's maintainers will always be able to do better than we can, since the condition classes are poorly standardized.
No. The implementation is already doing the deferring or not. ASDF's job is just to capture the relevant warnings, and either (1) effectively discard them, which it currently does with its W-C-U, unless some implementations convert them to errors at the end of W-C-U and that's a huge incrementality and portability issue that needs be solved or (2) replay them deterministically at the end of the system's compilation, which ASDF does when you enable-deferred-warnings-check.
- It seems like the implementation needs to think carefully about how
to defer warnings in WITH-COMPILATION-UNIT anyway.
No. We only need worry if some implementations convert warnings to errors at the end of W-C-U, in which case it becomes much more important to implement and deploy deferred-warnings.
Why would anyone do this conversion? Is it because there's a warning because locally the compiler can't tell that code is messed up, but once the W-C-U has exited, the compiler assumes some sort of closure? So if I don't see some form of declaration locally, I signal a warning, but it is held until the compilation-unit ends, and if it can't be handled then, we treat it as an error? In that case why signal a warning and turn it into an error, instead of just signaling an error? Is there a concrete example of this behavior?
thanks, r
: rpg
: fare
: rpg
How do you distinguish between the build failing and succeeding but being followed by an error signal?
Nothing in ASDF should cause an error signal at the end of the W-C-U.
I think I'm misunderstanding the following from your previous message:
"if deferred warnings are disabled (the default), then the compilation succeeds, and I get an undefined variable warning at the end of the build but that doesn't cause a build failure, because operate's with-compilation-unit doesn't catch these warnings (and can't replay those from previous sessions, anyway)."
OK, so there's no error signal because the warning is not caught in the W-C-U. TBH, I don't understand this. When you say "caught" here, do you mean "handled"? And why should OPERATE need to catch these to avoid a spurious compilation success? Shouldn't this warning cause COMPILE-FILE's to return a non-nil warningsp?
The warning is caught/handled/captured/call-it-what-you-may by W-C-U, and deferred to the end of W-C-U, ***as is the one and only purpose of W-C-U*** (so far as I can tell). The COMPILE-FILE is inside W-C-U, therefore doesn't even see the warnings, therefore cannot and will not compute its warnings-p and failures-p return values based on them, or otherwise display them or do anything whatsoever based on these warnings. It thus cannot and will not notify ASDF that cannot and will not upgrade them to full warnings or errors.
I don't know that OPERATE "needs" to do anything. The W-C-U has *always* been in ASDF (since danb's 1.34 in 2002), there is no more "spurious compilation success" than has always been.
When I discussed removing the W-C-U in ASDF 3 when not using the more robust deferred-warnings mechanism, this caused a backlash: ASDF would signal an error on SBCL when compiling buggy systems that used misspelled, undeclared or forward-referenced special variables. And yes, the systems were buggy, and I sent plenty of bug reports to Quicklisp system authors based on the bugs thus detected. It's a bug and a portability issue to fail to use a variable without suitable declaration. If users didn't complain, it's because they never used the functions with a misspelled variable, or happened to use an implementation that did the right thing anyway with undeclared special variables. The deferred-warnings mechanism catches and hushes forward-references to functions — I don't remember what it does with undeclared forward-references to special variables, but I would be slightly disappointed if SBCL didn't consider that a full WARNING worthy of a build failure.
You're discussing the behavior of a file that isn't checked in;
No, this file is checked in, and you should see these results if you run the test suite after pulling master from cl.net.
OK, I might have been looking at the wrong place. I see that test now, and tweaked it to make it more portable. This test (only) checks cases where deferred-warnings are enabled.
does it have interesting handler-bind's?
No, it's just Ilya's example.
It's not: you're enabling deferred-warnings. Ilya wasn't. This explains the different in behavior.
This suggested some conjectures:
- AFAICT, using ASDF's deferred-warnings would have required first
breaking the logic that ACL already provides, and then recreating it in ASDF.
No. It doesn't require anything but suitable defaults. It might "just" be that check-deferred-warnings needs be made more clever, and/or might need to have its own separate variants of *compile-file-warnings-behaviour* and *compile-file-failure-behaviour*, and maybe also *compile-check*.
This still means "take code that works, break it, and then add more code to fix the breakage."
No. Any code that the deferred-warnings declares broken is indeed broken code, though the bugs that go unchecked without deferred-warnings might happen to not be seen by users because it's in code not reached at runtime, or executed correctly on the implementation used by the user, though unportable.
- If ACL can handle this sensibly w/o requiring any outside assistance
from ASDF, then I don't believe that this should be ASDF's job.
By definition, it's ASDF's job to put the correct W-C-U, and to emulate a system-wide W-C-U when warnings were deferred in a previous session (i.e. file "a" was previously compiled with deferred warnings, and least we forgo all intra-system incrementality, we don't want to recompile it). The implementation just can't make that stuff up out of thin air. Hopefully, we don't have to write clever handler-bind's as part of ASDF itself, but there's a possibility we might, and indeed someone should look at the undefined-variable behavior on each and every of the 16 implementations.
I'd be willing to meet the implementations halfway on this. If we can specify the information we need from the implementors to do this right, then we can ask them to provide an API that will provide that information. If they don't, then ASDF won't perform as well on that implementation.
I'm open to a volunteer to look at the undefined-variable behavior on each and every of the 16 implementations, but as Mr. Zimmerman once said "it ain't me you're lookin' for, babe."
I'm interested in shifting a lot of this "grovel over implementation internals" work to the place where it can best be done -- and more importantly, where it can best be maintained: to the implementors.
Actually, it looks like you only need to check implementations with deferred-warnings support: allegro, clozure, cmucl, sbcl, scl. cmucl (and I presume scl) emit a full warning for undefined-variables, but there is no provision for upgrading that to a full error; users who want to catch them shall define their handler-bind — or just switch to sbcl. allegro, clozure, sbcl, seem to correctly catch the undefined variables.
Therefore, I believe the current asdf support for deferred-warnings already works as well as we can hope it to do. It's a "simple" matter of chasing the bugs in Quicklisp and warning all users before to make it the default.
- It seems like the implementation needs to think carefully about how
to defer warnings in WITH-COMPILATION-UNIT anyway.
No. We only need worry if some implementations convert warnings to errors at the end of W-C-U, in which case it becomes much more important to implement and deploy deferred-warnings.
Why would anyone do this conversion? Is it because there's a warning because locally the compiler can't tell that code is messed up, but once the W-C-U has exited, the compiler assumes some sort of closure? So if I don't see some form of declaration locally, I signal a warning, but it is held until the compilation-unit ends, and if it can't be handled then, we treat it as an error? In that case why signal a warning and turn it into an error, instead of just signaling an error? Is there a concrete example of this behavior?
I don't believe any implementation is doing that. Your report made me worried, but you just had the ASDF deferred-warnings enabled, and it was ASDF doing this upgrading.
The *compile-file-warnings-behaviour* and *compile-file-failure-behaviour* features have existed since ASDF 1 and are semi-documented in the manual (with a bogus name for the latter).
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Live as if you were living already for the second time and as if you had acted the first time as wrongly as you are about to act now! — Viktor Frankl, "Man's Search for Meaning"
Faré wrote:
: rpg
: fare
: rpg
....
You're discussing the behavior of a file that isn't checked in;
No, this file is checked in, and you should see these results if you run the test suite after pulling master from cl.net.
OK, I might have been looking at the wrong place. I see that test now, and tweaked it to make it more portable. This test (only) checks cases where deferred-warnings are enabled.
does it have interesting handler-bind's?
No, it's just Ilya's example.
It's not: you're enabling deferred-warnings. Ilya wasn't. This explains the different in behavior.
Argh. I misinterpreted the name and didn't read carefully enough. I was thinking of deferred-warnings as a thing that happens, rather than as an ASDF feature. My bad. I should copy this test out to a disabled-deferred-warnings.script.
This suggested some conjectures:
- AFAICT, using ASDF's deferred-warnings would have required first
breaking the logic that ACL already provides, and then recreating it in ASDF.
No. It doesn't require anything but suitable defaults. It might "just" be that check-deferred-warnings needs be made more clever, and/or might need to have its own separate variants of *compile-file-warnings-behaviour* and *compile-file-failure-behaviour*, and maybe also *compile-check*.
This still means "take code that works, break it, and then add more code to fix the breakage."
No. Any code that the deferred-warnings declares broken is indeed broken code, though the bugs that go unchecked without deferred-warnings might happen to not be seen by users because it's in code not reached at runtime, or executed correctly on the implementation used by the user, though unportable.
Hmmm... I will check again. In the past, what was happening for me on ACL was that I was seeing a large number of bogus UNDEFINED-FUNCTION warnings. But maybe I'm confusing ENABLE-DEFERRED-WARNINGS with an earlier version where we moved the W-C-U's around. I will recheck against a large system with a lot of forward-referenced functions.
More philosophical musings I'll have to defer....
cheers, r
I figured out my problem: my code was not calling (enable-deferred-warnings-check). Sorry for the noise. I was not even aware of ENABLE-DEFERRED-WARNINGS-CHECK. What is the reason for suppressing defer-able warnings by default? As far as I understand the distinction between normal and deferred warnings is implementation-specific, so ASDF probably suppress different sets of warnings on different CL implementations.
Thanks, Ilya