Suggested enhancement: a :do-first keyword for defining systems

Daniel Weinreb <[email protected]>
Newsgroups gmane.lisp.cclan.general
Message-ID <[email protected]>
I would like to suggest a slight enhancement to asdf: the ability to
specify :do-first dependencies in system declarations.  The change has
both practical and pedagogical benefits.

Here is a practical application.  Suppose I have a pre-processor that
takes a file named, e.g., "foo.xyz" and produces "foo.lisp" from it.
But it's not just a simple pre-processor.  It's an extensible
pre-processor that allows you to customize its behavior by
writing Lisp code.

So I have a bunch of ".xyz" files, and a file called "aux.lisp" that
contains auxiliary functions that the preprocessor uses for my
particular ".xyz" files.  I define a new component class called
xyz-source-file, based on source-file, and a new operation class
called preproc-op whose perform method runs the preprocessor.  I want
to define a system that can turn the ".xyz" files into ".lisp" files.
To do that, they need for "aux.fasl" to be loaded.

I use an ordinary :in-order-to dependency for each of the generated
".lisp" files to say that it is dependent on its corresponding ".xyz"
file.

I also want to say that these transformations are dependent on
"aux.fasl" being loaded.

If all of the ".lisp" files already exist, and each of them has a
creation date greater than that of their corresponding ".xyz" file,
then there is no work to be done, and I do not want "aux.fasl" to be
loaded, since it is not needed.

To obtain this effect, I need to express the dependence on "aux.fasl"
using a :do-first dependency rather than an :in-order-to dependency.
If I use :in-order-to, "aux.fasl" will be loaded unnecessarily.

There is also a pedagogical reason.  Talking to my co-workers, I find
that there is some confusion about exactly what :depends-on means.  In
reality, down inside asdf, the decision making is really driven by the
two kinds of dependencies (:in-order-to and :do-first).  Once you
understand what these two are -- and I think you need to understand
them in order to do what I suggested above -- then you can explain
:depends-on very precisely by expressing it in terms of :in-order-to
and :do-first.  :depends-on is essentially a kind of specialized
"macro" that "expands" into the two kinds of dependency.  By
explaining :depends-on in this way, you can completely explain its
behavior.

Here is the suggested change:

*** asdf.lisp	Thu Sep 21 22:23:01 2006
--- do-first-asdf.lisp	Thu Oct  5 01:08:46 2006
***************
*** 1004,1010 ****
                components pathname default-component-class
                perform explain output-files operation-done-p
                weakly-depends-on
!               depends-on serial in-order-to
                ;; list ends
                &allow-other-keys) options
      (check-component-input type name weakly-depends-on
                             depends-on components in-order-to)
--- 1004,1010 ----
                components pathname default-component-class
                perform explain output-files operation-done-p
                weakly-depends-on
!               depends-on serial in-order-to do-first
                ;; list ends
                &allow-other-keys) options
      (check-component-input type name weakly-depends-on 
                             depends-on components in-order-to)
***************
*** 1067,1073 ****
               in-order-to
               `((compile-op (compile-op ,@depends-on))
                 (load-op (load-op ,@depends-on))))
!             (slot-value ret 'do-first) `((compile-op (load-op ,@depends-on))))
  
        (loop for (n v) in `((perform ,perform) (explain ,explain)
                             (output-files ,output-files)
--- 1067,1076 ----
               in-order-to
               `((compile-op (compile-op ,@depends-on))
                 (load-op (load-op ,@depends-on))))
!             (slot-value ret 'do-first)
! 	    (union-of-dependencies
! 	     do-first
! 	     `((compile-op (load-op ,@depends-on)))))
  
        (loop for (n v) in `((perform ,perform) (explain ,explain)
                             (output-files ,output-files)

-- Dan Weinreb



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.