[asdf-devel] compile-with-nicknames
hY, I would like to propose a kind of an enhancement to the ASDF functionalities. So there is a problem with package nicknames that they have to be unique. So using the :nicknames option in a package definition can cause "uncorrectable" collisions. On the other hand, by not doing so, one has to use fully qualified package names (eg. :com.gigamonkeys.macro-utilities) during library development which makes the code completely unreadable (in my opinion at least). So there would be a possibility in asdf to at least partially handle this problem. It would be nice to define temporary nicknames for the compilation time. At the moment, it is possible by the :perform asdf option. So one can place and remove the nicknames by :perform (compile-op :before ...) and :perform (compile-op :after) options. Often it would be desirable, to do so for every asdf compilation unit, but there is no easy way to do so yet. Note: one has to define the nickname operators for every compilation unit in which it is used, otherwise the exclusive recompilation of this unit will produce an error (which would make development difficult). The other problem with this approach is when a compilation fails, the nicknames won't be cleared. However it is not a big problem for a development process, and otherwise it should not happen. Defining the :perform options for each asdf unit, is pretty ugly. So it is nice to have a script at least which walks over all compilation units and sets the perform options. But there would be a nicer way, and this is the proposal. What about a new asdf option (eg :compile-with-nicknames), which could look like something this? (defsystem my-system :depends-on ("package-1" "package-2" "package-3" ...) :compile-with-nicknames (("package-1" "pckg-1") ("package-3" "pckg-3")) :components (...)) I think this approach nicely works in a "clear" environment for non-parallel compilation when there are no insane nickname requests. The "clear" environment assumption can be relaxed to say that the user hasn't defined any nicknames which causes collisions for any necessary compilations. Or if you know a better way to handle this problem, I would be happy to hear about that... Thanks, `bg`
2011/10/16 Gábor Balázs <gabalz@gmail.com>:
But there would be a nicer way, and this is the proposal. What about a new asdf option (eg :compile-with-nicknames), which could look like something this?
(defsystem my-system :depends-on ("package-1" "package-2" "package-3" ...) :compile-with-nicknames (("package-1" "pckg-1") ("package-3" "pckg-3")) :components (...))
I think this approach nicely works in a "clear" environment for non-parallel compilation when there are no insane nickname requests. The "clear" environment assumption can be relaxed to say that the user hasn't defined any nicknames which causes collisions for any necessary compilations.
Or if you know a better way to handle this problem, I would be happy to hear about that...
Dear Gábor, you describe a common problem and a shared frustration of many CL developers. However, the problem is not limited to package nicknames, and instead I would prefer something more general: the ability to wrap something around compilation, essentially an advice around compile-file*. I recently added this feature to xcvb, so that it may compile ironclad, that uses such a wrapper (an :around method on perform) to bind the *readtable* and muffle some warnings around compilation. And so, I propose something more like: (defun call-with-my-nicknames (thunk) (with-package-nicknames (("package-1" "pckg-1") ("package-3" "pckg-3")) (funcall thunk))) (defsystem my-system :depends-on ("system-1" "system-2" "system-3" ...) :around-compile call-with-my-nicknames :components (...)) What do you think? Of course, you'd have to use ASDF 2.018 or later for that. Or maybe it's time to call it ASDF 2.18 instead? —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org
On 10/16/11 Oct 16 -4:52 PM, Faré wrote:
2011/10/16 Gábor Balázs <gabalz@gmail.com>:
But there would be a nicer way, and this is the proposal. What about a new asdf option (eg :compile-with-nicknames), which could look like something this?
(defsystem my-system :depends-on ("package-1" "package-2" "package-3" ...) :compile-with-nicknames (("package-1" "pckg-1") ("package-3" "pckg-3")) :components (...))
I think this approach nicely works in a "clear" environment for non-parallel compilation when there are no insane nickname requests. The "clear" environment assumption can be relaxed to say that the user hasn't defined any nicknames which causes collisions for any necessary compilations.
Or if you know a better way to handle this problem, I would be happy to hear about that...
I think there is a better way to solve this problem, but it is an ASDF3 method. The basic idea is as follows: 1. ASDF currently works by developing a LINEAR plan for performing an operation. Here's an example: CL-USER> (asdf:operate 'asdf:load-op :murphy-ltk-demo) #<ASDF:LOAD-OP NIL @ #x1000d42f82> ((#<ASDF:LOAD-OP NIL @ #x1000d57312> . #<ASDF:CL-SOURCE-FILE "ltk" "ltk">) (#<ASDF:LOAD-OP NIL @ #x1000d57312> . #<ASDF:SYSTEM "ltk">) (#<ASDF:LOAD-OP NIL @ #x1000d62f32> . #<ASDF:CL-SOURCE-FILE "murphy-ltk-demo" "package">) (#<ASDF:COMPILE-OP NIL @ #x1000d62f52> . #<ASDF:CL-SOURCE-FILE "murphy-ltk-demo" "ltk-demo">) (#<ASDF:COMPILE-OP NIL @ #x1000d62f52> . #<ASDF:SYSTEM "murphy-ltk-demo">) (#<ASDF:LOAD-OP NIL @ #x1000d42f82> . #<ASDF:CL-SOURCE-FILE "murphy-ltk-demo" "ltk-demo">) (#<ASDF:LOAD-OP NIL @ #x1000d42f82> . #<ASDF:SYSTEM "murphy-ltk-demo">)) Inspecting this plan reveals the problem: the operation COMPILE-OP on #<ASDF:SYSTEM "murphy-ltk-demo"> is not done AROUND the compilation operations on the component files, but AFTER them. 2. A possible solution would be to restructure the plans so that they are TREE-SHAPED, instead of linear. So that there would be an operation that CONTAINS the compile-ops of the individual systems. Then, instead of the "plan interpreter" component of ASDF just being a MAP, it would be a tree-mapper. I think that this is in some sense The Right Thing. The only problem is that the LOAD-OP is not "convex" in some sense. Instead, there is loading of files done *during* the compilation. So if we were to do this, wrapping something around the LOAD-OP might have counterintuitive results. Note also that I believe that we would have to keep the original, odd semantics of the operations on systems, and add a new operation, for backwards compatibility. So we might have COMPILE-COMPONENT-OP or something. Cheers, r
Dear Gábor,
you describe a common problem and a shared frustration of many CL developers. However, the problem is not limited to package nicknames, and instead I would prefer something more general: the ability to wrap something around compilation, essentially an advice around compile-file*. I recently added this feature to xcvb, so that it may compile ironclad, that uses such a wrapper (an :around method on perform) to bind the *readtable* and muffle some warnings around compilation.
And so, I propose something more like:
(defun call-with-my-nicknames (thunk) (with-package-nicknames (("package-1" "pckg-1") ("package-3" "pckg-3")) (funcall thunk)))
(defsystem my-system :depends-on ("system-1" "system-2" "system-3" ...) :around-compile call-with-my-nicknames :components (...))
What do you think?
Of course, you'd have to use ASDF 2.018 or later for that. Or maybe it's time to call it ASDF 2.18 instead?
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org
_______________________________________________ asdf-devel mailing list asdf-devel@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel
hY Fare and Robert, I have my function, which does the described job for me too. The point here is to offer this functionality in public on an easy, standard way. Personally, I like to have a single defsystem sexp in the asd file, so I would prefer avoiding function definitions there. I haven't met any situation before when something serious had to be done around a compilation, but you are probably right and wrapping arbitrary functions is a useful functionality. However to do that nicely, asdf should be refactored in a way described by Robert. But I think it would be still nice to offer this (cheap) renaming functionality separately without some heavy syntax (wrapping the whole defsystem into a function seems to be heavy for me). So my function walks along the whole asdf component tree and set the :before and :after for each (non-module) component. I had to do this way just because the fact you described (I guess). But I was thinking instead of putting this functionality around the compile-file call itself inside asdf. So to apply this immediately to the whole component tree (to each compilation unit). I think it is not a restriction with renaming. At least I cannot imagine a reasonable scenario when one wants to use different nicknames of the same package for different asdf modules. So as I see this renaming functionality has the following properties: - it is fairly easy to implement into the current mainstream asdf version - it is easy to use, so CL library developers could easily eliminate the :nicknames options from the package definitions and use this instead (they should basically change only a few lines of code in the .asd and package.lisp files) - unfortunately, it is not the most general solution, so the arbitrary function wrapping would not be provided this way I feel the 2nd point very valuable, so I think it would worth doing... `bg` On Sun, Oct 16, 2011 at 4:11 PM, Robert Goldman <rpgoldman@sift.info> wrote:
On 10/16/11 Oct 16 -4:52 PM, Faré wrote:
2011/10/16 Gábor Balázs <gabalz@gmail.com>:
But there would be a nicer way, and this is the proposal. What about a new asdf option (eg :compile-with-nicknames), which could look like something this?
(defsystem my-system :depends-on ("package-1" "package-2" "package-3" ...) :compile-with-nicknames (("package-1" "pckg-1") ("package-3" "pckg-3")) :components (...))
I think this approach nicely works in a "clear" environment for non-parallel compilation when there are no insane nickname requests. The "clear" environment assumption can be relaxed to say that the user hasn't defined any nicknames which causes collisions for any necessary compilations.
Or if you know a better way to handle this problem, I would be happy to hear about that...
I think there is a better way to solve this problem, but it is an ASDF3 method. The basic idea is as follows:
1. ASDF currently works by developing a LINEAR plan for performing an operation. Here's an example:
CL-USER> (asdf:operate 'asdf:load-op :murphy-ltk-demo) #<ASDF:LOAD-OP NIL @ #x1000d42f82> ((#<ASDF:LOAD-OP NIL @ #x1000d57312> . #<ASDF:CL-SOURCE-FILE "ltk" "ltk">) (#<ASDF:LOAD-OP NIL @ #x1000d57312> . #<ASDF:SYSTEM "ltk">) (#<ASDF:LOAD-OP NIL @ #x1000d62f32> . #<ASDF:CL-SOURCE-FILE "murphy-ltk-demo" "package">) (#<ASDF:COMPILE-OP NIL @ #x1000d62f52> . #<ASDF:CL-SOURCE-FILE "murphy-ltk-demo" "ltk-demo">) (#<ASDF:COMPILE-OP NIL @ #x1000d62f52> . #<ASDF:SYSTEM "murphy-ltk-demo">) (#<ASDF:LOAD-OP NIL @ #x1000d42f82> . #<ASDF:CL-SOURCE-FILE "murphy-ltk-demo" "ltk-demo">) (#<ASDF:LOAD-OP NIL @ #x1000d42f82> . #<ASDF:SYSTEM "murphy-ltk-demo">))
Inspecting this plan reveals the problem: the operation COMPILE-OP on #<ASDF:SYSTEM "murphy-ltk-demo"> is not done AROUND the compilation operations on the component files, but AFTER them.
2. A possible solution would be to restructure the plans so that they are TREE-SHAPED, instead of linear. So that there would be an operation that CONTAINS the compile-ops of the individual systems.
Then, instead of the "plan interpreter" component of ASDF just being a MAP, it would be a tree-mapper.
I think that this is in some sense The Right Thing. The only problem is that the LOAD-OP is not "convex" in some sense. Instead, there is loading of files done *during* the compilation. So if we were to do this, wrapping something around the LOAD-OP might have counterintuitive results.
Note also that I believe that we would have to keep the original, odd semantics of the operations on systems, and add a new operation, for backwards compatibility. So we might have COMPILE-COMPONENT-OP or something.
Cheers, r
Dear Gábor,
you describe a common problem and a shared frustration of many CL developers. However, the problem is not limited to package nicknames, and instead I would prefer something more general: the ability to wrap something around compilation, essentially an advice around compile-file*. I recently added this feature to xcvb, so that it may compile ironclad, that uses such a wrapper (an :around method on perform) to bind the *readtable* and muffle some warnings around compilation.
And so, I propose something more like:
(defun call-with-my-nicknames (thunk) (with-package-nicknames (("package-1" "pckg-1") ("package-3" "pckg-3")) (funcall thunk)))
(defsystem my-system :depends-on ("system-1" "system-2" "system-3" ...) :around-compile call-with-my-nicknames :components (...))
What do you think?
Of course, you'd have to use ASDF 2.018 or later for that. Or maybe it's time to call it ASDF 2.18 instead?
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org
_______________________________________________ asdf-devel mailing list asdf-devel@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel
_______________________________________________ asdf-devel mailing list asdf-devel@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel
On 10/16/11 Oct 16 -8:53 PM, Gábor Balázs wrote:
hY Fare and Robert,
I have my function, which does the described job for me too. The point here is to offer this functionality in public on an easy, standard way. Personally, I like to have a single defsystem sexp in the asd file, so I would prefer avoiding function definitions there. I haven't met any situation before when something serious had to be done around a compilation, but you are probably right and wrapping arbitrary functions is a useful functionality. However to do that nicely, asdf should be refactored in a way described by Robert. But I think it would be still nice to offer this (cheap) renaming functionality separately without some heavy syntax (wrapping the whole defsystem into a function seems to be heavy for me).
So my function walks along the whole asdf component tree and set the :before and :after for each (non-module) component. I had to do this way just because the fact you described (I guess). But I was thinking instead of putting this functionality around the compile-file call itself inside asdf. So to apply this immediately to the whole component tree (to each compilation unit). I think it is not a restriction with renaming. At least I cannot imagine a reasonable scenario when one wants to use different nicknames of the same package for different asdf modules.
I think the problem with doing this :before and :after of each component and operation is that it doesn't have sensible :around semantics. E.g., you can't easily use it to do something obvious like wrap a dynamic variable binding around the entire compilation of the system and then update that dynamic variable binding to communicate across individual compilations. I also worry about this nicknaming idea because it seems to rely on assumptions about the package-to-system mapping that aren't articulated clearly yet. Can you explain the use case more clearly so we understand why this is generally useful?
So as I see this renaming functionality has the following properties:
* it is fairly easy to implement into the current mainstream asdf version * it is easy to use, so CL library developers could easily eliminate the :nicknames options from the package definitions and use this instead (they should basically change only a few lines of code in the .asd and package.lisp files) * unfortunately, it is not the most general solution, so the arbitrary function wrapping would not be provided this way
I feel the 2nd point very valuable, so I think it would worth doing...
`bg`
On Sun, Oct 16, 2011 at 4:11 PM, Robert Goldman <rpgoldman@sift.info <mailto:rpgoldman@sift.info>> wrote:
On 10/16/11 Oct 16 -4:52 PM, Faré wrote: > 2011/10/16 Gábor Balázs <gabalz@gmail.com <mailto:gabalz@gmail.com>>: >> But there would be a nicer way, and this is the proposal. What about a new >> asdf option (eg :compile-with-nicknames), which could look like something >> this? >> >> (defsystem my-system >> :depends-on ("package-1" "package-2" "package-3" ...) >> :compile-with-nicknames (("package-1" "pckg-1") >> ("package-3" "pckg-3")) >> :components (...)) >> >> I think this approach nicely works in a "clear" environment for non-parallel >> compilation when there are no insane nickname requests. >> The "clear" environment assumption can be relaxed to say that the user >> hasn't defined any nicknames which causes collisions for any necessary >> compilations. >> >> Or if you know a better way to handle this problem, I would be happy to hear >> about that...
I think there is a better way to solve this problem, but it is an ASDF3 method. The basic idea is as follows:
1. ASDF currently works by developing a LINEAR plan for performing an operation. Here's an example:
CL-USER> (asdf:operate 'asdf:load-op :murphy-ltk-demo) #<ASDF:LOAD-OP NIL @ #x1000d42f82> ((#<ASDF:LOAD-OP NIL @ #x1000d57312> . #<ASDF:CL-SOURCE-FILE "ltk" "ltk">) (#<ASDF:LOAD-OP NIL @ #x1000d57312> . #<ASDF:SYSTEM "ltk">) (#<ASDF:LOAD-OP NIL @ #x1000d62f32> . #<ASDF:CL-SOURCE-FILE "murphy-ltk-demo" "package">) (#<ASDF:COMPILE-OP NIL @ #x1000d62f52> . #<ASDF:CL-SOURCE-FILE "murphy-ltk-demo" "ltk-demo">) (#<ASDF:COMPILE-OP NIL @ #x1000d62f52> . #<ASDF:SYSTEM "murphy-ltk-demo">) (#<ASDF:LOAD-OP NIL @ #x1000d42f82> . #<ASDF:CL-SOURCE-FILE "murphy-ltk-demo" "ltk-demo">) (#<ASDF:LOAD-OP NIL @ #x1000d42f82> . #<ASDF:SYSTEM "murphy-ltk-demo">))
Inspecting this plan reveals the problem: the operation COMPILE-OP on #<ASDF:SYSTEM "murphy-ltk-demo"> is not done AROUND the compilation operations on the component files, but AFTER them.
2. A possible solution would be to restructure the plans so that they are TREE-SHAPED, instead of linear. So that there would be an operation that CONTAINS the compile-ops of the individual systems.
Then, instead of the "plan interpreter" component of ASDF just being a MAP, it would be a tree-mapper.
I think that this is in some sense The Right Thing. The only problem is that the LOAD-OP is not "convex" in some sense. Instead, there is loading of files done *during* the compilation. So if we were to do this, wrapping something around the LOAD-OP might have counterintuitive results.
Note also that I believe that we would have to keep the original, odd semantics of the operations on systems, and add a new operation, for backwards compatibility. So we might have COMPILE-COMPONENT-OP or something.
Cheers, r
>> > Dear Gábor, > > you describe a common problem and a shared frustration of many CL developers. > However, the problem is not limited to package nicknames, and instead > I would prefer something more general: > the ability to wrap something around compilation, > essentially an advice around compile-file*. > I recently added this feature to xcvb, so that it may compile ironclad, > that uses such a wrapper (an :around method on perform) > to bind the *readtable* and muffle some warnings around compilation. > > And so, I propose something more like: > > (defun call-with-my-nicknames (thunk) > (with-package-nicknames > (("package-1" "pckg-1") > ("package-3" "pckg-3")) > (funcall thunk))) > > (defsystem my-system > :depends-on ("system-1" "system-2" "system-3" ...) > :around-compile call-with-my-nicknames > :components (...)) > > What do you think? > > Of course, you'd have to use ASDF 2.018 or later for that. > Or maybe it's time to call it ASDF 2.18 instead? > > —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org > > _______________________________________________ > asdf-devel mailing list > asdf-devel@common-lisp.net <mailto:asdf-devel@common-lisp.net> > http://lists.common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel
_______________________________________________ asdf-devel mailing list asdf-devel@common-lisp.net <mailto:asdf-devel@common-lisp.net> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel
Sorry, I had a typo, I didn't want to assume any relationship between system and package names. That is the role of the developer who writes the asd file. So let take the following scenario: Instead of having: com.long-host.my-library.asd (defsystem com.long-host.my-library :serial t :depends-on ("com.long-host.system-1" "com.long-host.system-2" "com.long-host.system-3") :components ((:file "package") (:file "file-1") (:file "file-2") (:module "module" :components ((:file "file-3")))) package.lisp (defpackage com.long-host.my-package (:use :cl :com.long-host.package-1) ...) If I am lucky and I can use the :com.long-host.package-1 package (defined by com.long-host.system-1 library). If I cannot do it with :com.long-host.package-2, then I have to use fully qualified names in "file-1.lisp", "file2.lisp" and "file3.lisp" like com.long-host.package-2:some-function. Similarly let say I don't want to use :com.long-host.package-3 for some reason. I would like to write something like this: com.long-host.my-library.asd (defsystem com.long-host.my-library :serial t :depends-on ("com.long-host.system-1" "com.long-host.system-2" "com.long-host.system-3") :compile-with-nicknames (("com.long-host.package-2" "p2") ("com.long-host.package-3" "p3")) :components ((:file "package") (:file "file-1") (:file "file-2") (:module "module" :components ((:file "file-3")))) Then I can simply write p2:some-function in "file-1.lisp", "file-2.lisp" and "file-3.lisp". I think as far as there is no easy way to do this, people will just define short nicknames for their packages, and the number of collisions will increase... That's why I think it would be useful, to stop this "habit"... `bg` 2011/10/16 Robert Goldman <rpgoldman@sift.info>
On 10/16/11 Oct 16 -8:53 PM, Gábor Balázs wrote:
hY Fare and Robert,
I have my function, which does the described job for me too. The point here is to offer this functionality in public on an easy, standard way. Personally, I like to have a single defsystem sexp in the asd file, so I would prefer avoiding function definitions there. I haven't met any situation before when something serious had to be done around a compilation, but you are probably right and wrapping arbitrary functions is a useful functionality. However to do that nicely, asdf should be refactored in a way described by Robert. But I think it would be still nice to offer this (cheap) renaming functionality separately without some heavy syntax (wrapping the whole defsystem into a function seems to be heavy for me).
So my function walks along the whole asdf component tree and set the :before and :after for each (non-module) component. I had to do this way just because the fact you described (I guess). But I was thinking instead of putting this functionality around the compile-file call itself inside asdf. So to apply this immediately to the whole component tree (to each compilation unit). I think it is not a restriction with renaming. At least I cannot imagine a reasonable scenario when one wants to use different nicknames of the same package for different asdf modules.
I think the problem with doing this :before and :after of each component and operation is that it doesn't have sensible :around semantics. E.g., you can't easily use it to do something obvious like wrap a dynamic variable binding around the entire compilation of the system and then update that dynamic variable binding to communicate across individual compilations.
I also worry about this nicknaming idea because it seems to rely on assumptions about the package-to-system mapping that aren't articulated clearly yet.
Can you explain the use case more clearly so we understand why this is generally useful?
So as I see this renaming functionality has the following properties:
* it is fairly easy to implement into the current mainstream asdf
version
* it is easy to use, so CL library developers could easily eliminate the :nicknames options from the package definitions and use this instead (they should basically change only a few lines of code in the .asd and package.lisp files) * unfortunately, it is not the most general solution, so the arbitrary function wrapping would not be provided this way
I feel the 2nd point very valuable, so I think it would worth doing...
`bg`
On Sun, Oct 16, 2011 at 4:11 PM, Robert Goldman <rpgoldman@sift.info <mailto:rpgoldman@sift.info>> wrote:
On 10/16/11 Oct 16 -4:52 PM, Faré wrote: > 2011/10/16 Gábor Balázs <gabalz@gmail.com <mailto:gabalz@gmail.com
: >> But there would be a nicer way, and this is the proposal. What about a new >> asdf option (eg :compile-with-nicknames), which could look like something >> this? >> >> (defsystem my-system >> :depends-on ("package-1" "package-2" "package-3" ...) >> :compile-with-nicknames (("package-1" "pckg-1") >> ("package-3" "pckg-3")) >> :components (...)) >> >> I think this approach nicely works in a "clear" environment for non-parallel >> compilation when there are no insane nickname requests. >> The "clear" environment assumption can be relaxed to say that the user >> hasn't defined any nicknames which causes collisions for any necessary >> compilations. >> >> Or if you know a better way to handle this problem, I would be happy to hear >> about that...
I think there is a better way to solve this problem, but it is an ASDF3 method. The basic idea is as follows:
1. ASDF currently works by developing a LINEAR plan for performing an operation. Here's an example:
CL-USER> (asdf:operate 'asdf:load-op :murphy-ltk-demo) #<ASDF:LOAD-OP NIL @ #x1000d42f82> ((#<ASDF:LOAD-OP NIL @ #x1000d57312> . #<ASDF:CL-SOURCE-FILE "ltk" "ltk">) (#<ASDF:LOAD-OP NIL @ #x1000d57312> . #<ASDF:SYSTEM "ltk">) (#<ASDF:LOAD-OP NIL @ #x1000d62f32> . #<ASDF:CL-SOURCE-FILE "murphy-ltk-demo" "package">) (#<ASDF:COMPILE-OP NIL @ #x1000d62f52> . #<ASDF:CL-SOURCE-FILE "murphy-ltk-demo" "ltk-demo">) (#<ASDF:COMPILE-OP NIL @ #x1000d62f52> . #<ASDF:SYSTEM "murphy-ltk-demo">) (#<ASDF:LOAD-OP NIL @ #x1000d42f82> . #<ASDF:CL-SOURCE-FILE "murphy-ltk-demo" "ltk-demo">) (#<ASDF:LOAD-OP NIL @ #x1000d42f82> . #<ASDF:SYSTEM "murphy-ltk-demo">))
Inspecting this plan reveals the problem: the operation COMPILE-OP on #<ASDF:SYSTEM "murphy-ltk-demo"> is not done AROUND the compilation operations on the component files, but AFTER them.
2. A possible solution would be to restructure the plans so that they are TREE-SHAPED, instead of linear. So that there would be an operation that CONTAINS the compile-ops of the individual systems.
Then, instead of the "plan interpreter" component of ASDF just being a MAP, it would be a tree-mapper.
I think that this is in some sense The Right Thing. The only problem is that the LOAD-OP is not "convex" in some sense. Instead, there is loading of files done *during* the compilation. So if we were to do this, wrapping something around the LOAD-OP might have counterintuitive results.
Note also that I believe that we would have to keep the original, odd semantics of the operations on systems, and add a new operation, for backwards compatibility. So we might have COMPILE-COMPONENT-OP or something.
Cheers, r
>> > Dear Gábor, > > you describe a common problem and a shared frustration of many CL developers. > However, the problem is not limited to package nicknames, and instead > I would prefer something more general: > the ability to wrap something around compilation, > essentially an advice around compile-file*. > I recently added this feature to xcvb, so that it may compile ironclad, > that uses such a wrapper (an :around method on perform) > to bind the *readtable* and muffle some warnings around compilation. > > And so, I propose something more like: > > (defun call-with-my-nicknames (thunk) > (with-package-nicknames > (("package-1" "pckg-1") > ("package-3" "pckg-3")) > (funcall thunk))) > > (defsystem my-system > :depends-on ("system-1" "system-2" "system-3" ...) > :around-compile call-with-my-nicknames > :components (...)) > > What do you think? > > Of course, you'd have to use ASDF 2.018 or later for that. > Or maybe it's time to call it ASDF 2.18 instead? > > —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org > > _______________________________________________ > asdf-devel mailing list > asdf-devel@common-lisp.net <mailto:asdf-devel@common-lisp.net> > http://lists.common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel
_______________________________________________ asdf-devel mailing list asdf-devel@common-lisp.net <mailto:asdf-devel@common-lisp.net> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel
I have my function, which does the described job for me too. The point here is to offer this functionality in public on an easy, standard way. Agreed.
Personally, I like to have a single defsystem sexp in the asd file, so I would prefer avoiding function definitions there. Same here. However, I would even more prefer having one generic mechanism for all these similar issues (wrapping bindings and environment-setup side-effects around compilation), rather than every time having to invent a new ad-hoc mechanism for each possible binding or side-effect that one might conceivably want:
However to do that nicely, asdf should be refactored in a way described by Robert. Not necessarily. It is often important to wrap code around compilation, as shown above, but after writing XCVB, it seems to be that it isn't so useful to have wrappers around subtrees of the build, unless you can somehow save the information to files after a build, and merge it from saved files when you skip the incremental compilation of a file that hasn't been modified. In other words, all the information should be inside
locally renaming packages binding *readtables* and other syntax-controlling variables handling warnings and other conditions proclaiming optimization settings saving code coverage information maintaining meta-data about compilation timings resetting gensym counters, PRNG seeds, etc., for determinism cheating the source-location and/or timestamping systems checking that some cleanup function was properly called etc. the FASL or a complement to said FASL. Otherwise, whatever information you use is just going to make your build less deterministic, and you'll end up always building from clean anyway, at which point you might as well use a load list instead of asdf.
But I think it would be still nice to offer this (cheap) renaming functionality separately without some heavy syntax (wrapping the whole defsystem into a function seems to be heavy for me).
A more interesting question would be: why not do that as originally intended, by defining a proper CLOS subclass of cl-source-file? If it isn't fully satisfactory, what would be, and what variant of CLOS would it take? (Say, would SHEEPLE make things nicer?)
it is fairly easy to implement into the current mainstream asdf version it is easy to use, so CL library developers could easily eliminate the :nicknames options from the package definitions and use this instead (they should basically change only a few lines of code in the .asd and package.lisp files) unfortunately, it is not the most general solution, so the arbitrary function wrapping would not be provided this way
I feel the 2nd point very valuable, so I think it would worth doing...
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Voting for liberty is like raping for virginity. — Jim Davidson
Hm, I like the idea of having multiple classes for cl-source-file objects. But I wouldn't do it through CLOS. Just playing around, something like this might be able to provide functionality to your problem. (defsystem com.host.my-system (:serial t) (:depends-on ("system-1" "system-2") (:components ((:file "file1") (:file "file2" :class 1) (:file "file3" :class 2) (:file "file4" :class 1)) (:before-compile 1 #'(lambda (component) (do what you want))) (:after-compile 1 #'(lambda (component) (do what you want))))) And class 0 could be the (unspecified) default. However, I would still prefer to have some kind of simplified notation for the local package renaming functionality as I think that is the most common. And I have no idea how difficult it is to put something like this into asdf as I am not familiar with its code... `bg` 2011/10/16 Faré <fahree@gmail.com>
I have my function, which does the described job for me too. The point here is to offer this functionality in public on an easy, standard way. Agreed.
Personally, I like to have a single defsystem sexp in the asd file, so I would prefer avoiding function definitions there. Same here. However, I would even more prefer having one generic mechanism for all these similar issues (wrapping bindings and environment-setup side-effects around compilation), rather than every time having to invent a new ad-hoc mechanism for each possible binding or side-effect that one might conceivably want:
locally renaming packages binding *readtables* and other syntax-controlling variables handling warnings and other conditions proclaiming optimization settings saving code coverage information maintaining meta-data about compilation timings resetting gensym counters, PRNG seeds, etc., for determinism cheating the source-location and/or timestamping systems checking that some cleanup function was properly called etc.
However to do that nicely, asdf should be refactored in a way described by Robert. Not necessarily. It is often important to wrap code around compilation, as shown above, but after writing XCVB, it seems to be that it isn't so useful to have wrappers around subtrees of the build, unless you can somehow save the information to files after a build, and merge it from saved files when you skip the incremental compilation of a file that hasn't been modified. In other words, all the information should be inside the FASL or a complement to said FASL. Otherwise, whatever information you use is just going to make your build less deterministic, and you'll end up always building from clean anyway, at which point you might as well use a load list instead of asdf.
But I think it would be still nice to offer this (cheap) renaming functionality separately without some heavy syntax (wrapping the whole defsystem into a function seems to be heavy for me).
A more interesting question would be: why not do that as originally intended, by defining a proper CLOS subclass of cl-source-file? If it isn't fully satisfactory, what would be, and what variant of CLOS would it take? (Say, would SHEEPLE make things nicer?)
it is fairly easy to implement into the current mainstream asdf version it is easy to use, so CL library developers could easily eliminate the :nicknames options from the package definitions and use this instead (they should basically change only a few lines of code in the .asd and package.lisp files) unfortunately, it is not the most general solution, so the arbitrary function wrapping would not be provided this way
I feel the 2nd point very valuable, so I think it would worth doing...
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Voting for liberty is like raping for virginity. — Jim Davidson
(defsystem com.host.my-system (:serial t) (:depends-on ("system-1" "system-2") (:components ((:file "file1") (:file "file2" :class 1) (:file "file3" :class 2) (:file "file4" :class 1)) (:before-compile 1 #'(lambda (component) (do what you want))) (:after-compile 1 #'(lambda (component) (do what you want)))))
Once again, :around compile is more general than :before and :after, and some of its functionality (e.g. binding, condition handling, unwind-protect, result filtering, etc.) just cannot be properly achieved with :before and :after methods. Also, some files may need special handling. For instance, the file that defines packages and/or helpers for a :around-compile function must not be wrapped by the function that depends on it. So it is not practical to have a system-wide default that cannot be overridden.
And class 0 could be the (unspecified) default. However, I would still prefer to have some kind of simplified notation for the local package renaming functionality as I think that is the most common. And I have no idea how difficult it is to put something like this into asdf as I am not familiar with its code...
I don't see how the numbering helps. Let's keep it with named classes when needed. As to how I'd implement it: I'd add an around-compile slot to component, with no :initform, an effective-around-compile generic function that handles "inheritance" from the parent when the slot is unbound, a (call-with-around-compile-hook component thunk) that does the wrapping based on the former gf, and use that use that function in the perform method for compile-op. —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Mathematics is the Queen of Science but she isn't very Pure; she keeps having babies by handsome young upstarts and various frog princes. — Donald Kingsbury (In "psychohistorical crisis", 2001)
I think the divergence is coming from the fact that I want a special functionality (package renaming) with a simple syntax and you want a general functionality which cannot be represented by a simple syntax. So it is a tradeoff between simple syntax and general functionality. As package renaming is already available in a "complex" way, providing another complex way won't improve on its popularity. If it would be possible just with a few more characters in an asd file, people might use it. Otherwise if they have to create different functions, classes in separate files for that, they just keep providing nicknames... But I am wondering how an asd file would look like with your scenario. Can you provide an example? Btw, I imagine before/after implemented in a setup/cleanup style, so if compilation fails, cleanup (after) still runs. So it is wrapped in an unwind-protect. So the before/after is nothing to do with generic functions in my view. It is just a wrapping around COMPILE-FILE. `bg` 2011/10/17 Faré <fahree@gmail.com>
(defsystem com.host.my-system (:serial t) (:depends-on ("system-1" "system-2") (:components ((:file "file1") (:file "file2" :class 1) (:file "file3" :class 2) (:file "file4" :class 1)) (:before-compile 1 #'(lambda (component) (do what you want))) (:after-compile 1 #'(lambda (component) (do what you want)))))
Once again, :around compile is more general than :before and :after, and some of its functionality (e.g. binding, condition handling, unwind-protect, result filtering, etc.) just cannot be properly achieved with :before and :after methods.
Also, some files may need special handling. For instance, the file that defines packages and/or helpers for a :around-compile function must not be wrapped by the function that depends on it. So it is not practical to have a system-wide default that cannot be overridden.
And class 0 could be the (unspecified) default. However, I would still prefer to have some kind of simplified notation for the local package renaming functionality as I think that is the most common. And I have no idea how difficult it is to put something like this into asdf as I am not familiar with its code...
I don't see how the numbering helps. Let's keep it with named classes when needed.
As to how I'd implement it: I'd add an around-compile slot to component, with no :initform, an effective-around-compile generic function that handles "inheritance" from the parent when the slot is unbound, a (call-with-around-compile-hook component thunk) that does the wrapping based on the former gf, and use that use that function in the perform method for compile-op.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Mathematics is the Queen of Science but she isn't very Pure; she keeps having babies by handsome young upstarts and various frog princes. — Donald Kingsbury (In "psychohistorical crisis", 2001)
2011/10/17 Gábor Balázs <gabalz@gmail.com>:
I think the divergence is coming from the fact that I want a special functionality (package renaming) with a simple syntax and you want a general functionality which cannot be represented by a simple syntax. So it is a tradeoff between simple syntax and general functionality.
No. I want to keep asdf.lisp minimal, yet provide hooks for other people to write extensions that do what they need to do without making it a mess. I am also writing those hooks with knowledge of how things are done or can be done in xcvb, which I believe follows a saner computation model, and which I hope will replace asdf someday. An around-compile hook is general enough that 1- you can implement whatever you want on top 2- it encourages a sane approach to controlling compilation Yet 3- it couldn't be done cleanly without a hook inside asdf.lisp. Indeed, you could have your own cl-source-file subclass and override perform, but you'd have to either copy/paste code from the default perform method, or lose the functionality and experience bitrot when it changes. Or you could try an :around method around perform, but you wouldn't be able to filter the results of compile-file based on e.g. a check of whether compile-time side-effects verified some invariant of yours (see what I mean with fare-utils/molicle/). Or you could try to bind *compile-op-compile-file-function*, but systems that do that would interfere badly with each other, and possibly with lower-level settings from e.g. ECL.
As package renaming is already available in a "complex" way, providing another complex way won't improve on its popularity. If it would be possible just with a few more characters in an asd file, people might use it. Otherwise if they have to create different functions, classes in separate files for that, they just keep providing nicknames...
I invite you to write a asdf-package-renaming extension to asdf, that does what you need, by defining your own cl-source-file extension and/or (preferrably) by using this new around-compile mechanism. Note: if you use the :around-compile facility, you might want to include in your defsystem a :depends-on ((:version :asdf "2.017.18")).
But I am wondering how an asd file would look like with your scenario. Can you provide an example?
See the test .asd file in the attached patch. Instead of binding the *read-base* it could call a function that uses unwind-protect to locally rename packages.
Btw, I imagine before/after implemented in a setup/cleanup style, so if compilation fails, cleanup (after) still runs. So it is wrapped in an unwind-protect. So the before/after is nothing to do with generic functions in my view. It is just a wrapping around COMPILE-FILE.
Therefore, you need an :around function anyway. Then why not expose the complete functionality? —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org If it's not worth doing, it's not worth doing well — Donald Hebb
NB: I committed this :around-compile feature with some minimal documentation as 2.017.18. —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Foreign aid might be defined as a transfer from poor people in rich countries to rich people in poor countries. — Douglas Casey
I don't see how can you manipulate things by defining subclasses of cl-source-file. I have to admit that I don't understand how components are created in asdf. My best guess (by looking at the class-for-type function) is that everything defined in the defsystem by :file and having .lisp extension becomes *default-component-class* which is cl-source-file. And I neither want to introduce a new syntax next to :file, nor change my lisp file extensions to something else. So I don't see how your components can become subclasses of cl-source-file at all. `bg` 2011/10/17 Faré <fahree@gmail.com>
NB: I committed this :around-compile feature with some minimal documentation as 2.017.18.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Foreign aid might be defined as a transfer from poor people in rich countries to rich people in poor countries. — Douglas Casey
This is how I would do the renaming (see attachment). So I wouldn't use around-compile as I want the renaming to be effective on cl-source-file. I also have to admit that there might be a more efficient way which would do this on the top level if there is any compilation in the plan. But I don't know how to implement that way. If you like it, I can finish the implementation... `bg` 2011/10/17 Gábor Balázs <gabalz@gmail.com>
I don't see how can you manipulate things by defining subclasses of cl-source-file.
I have to admit that I don't understand how components are created in asdf. My best guess (by looking at the class-for-type function) is that everything defined in the defsystem by :file and having .lisp extension becomes *default-component-class* which is cl-source-file.
And I neither want to introduce a new syntax next to :file, nor change my lisp file extensions to something else. So I don't see how your components can become subclasses of cl-source-file at all.
`bg`
2011/10/17 Faré <fahree@gmail.com>
NB: I committed this :around-compile feature with some minimal documentation as 2.017.18.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Foreign aid might be defined as a transfer from poor people in rich countries to rich people in poor countries. — Douglas Casey
I don't see how can you manipulate things by defining subclasses of cl-source-file.
(defpackage :my-system-system (:use :asdf :cl)) (in-package :my-system-system) (defclass my-cl-source-file (cl-source-file) ()) (defmethod perform ((op compile-op) (c my-cl-source-file)) ...) ;; wrapping! (defsystem :my-system :default-component-class my-cl-source-file :components ((cl-source-file "package") ;; override the new default, so this one isn't wrapped! (:file "macros" :depends-on ("package")) ...))
I have to admit that I don't understand how components are created in asdf. My best guess (by looking at the class-for-type function) is that everything defined in the defsystem by :file and having .lisp extension becomes *default-component-class* which is cl-source-file.
Yup. ASDF is really straightforward. Especially after all the refactoring we did for ASDF 2, for the only way we managed to make sense of the code we inherited was to simplify it. See also the article Robert and I wrote on ASDF: http://common-lisp.net/project/asdf/ilc2010draft.pdf
And I neither want to introduce a new syntax next to :file, nor change my lisp file extensions to something else. So I don't see how your components can become subclasses of cl-source-file at all.
Doing it with the new :around-compile feature, it would be: (defun my-package-frob-hook (thunk) (call-with-package-renamings '((long-name-1 shrtnm1) (long-name-2 shrtnm2)) (funcall thunk))) (defsystem :my-system :depends-on ((:version :asdf "2.017.18")) :around-compile my-package-frob-hook :components ((:file "package" :around-compile nil) ;; no frobbing around this one (:file "macros" :depends-on ("package")) ...)) —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org The reason why we must be tolerant is NOT that everyone is as right as everyone else. It is that no system allows to reliably distinguish right and wrong beforehand. Only by having the right to err can one have the right to be correct. The attitude of toleration is thus to let the fools be victims of their own folly rather than of ours, as long as they in turn do not impose their folly upon us. — Faré
:around-compile - wonderful solve of problem! Can add the :around-load for similar purpose? This it seems logical. Втр 18 Окт 2011 09:44:17 +0400, Far <fahree@gmail.com> написал:
I don't see how can you manipulate things by defining subclasses of cl-source-file.
(defpackage :my-system-system (:use :asdf :cl))
(in-package :my-system-system)
(defclass my-cl-source-file (cl-source-file) ())
(defmethod perform ((op compile-op) (c my-cl-source-file)) ...) ;; wrapping!
(defsystem :my-system :default-component-class my-cl-source-file :components ((cl-source-file "package") ;; override the new default, so this one isn't wrapped! (:file "macros" :depends-on ("package")) ...))
I have to admit that I don't understand how components are created in asdf. My best guess (by looking at the class-for-type function) is that everything defined in the defsystem by :file and having .lisp extension becomes *default-component-class* which is cl-source-file.
Yup. ASDF is really straightforward. Especially after all the refactoring we did for ASDF 2, for the only way we managed to make sense of the code we inherited was to simplify it. See also the article Robert and I wrote on ASDF: http://common-lisp.net/project/asdf/ilc2010draft.pdf
And I neither want to introduce a new syntax next to :file, nor change my lisp file extensions to something else. So I don't see how your components can become subclasses of cl-source-file at all.
Doing it with the new :around-compile feature, it would be:
(defun my-package-frob-hook (thunk) (call-with-package-renamings '((long-name-1 shrtnm1) (long-name-2 shrtnm2)) (funcall thunk)))
(defsystem :my-system :depends-on ((:version :asdf "2.017.18")) :around-compile my-package-frob-hook :components ((:file "package" :around-compile nil) ;; no frobbing around this one (:file "macros" :depends-on ("package")) ...))
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org The reason why we must be tolerant is NOT that everyone is as right as everyone else. It is that no system allows to reliably distinguish right and wrong beforehand. Only by having the right to err can one have the right to be correct. The attitude of toleration is thus to let the fools be victims of their own folly rather than of ours, as long as they in turn do not impose their folly upon us. — Faré
_______________________________________________ asdf-devel mailing list asdf-devel@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel
On Tue, Oct 18, 2011 at 10:22, Сергей Катревич <linkfly1@newmail.ru> wrote:
:around-compile - wonderful solve of problem! Can add the :around-load for similar purpose? This it seems logical.
Thanks for the appreciation! I think :around-load is a bad idea, for reasons that Juanjo and I mentioned previously in this discussion: it doesn't play well with the link model used by ECL, XCVB, FASL-concatenators, etc. The whole idea of a FASL is that it is fully formed and easy to load in a simple way; if wrapping is required around the load, then something wrong is happening. Is there any particular effect you think would be useful at load time that wouldn't be better done at compile-time? On the other hand, I now realize that load-source-op should probably heed the around-compile hook. —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org To authorize all commercial relations between consenting adults.
Is there any particular effect you think would be useful at load time that wouldn't be better done at compile-time?
The main application - monitoring changes in the Lisp system after loading the code (see attachment) Main concept code: (let ((old-all-packages (list-all-packages))) (load *test-file*) (set-difference (list-all-packages) old-all-packages)) i am don't know need whether add :around-load key, but need tracking changes in lisp image. Example: tracking new packages. Moreover, need to check that the component entities will provide such packages: (: file "somefile": provided (: packages (: pkg1: pkg2))) Втр 18 Окт 2011 18:41:59 +0400, Far <fahree@gmail.com> написал:
On Tue, Oct 18, 2011 at 10:22, Сергей Катревич <linkfly1@newmail.ru> wrote:
:around-compile - wonderful solve of problem! Can add the :around-load for similar purpose? This it seems logical.
Thanks for the appreciation!
I think :around-load is a bad idea, for reasons that Juanjo and I mentioned previously in this discussion: it doesn't play well with the link model used by ECL, XCVB, FASL-concatenators, etc. The whole idea of a FASL is that it is fully formed and easy to load in a simple way; if wrapping is required around the load, then something wrong is happening.
Is there any particular effect you think would be useful at load time that wouldn't be better done at compile-time?
On the other hand, I now realize that load-source-op should probably heed the around-compile hook.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org To authorize all commercial relations between consenting adults.
On Tue, Oct 18, 2011 at 16:50, Сергей Катревич <linkfly1@newmail.ru> wrote:
Is there any particular effect you think would be useful at load time that wouldn't be better done at compile-time?
The main application - monitoring changes in the Lisp system after loading the code (see attachment)
Main concept code: (let ((old-all-packages (list-all-packages))) (load *test-file*) (set-difference (list-all-packages) old-all-packages))
i am don't know need whether add :around-load key, but need tracking changes in lisp image. Example: tracking new packages.
Moreover, need to check that the component entities will provide such packages: (: file "somefile": provided (: packages (: pkg1: pkg2)))
Oh, package management in the context of ASDF: tricky! Indeed, packages are typically created a compile-time, while compiling your package.lisp file or equivalent. So there should be no package created while loading -- at least when building from clean, because when you're doing an incremental compilation, the package will instead be created by loading the package.fasl. Therefore, your around-load package tracking will not be deterministic in a compiled from clean vs incrementally compiled scenario. around-compile package tracking will work perfectly from clean, and from incremental compilation too if you save and restore state to files. Another solution would be to wrap around an entire system: it usually makes sense what packages are created by loading a system. Unhappily, ASDF does not make it easy at all to separate a system from its dependencies (though it's not conceptually impossible either). But yes, I understand what you mean in general by tracking change. However, this is probably something you want to do as part of an ASDF extension, with a defmethod perform :around ((op load-op) (c cl-source-file)) so it affects your entire image, rather than a patch that adds your tracking :around-load to each and every system you use to use. —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org
Here is the implementation for call-with-package-renamings (see attachment). I also attached its test case. I successfully tested this on ccl, scl and clisp. The run-tests.sh script didn't work for me with sbcl (conflicted with my system settings), so I skipped that... Best, `bg` 2011/10/17 Faré <fahree@gmail.com>
I don't see how can you manipulate things by defining subclasses of cl-source-file.
(defpackage :my-system-system (:use :asdf :cl))
(in-package :my-system-system)
(defclass my-cl-source-file (cl-source-file) ())
(defmethod perform ((op compile-op) (c my-cl-source-file)) ...) ;; wrapping!
(defsystem :my-system :default-component-class my-cl-source-file :components ((cl-source-file "package") ;; override the new default, so this one isn't wrapped! (:file "macros" :depends-on ("package")) ...))
I have to admit that I don't understand how components are created in asdf. My best guess (by looking at the class-for-type function) is that everything defined in the defsystem by :file and having .lisp extension becomes *default-component-class* which is cl-source-file.
Yup. ASDF is really straightforward. Especially after all the refactoring we did for ASDF 2, for the only way we managed to make sense of the code we inherited was to simplify it. See also the article Robert and I wrote on ASDF: http://common-lisp.net/project/asdf/ilc2010draft.pdf
And I neither want to introduce a new syntax next to :file, nor change my lisp file extensions to something else. So I don't see how your components can become subclasses of cl-source-file at all.
Doing it with the new :around-compile feature, it would be:
(defun my-package-frob-hook (thunk) (call-with-package-renamings '((long-name-1 shrtnm1) (long-name-2 shrtnm2)) (funcall thunk)))
(defsystem :my-system :depends-on ((:version :asdf "2.017.18")) :around-compile my-package-frob-hook :components ((:file "package" :around-compile nil) ;; no frobbing around this one (:file "macros" :depends-on ("package")) ...))
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org The reason why we must be tolerant is NOT that everyone is as right as everyone else. It is that no system allows to reliably distinguish right and wrong beforehand. Only by having the right to err can one have the right to be correct. The attitude of toleration is thus to let the fools be victims of their own folly rather than of ours, as long as they in turn do not impose their folly upon us. — Faré
1- I don't think asdf.lisp itself is the right place for this function, although if someone starts a formal asdf-contrib system, it should definitely be there. 2- For extra brownies, you ought to handle arbitrary nickname conflicts, and properly restore things afterwards. You can assume no conflict in the initial state, and have the function return a list of the reverse changes, that you'd apply on the other side of the unwind-protect. —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org 2011/10/18 Gábor Balázs <gabalz@gmail.com>:
Here is the implementation for call-with-package-renamings (see attachment). I also attached its test case. I successfully tested this on ccl, scl and clisp. The run-tests.sh script didn't work for me with sbcl (conflicted with my system settings), so I skipped that...
Best, `bg`
Sorry for the duplicate. I set the function definitions to defun*, whatever it means. :) Plus I changed the name to call-with-package-nicknames as it never renames any package, just set extra nicknames. I think it is a better name, you can choose... `bg` 2011/10/18 Gábor Balázs <gabalz@gmail.com>
Here is the implementation for call-with-package-renamings (see attachment). I also attached its test case. I successfully tested this on ccl, scl and clisp. The run-tests.sh script didn't work for me with sbcl (conflicted with my system settings), so I skipped that...
Best, `bg`
2011/10/17 Faré <fahree@gmail.com>
I don't see how can you manipulate things by defining subclasses of cl-source-file.
(defpackage :my-system-system (:use :asdf :cl))
(in-package :my-system-system)
(defclass my-cl-source-file (cl-source-file) ())
(defmethod perform ((op compile-op) (c my-cl-source-file)) ...) ;; wrapping!
(defsystem :my-system :default-component-class my-cl-source-file :components ((cl-source-file "package") ;; override the new default, so this one isn't wrapped! (:file "macros" :depends-on ("package")) ...))
I have to admit that I don't understand how components are created in asdf. My best guess (by looking at the class-for-type function) is that everything defined in the defsystem by :file and having .lisp extension becomes *default-component-class* which is cl-source-file.
Yup. ASDF is really straightforward. Especially after all the refactoring we did for ASDF 2, for the only way we managed to make sense of the code we inherited was to simplify it. See also the article Robert and I wrote on ASDF: http://common-lisp.net/project/asdf/ilc2010draft.pdf
And I neither want to introduce a new syntax next to :file, nor change my lisp file extensions to something else. So I don't see how your components can become subclasses of cl-source-file at all.
Doing it with the new :around-compile feature, it would be:
(defun my-package-frob-hook (thunk) (call-with-package-renamings '((long-name-1 shrtnm1) (long-name-2 shrtnm2)) (funcall thunk)))
(defsystem :my-system :depends-on ((:version :asdf "2.017.18")) :around-compile my-package-frob-hook :components ((:file "package" :around-compile nil) ;; no frobbing around this one (:file "macros" :depends-on ("package")) ...))
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org The reason why we must be tolerant is NOT that everyone is as right as everyone else. It is that no system allows to reliably distinguish right and wrong beforehand. Only by having the right to err can one have the right to be correct. The attitude of toleration is thus to let the fools be victims of their own folly rather than of ours, as long as they in turn do not impose their folly upon us. — Faré
Gabor, why don't you start a contrib/asdf-contrib.asd system under the asdf tree, or as another project? Also, a better version of with-package-nicknames would handle conflicts with the main name of some packages, that could even be shadowed, and rotation of nicknames between packages as well. —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org The sunlights differ, but there is only one darkness. — Ursula K. LeGuin, "The Dispossessed" There are 40 kinds of lunacy, but only one kind of common sense. — African proverb 2011/10/19 Gábor Balázs <gabalz@gmail.com>:
Sorry for the duplicate. I set the function definitions to defun*, whatever it means. :) Plus I changed the name to call-with-package-nicknames as it never renames any package, just set extra nicknames. I think it is a better name, you can choose...
2011/10/18 Faré <fahree@gmail.com>
Gabor, why don't you start a contrib/asdf-contrib.asd system under the asdf tree, or as another project?
Well, I think one of the biggest strength of asdf, that it is only one file. You just ship that file, and it is there, does the job for you. With multiple files, you don't have this "portability", and workarounds will win against such a contrib library. And personally, I am not so interested in managing such a library. When I read about this package nickname problem, and solved in a way for my library set, I just thought asdf would be a right place to handle this uniformly by faking the missing "use-as" functionality of depackage. So it would be cheaply available for anyone (as I think most of the lisp library uses asdf). But this might be just my feeling... I can live with that... :) Also, a better version of with-package-nicknames
would handle conflicts with the main name of some packages, that could even be shadowed, and rotation of nicknames between packages as well.
Yes, it is true, but I think these are not so frequent cases, so the functionality could be quite useful in its simple pure state. Of course you could push it further as you say. An then even further by supporting parallel compilations scenarios, or by substituting package designators by string replacements in source files as a last resort. But I think the people who really need this are minority.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org The sunlights differ, but there is only one darkness. — Ursula K. LeGuin, "The Dispossessed" There are 40 kinds of lunacy, but only one kind of common sense. — African proverb
2011/10/19 Gábor Balázs <gabalz@gmail.com>:
Sorry for the duplicate. I set the function definitions to defun*,
whatever
it means. :) Plus I changed the name to call-with-package-nicknames as it never renames any package, just set extra nicknames. I think it is a better name, you can choose...
I think that asdf is a big enough system in order to start its division. But have to single file asdf.lisp - it is convenient. I propose to take advantage of both approaches: concated many files into asdf.lisp (for example: utils.lisp + pathnames-utils.lisp + planning-operations.lisp + ... = asdf.lisp). Such as is done in jquery (https://github.com/jquery/jquery). Срд 19 Окт 2011 09:03:03 +0400, Gbor Balzs <gabalz@gmail.com> написал:
2011/10/18 Faré <fahree@gmail.com> Gabor, why don't you start a contrib/asdf-contrib.asd system under the asdf tree, or as another project?
Well, I think one of the biggest strength of asdf, that it is only one file. You just ship that file, and it is there, does the job for you. With multiple files, you don't have this "portability", and workarounds will win against such a contrib library.
And personally, I am not so interested in managing such a library. When I read about this package nickname problem, and solved in a way for my library set, I just thought asdf would be a right place to handle this uniformly by faking the missing "use-as" functionality of depackage. So it would be cheaply available for anyone (as I think most of the lisp library uses asdf). But this might be just my feeling... I can live with that... :)
Also, a better version of with-package-nicknames would handle conflicts with the main name of some packages, that could even be shadowed, and rotation of nicknames between packages as well.
Yes, it is true, but I think these are not so frequent cases, so the functionality could be quite useful in its simple pure state. Of course you could push it further as you say. An then even further by supporting parallel compilations scenarios, or by substituting package designators by string replacements in source files as a last resort. But I think the people who really need this are minority.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org
The sunlights differ, but there is only one darkness. — Ursula K. LeGuin, "The Dispossessed" There are 40 kinds of lunacy, but only one kind of common sense. — African proverb
2011/10/19 Gábor Balázs <gabalz@gmail.com>:
Sorry for the duplicate. I set the function definitions to defun*, whatever it means. :) Plus I changed the name to call-with-package-nicknames as it never renames any package, just set extra nicknames. I think it is a better name, you can choose...
On Wed, Oct 19, 2011 at 21:36, Сергей Катревич <linkfly1@newmail.ru> wrote:
I think that asdf is a big enough system in order to start its division. But have to single file asdf.lisp - it is convenient. I propose to take advantage of both approaches: concated many files into asdf.lisp (for example: utils.lisp + pathnames-utils.lisp + planning-operations.lisp + ... = asdf.lisp). Such as is done in jquery (https://github.com/jquery/jquery).
This has been proposed before, but was not done, because 1- there are currently no situation where concatenating files is practical. 2- the one only situation where we want everything in one file is for bootstrapping purposes, and in that situation, we want the file minimal, so we need to distribute a small file that doesn't change more often than it needs to, or takes more resources than needed in slow loading implementations. 3- when editing such a minimal file, there is little to be gained with splitting into multiple files. It's 4275 lines including plenty of comments. That's still quite manageable. Scripts to either keep it together or apart are not so manageable. But once again, an asdf-contrib add-on module sounds great, and with today's technology, particularly quicklisp, it should be really easy to distribute. —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org A president worth voting for wouldn't run for office.
Ok, minimizing of asdf.lisp and placing (and probably moving to) additional functionality in the asdf-contrib - looks good. Чтв 20 Окт 2011 09:17:42 +0400, Far <fahree@gmail.com> написал:
On Wed, Oct 19, 2011 at 21:36, Сергей Катревич <linkfly1@newmail.ru> wrote:
I think that asdf is a big enough system in order to start its division. But have to single file asdf.lisp - it is convenient. I propose to take advantage of both approaches: concated many files into asdf.lisp (for example: utils.lisp + pathnames-utils.lisp + planning-operations.lisp + ... = asdf.lisp). Such as is done in jquery (https://github.com/jquery/jquery).
This has been proposed before, but was not done, because 1- there are currently no situation where concatenating files is practical. 2- the one only situation where we want everything in one file is for bootstrapping purposes, and in that situation, we want the file minimal, so we need to distribute a small file that doesn't change more often than it needs to, or takes more resources than needed in slow loading implementations. 3- when editing such a minimal file, there is little to be gained with splitting into multiple files. It's 4275 lines including plenty of comments. That's still quite manageable. Scripts to either keep it together or apart are not so manageable.
But once again, an asdf-contrib add-on module sounds great, and with today's technology, particularly quicklisp, it should be really easy to distribute.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org A president worth voting for wouldn't run for office.
participants (4)
-
Faré
-
Gábor Balázs
-
Robert Goldman
-
Сергей Катревич