Commit 69bbe281 authored by Robert P. Goldman's avatar Robert P. Goldman
Browse files
parents dc5cee32 9414c493
......@@ -48,13 +48,6 @@
Publisher = {Springer}
}
Article{XCVB,
Author = {Fran\c{c}ois-Ren\'{e} Rideau and Spencer Brody},
Title = {{XCVB}: Improving Modularity for {C}ommon {L}isp},
Booktitle={International Lisp Conference},
URL="http://common-lisp.net/projects/xcvb/",
Year = {2009}
}
@InProceedings{XCVB,
author = {Fran\c{c}ois-Ren\'{e} Rideau and Spencer Brody},
title = {{XCVB}: an {eXtensible} {Component} {Verifier} and {Builder}
......@@ -172,7 +165,7 @@ Article{XCVB,
number = {4},
year = {1979},
pages = {255-65},
bibsource = {DBLP, http://dblp.uni-trier.de}
bibsource = {DBLP, http://dblp.uni-trier.de/}
}
@Article{Sidebotham98,
......@@ -186,6 +179,5 @@ Article{XCVB,
@Misc{scons,
key = {SCons},
title = {SCons website},
url = {www.scons.org}}
url = {http://www.scons.org/}
}
......@@ -64,7 +64,7 @@ such as distributing software, managing bugs, connecting people,
solving dependency versioning issues (aka ``DLL hell''), etc.
\subsection{Analogy with \texttt{make}} % {\make} looks weird here
\subsection{Analogy with {\large \make}}
\label{sec:analogy-with-make}
It is conventional to explain {\ASDF} as the {\CL} analog of {\make}~\cite{Feldman79}:
......@@ -107,12 +107,12 @@ simple pattern matching rules used by an inference engine
that will run simply parameterized shell scripts.
{\make} is a powerful tool that can express arbitrary programs,
but the result is a mesh of code that defies any simple analysis.
{\ASDF} is a small \CL{} program,
{\ASDF} is a small {\CL} program,
and its system definitions are data rather than programs.
Any non-trivial code required by an \ASDF{} system definition
has to be expressed either as an extension to {\ASDF}
or as ancillary method definitions for one of the generic functions
that defines the \ASDF{} protocol.
Any non-trivial code required by an {\ASDF} system definition
has to be expressed as an extension to {\ASDF},
typically as method definitions for one of the generic functions
that defines the {\ASDF} protocol.
Executing code in the components being built is natural with {\ASDF}
and not with {\make} because,
......@@ -121,26 +121,31 @@ the {\CL} compiler and loader are imperative languages.
When building C programs, side-effects therefore have to be specified
in a different language, typically the shell.
When building {\CL} programs,
side-effects can be written in Lisp itself.
side-effects are written in Lisp itself.
Being able to do everything in Lisp without cross-language barriers
is a conceptual simplification;
however, you pay a price in side-effects.
however, you pay a price for using side-effects.
% I don't believe the following helps the reader a lot, and our purpose is only
% to explain make to the extent that it helps understand ASDF... [2010/08/23:rpg]
% On the one hand, this means that {\ASDF} itself
% is much less powerful than {\make}, and
% offers very restricted system definition language.
% On the other hand, {\ASDF} is part of a whole
% that is just as powerful as {\make},
% and the strictures of system definitions allow for
% semantically richer analysis and manipulation of such,
% with tools such as automatic packagers.
\hide{
\rtof{I don't believe the following helps the reader a lot, and our purpose is only
to explain make to the extent that it helps understand ASDF... [2010/08/23:rpg]}
On the one hand, this means that {\ASDF} itself
is much less powerful than {\make}, and
offers very restricted system definition language.
On the other hand, {\ASDF} is part of a whole
that is just as powerful as {\make},
and the strictures of system definitions allow for
semantically richer analysis and manipulation of such,
with tools such as automatic packagers.
}
A final difference between \ASDF{} and \make{}, which we will discuss more in
Section~\ref{sec:traverse-bug-fix}, is that \ASDF{} builds a full plan for its
operations before executing them. By contrast, \make{} performs actions eagerly
during a traversal of its dependency tree~\cite{AITR-874}.
A final difference between {\ASDF} and {\make}
is that {\ASDF} generates a full plan of the actions required
to fulfill all the dependencies of its goal
before performing the planned actions.
By contrast, {\make} performs actions
as it traverses its dependency tree~\cite{AITR-874}.
We will discuss this further in Section~\ref{sec:plan-generation},
\subsection{Basic {\ASDF} object model}
......@@ -170,7 +175,7 @@ during a traversal of its dependency tree~\cite{AITR-874}.
(:file "goodbye")))))
\end{verbatim}
\end{minipage}
\caption{Sample {\ASDF} system definition, adapted from ASDF manual.}
\caption{Sample {\ASDF} system definition.}
\label{fig:sampleASD}
\end{figure}
......@@ -203,7 +208,7 @@ This is done by the generic function \lisp{find-system}, which searches
for the system definition in a configurable system registry
(and its in-memory cache).
The system definition search is one of the aspects of {\ASDFi} that we reformed;
the previous protocol had to be initialized using arbitrary lisp code,
the previous protocol had to be initialized using arbitrary Lisp code,
and had a number of undesirable features.
See Section \ref{sec:input-locations}.
{\operate} then generates a \emph{plan} for completing the {\operation}
......@@ -220,6 +225,7 @@ making it easy to fix simple mistakes without interrupting the build.
\subsection{Plan generation}
\label{sec:plan-generation}
The semantics of an {\ASDF} system definition only specifies
ordering dependencies between build steps
......@@ -339,12 +345,12 @@ We discuss this further in Section \ref{sec:future-directions}.
\rtof{
I don't believe that's correct. The rules in the makefile are not the
plan --- they are the pieces out of which a plan is assembled (if \make{}
plan --- they are the pieces out of which a plan is assembled (if {\make}
plans; I am not convinced this is the case). The parallel is the system definition in
\ASDF{}. That is not a plan; that is what the plan is assembled out of. For
example, if I ask \ASDF{} to do a load-op on a system, it will first build a
{\ASDF}. That is not a plan; that is what the plan is assembled out of. For
example, if I ask {\ASDF} to do a load-op on a system, it will first build a
plan, an ordered sequence of operation - component pairs. \emph{Then} it will
execute that plan. I don't believe that \make{} does anything like this. In
execute that plan. I don't believe that {\make} does anything like this. In
fact, I don't understand how make actually does its job. Similarly, I can
have a bunch of rules about how to build the pdf of the ASDF doc from texinfo, but those
rules will not be part of the plan if I ask make to build the html version of
......
......@@ -20,7 +20,7 @@
% }
% \draft{Symbolics \defsys{} here... Kantrowitz claims that it is a
% \draft{Symbolics {\defsys} here... Kantrowitz claims that it is a
% \emph{procedural}, rather than a structural system definition tool. Cites the
% BUILD system~\cite{AITR-874} as a structural tool.}
......@@ -30,7 +30,7 @@
% \begin{itemize}
% \item More declarative than other systems;
% \item Declarative specification of transformations between \emph{grains} (not
% offered by various flavors of \defsys{}.
% offered by various flavors of {\defsys}.
% \item Clear treatment of distinction between macro dependencies (compile-time)
% and call dependencies (run-time --- load time in our jargon).
% \item Dependencies are described directly, rather than in terms of system
......@@ -43,41 +43,41 @@
% \end{itemize}
% }
A key inspiration for ASDF was \mkdefsys{}, Mark Kan\-tro\-witz's portable
\defsys{} facility~\cite{kantrowitz:91}. At the time when \mkdefsys{}
A key inspiration for ASDF was {\mkdefsys}, Mark Kan\-tro\-witz's portable
{\defsys} facility~\cite{kantrowitz:91}. At the time when {\mkdefsys}
was developed, there was no portable, non-proprietary system definition
facility for {\CL}, as Lisp moved off special-purpose platforms and onto
general-purpose hardware. Prior to this (and substantially prior to a true
\emph{Common} Lisp), there were a number of different system-defining
facilities, notably the Symbolics \defsys{}~\cite{CHINE-NUAL}\footnote{Cited by Robbins~\cite{AITR-874}}, but people wanting to
facilities, notably the Symbolics {\defsys}~\cite{CHINE-NUAL}\footnote{Cited by Robbins~\cite{AITR-874}}, but people wanting to
portably define systems had to rely on \lisp{LOAD} scripts and/or
\lisp{REQUIRE}.
The \ASDF{} manual~\cite{ASDF-Manual}, discussing \mkdefsys{} as an inspiration,
explains that it was intended to better use \CL{} features (notably CLOS) for
extensibility. \mkdefsys{} is written in pre-CLOS \CL{}. However, we argue
that a primary reason for \ASDF{}'s success was not its CLOS architecture, but
The {\ASDF} manual~\cite{ASDF-Manual}, discussing {\mkdefsys} as an inspiration,
explains that it was intended to better use {\CL} features (notably CLOS) for
extensibility. {\mkdefsys} is written in pre-CLOS {\CL}. However, we argue
that a primary reason for {\ASDF}'s success was not its CLOS architecture, but
its elegant use of \lisp{*load-truename*} to solve the social problem of
installing and referencing lisp libraries. The problem of \emph{installing}
lisp libraries was not helped by \mkdefsys{}, but was substantially eased by \ASDF{}.
installing and referencing Lisp libraries. The problem of \emph{installing}
lisp libraries was not helped by {\mkdefsys}, but was substantially eased by {\ASDF}.
See
Section~\ref{sec:input-locations} for more discussion of this issue.
BUILD~\cite{AITR-874} was a substantially earlier Lisp build system (antedating
\CL{}), and an inspiration behind \mkdefsys{}.
BUILD attempted to be more declarative than \make{} and other predecessors. It
{\CL}), and an inspiration behind {\mkdefsys}.
BUILD attempted to be more declarative than {\make} and other predecessors. It
\emph{may} have introduced the notion of creating a complete operation plan
before executing any operations; we are not certain.
% \draft{Too-specific notes on \mkdefsys{} that need to be winnowed for the
% \draft{Too-specific notes on {\mkdefsys} that need to be winnowed for the
% paper....
% Some key ideas present in \mkdefsys{}:
% Some key ideas present in {\mkdefsys}:
% \begin{itemize}
% \item parametric \texttt{operate-on-system} function.
% \item selective recompilation to minimize work
% \item declarative system spec --- specify dependencies and components;
% \mkdefsys{} infers the procedure.
% {\mkdefsys} infers the procedure.
% \item intended to be extensible
% \item Use of Unix pathnames as de facto standard --- portability across unix
% and mac was punted to logical pathnames.
......@@ -87,7 +87,7 @@ before executing any operations; we are not certain.
% \emph{Not} present:
% \begin{itemize}
% \item Clever use of \texttt{*load-truename*} to locate source files. The
% problem of \emph{installing} systems was not helped by \mkdefsys{}. At the
% problem of \emph{installing} systems was not helped by {\mkdefsys}. At the
% top, \texttt{:SYSTEM}s had to have absolute pathnames.
% \item Automatic placement of binary files. I believe this had to be handled
% through use of conditional compilation (reader macros) combinated with
......@@ -103,7 +103,7 @@ before executing any operations; we are not certain.
% Features not taken over into ASDF:
% \begin{itemize}
% \item \mkdefsys{} had \texttt{:PRIVATE-FILE} as a component type that
% \item {\mkdefsys} had \texttt{:PRIVATE-FILE} as a component type that
% could be used for, e.g., user-specific configuration files.
% \item You can do package-wrangling in the system definition, instead of coding
% package into files.
......
......@@ -47,6 +47,7 @@
\newcommand{\ASDF}{ASDF}
\newcommand{\ASDFi}{ASDF\,1}
\newcommand{\ASDFii}{ASDF\,2}
\newcommand{\ASDFiii}{ASDF\,3}
\newcommand{\POIU}{POIU}
\newcommand{\longABL}{\texttt{ASDF-Binary-Locations}}
\newcommand{\ABL}{\texttt{A-B-L}}
......@@ -95,15 +96,10 @@
%\terms term1, term2
\keywords
Common Lisp, build infrastructure, interaction design, code evolution.
Common Lisp, build infrastructure, interaction design, code evolution, dynamic code update.
%\onecolumn % Single column. - for debugging only
\fixme{During final pass, harmonize capitalization. ``lisp'' all either
capitalized or not. Lisp function name capitalization also harmonized (the
\texttt{\\lisp} macro should help here) -- should these names all be capitalized
or all downcased?}
\section{Introduction}
\fixme{Propose we revise this after we've thrashed out the rest of the paper, to
......@@ -111,7 +107,7 @@ make sure it lines up.}
{\ASDFii} is the current version of {\ASDF},
``Another System Definition Facility'' \cite{ASDF-Manual}.
{\ASDF} allows {\longCL} (\CL{}) developers to specify
{\ASDF} allows {\longCL} ({\CL}) developers to specify
how to build their software from components,
a task for which C developers would typically use {\make}.
% \rtof{
......@@ -164,16 +160,17 @@ that reduces problematic interactions.
In this paper we discuss a number of interesting technical and social challenges
that we had to face while developing the new version of {\ASDF},
and the lessons we learned.
\fixme{Add a note to say that we didn't just plunge in and change everything.}
%\fixme{Add a note to say that we didn't just plunge in and change everything.}
\fixme{Before submission make sure we update the roadmap.}
The paper is divided in several sections.
After this introduction comes
a presentation of the essential yet non-functional changes we made
a presentation of what {\ASDF} does and how it does it.
Then we explain the essential yet non-functional changes we made
to achieve the hot upgrade of {\ASDF} code.
Next we discuss the semantic changes we made to the user-visible API,
extensions and restrictions.
Then we discuss how software engineering best practices
Thereon we discuss how software engineering best practices
applied to our endeavour.
Finally, we explain how our software relates to other efforts
and briefly discuss possible future improvements.
......@@ -252,7 +249,7 @@ Even adopting this expedient, programmers
would often fail to produce a portable system definition,
because of the subtle semantics of \lisp{merge-pathnames}.
In particular, common, apparently reasonably definitions would
work on Unix platforms yet fail spectacularly on Windows machines,
work on Unix platforms yet could fail spectacularly on Windows machines,
yielding pathnames with the wrong host and device.
This would happen because of the way
\lisp{make-pathname} inherits host and device slots
......@@ -338,13 +335,13 @@ when packages were added, removed, or moved.
Another strategy, used by one of us (Goldman) was to write a specialized,
portable version of the Unix \texttt{find} utility, that would find \file{.asd}
files.
Using such a utility, one could easily initialize \ASDFi{}'s
Using such a utility, one could easily initialize {\ASDFi}'s
\lisp{*central-registry*} from, for example, the top-level working directory
for a project's revision control system. In turn, that made it possible for a
project team to get a consistent, shared \ASDF{} configuration by loading a
project team to get a consistent, shared {\ASDF} configuration by loading a
single file, without the clumsy expedient of a ``link farm'' (difficult to
maintain), and making it possible for programmers easily to change between
different project-specific \ASDF{} configurations.
different project-specific {\ASDF} configurations.
In a somewhat simpler expedient,
ITA used a directory of \file{.../**/*.asd} to locate all relevant directories
to push to the central registry.
......@@ -497,7 +494,7 @@ We gave it a sensible default configuration
that redirected the output of compiled files to
an implementation-dependent path under the user's home directory,
following the model of {\CLLaunch} but with improvements: {\newline}
\file{\~{}/.cache/common-lisp\discretionary{/}{}{/}\emph{imple\-men\-ta\-tion-id}/\emph{source-path}}
{\file\~{}/.cache/common-lisp\discretionary{/}{}{/}\emph{imple\-men\-ta\-tion-id}/\emph{source-path}}
{\newline}
For example:
\begin{flushleft}
......@@ -533,23 +530,6 @@ to \moneyquote{fail early for everyone rather than pass as working for some}
and then fail for others.
\subsection{Finding data files}
\label{sec:finding-data-files}
One extension related to input and output locations is the question of how to
find files that were distributed with an \ASDF{} system, such as data files.
A system containing code that wished to find such files to read \emph{at run
time}, often encountered difficulties as code that, for example, attempted to
use \lisp{*load-truename*} would be foiled by \ABL{} or \AOT{}. There were
work-arounds, typically involving the use of \lisp{*load-truename*} in a
system's \file{.asd} file to initialize a global variable, but these were
cumbersome and black art that needed to be reinvented over and over. We have
added \lisp{system-relative-pathname} to the \ASDF{} api to make this easier.
\subsection{Decentralized Configuration}
As opposed to the previous central registry,
......@@ -638,7 +618,7 @@ as well as a full-featured Lisp syntax,
in the hope of keeping everyday system administration simple.
All this work on configuration, while technically simple,
almost doubled the size of {\ASDF};
significantly increased the size of {\ASDF};
but it was well worth it, because
this \textbf{allows each one to contribute what he knows when he knows it,
and does not require one to contribute what one doesn't know}.
......@@ -663,8 +643,32 @@ smoothing the need for synchronization between experts
and lowering the barriers to entry for newbies.
\section{Fixing \texttt{traverse}}
\label{sec:bug-fixes}
\subsection{Finding data files}
\label{sec:finding-data-files}
An extension related to pathnames above as well as
to input and output locations
is the question of
how to find files that were distributed with an {\ASDF} system,
such as data files.
A system containing code that wished to find such files
for use \emph{at run time}, often encountered difficulties:
code that, for example, attempted to use \lisp{*load-pathname*}
would be foiled by {\ABL} or {\AOT}.
There were workarounds, typically involving
the use of \lisp{(or *compile-file-pathname* *load-pathname*)},
or the definition of a global variable based on \lisp{*load-truename*}
in a system's \file{.asd} file;
but these were cumbersome and black art
that needed to be reinvented over and over.
We have added \lisp{system-relative-pathname} to the {\ASDF} API
to make this easier.
It accepts a portable relative pathname syntax and helps find files
in their input locations
without being foiled by translated output locations.
\section{Fixing {\Large \traverse}}
% \rtof{Moved some material from the backward compatiblity subsection here,
% because they are really about bug fixing, and not about backward compatibility
......@@ -700,53 +704,63 @@ and lowering the barriers to entry for newbies.
\begin{minipage}{0.95\columnwidth}
\begin{verbatim}
(defsystem :test-module-depend
:components ((:file "file1")
(:module "quux"
:pathname #p""
:depends-on ("file1")
:components
((:file "file2")
(:module "file3mod"
:pathname #p""
:components
((:file "file3")))))))
:components
((:file "file1")
(:module "quux"
:depends-on ("file1")
:components
((:file "file2")
(:module "file3mod"
:components
((:file "file3")))))))
\end{verbatim}
\end{minipage}
\caption{Example system (from the \ASDFii{} test suite), illustrating the
module dependency bug.}
\caption{Example system illustrating the module dependency bug.}
\label{fig:moduleBugExample}
\end{figure}
One of the most important bugs we fixed in \ASDFii{}, one that illustrates the
limits imposed by by backward compatibility, and one indicative of
future issues in \ASDF{}, was a problem with dependencies involving composite
components (modules and systems).
In \ASDFi{} there was a notorious bug that meant that dependencies upstream of a
composite component would not trigger recompilation of downstream components.
Figure \ref{fig:moduleBugExample} gives a system that shows the bug. If one
were to load this system, then modify \file{file1.lisp}, that would \emph{not}
cause \file{file2.lisp} or \file{file3.lisp} to be recompiled when reloading
system \lisp{test-module-depend}.
The problem arises because composite components are not like other \ASDF{}
component classes. In the original design of \ASDF{}, the decision seems to
have been made that to \perform{} an operation on a composite component, was to
mean ``perform additional operations on that composite,'' rather than ``perform
the operation on the composite as a group.'' So, for example, if one wanted to
build a hash-table based on the contents of a module or a system, one could do that in the
\perform{} method for that composite object.
We have no doubt that this design decision seemed reasonable when \ASDF{} was
first built, but it has turned out to have many unfortunate ramifications. In
general, it conflates together ``actions done to operate on a composite that are
not actions on a component'' (let us refer to these as ``synergistic actions'')
One of the most important bugs we fixed in {\ASDFii},
%% What are we compatible with and why?
%% See lp#479522
one that illustrates the limits imposed by by backward compatibility,
and one indicative of future issues in {\ASDF},
was a problem with dependencies
involving composite components (modules and systems).
% Why introduce name ``composite'' instead of just telling that systems are modules?
In {\ASDFi} there was a notorious bug that meant that
dependencies upstream of a composite component
would not trigger recompilation of downstream components.
Figure \ref{fig:moduleBugExample} gives a system that shows the bug.
If one were to load this system, then modify \file{file1.lisp},
that would \emph{not} cause \file{file2.lisp} or \file{file3.lisp}
to be recompiled when reloading system \lisp{test-module-depend}.
The problem arises because composite components
are not like other {\ASDF} component classes.
% ``Never ascribe to decisions what can be ascribed to lack thereof.''
In the original design of {\ASDF},
the decision seems to have been made that
to {\perform} an operation on a composite component
was to mean ``perform additional operations on that composite'' rather than
``perform the operation on the composite as a group.'' % This whole sentence is so unclear!
So, for example, if one wanted to build a hash-table
based on the contents of a module or a system, % why would you?
one could do that in the {\perform} method for that composite object. % uh?
We have no doubt that this design decision seemed reasonable
when {\ASDF} was first built, % was it?
but it has turned out to have many unfortunate ramifications.
In general, it conflates together
``actions done to operate on a composite that are not actions on a component''
(let us refer to these as ``synergistic actions'') % what does that mean???
and ``the action of operating on a composite'' in ways that are unfortunate.
% From there to end of section, I'm lost.
More specifically, because these synergistic actions are typically to be done
whenever a system is loaded, the \lisp{OPERATION-DONE-P} method for arbitrary
operations, would not work properly to indicate whether the operation had been
done for that composite, but only to indicate whether the \emph{synergistic
actions} had been performed.
So, in \ASDFi{}, if one was to (compile and) load system
done for that composite, but only to indicate whether the
\emph{synergistic actions} had been performed.
So, in {\ASDFi}, if one was to (compile and) load system
\lisp{test-module-depend}, touch \file{file2.lisp}, and then ask whether
\lisp{compile-op} had been done on module \lisp{quux} (containing \file{file2}),
the answer would be \lisp{T}, although intuitively the answer should be ``no.''
......@@ -756,36 +770,37 @@ instruction to load \file{file2}, to load \file{file3}, and then later to load
\lisp{file3mod}, to load \lisp{quux}, and finally to load
\lisp{test-module-depend}.
For this reason, it was not possible to modulate the loading of all of
\lisp{quux} by defining an \lisp{:around} method on \perform{} as applied to
\lisp{load-op} and the module \lisp{quux}. A common desire in \ASDF{} system
\lisp{quux} by defining an \lisp{:around} method on {\perform} as applied to
\lisp{load-op} and the module \lisp{quux}. A common desire in {\ASDF} system
definers is to do something like bind a dynamic variable (say \lisp{*readtable*}) around all of the
loading done to a module like \lisp{quux}. Unfortunately doing this in the
\perform{} method on \lisp{quux} will not have the desired effect, because that
\perform{} is done \emph{after} the operation on the components, not
{\perform} method on \lisp{quux} will not have the desired effect, because that
{\perform} is done \emph{after} the operation on the components, not
\emph{around} the operations on the components.
Trying to fix composite dependencies in \traverse{}, therefore, opened a big can
of worms. \ASDFi{} originally contained special-purpose, \textit{ad hoc}, logic
for modules to decide when their components needed to be operated on (since
\lisp{operation-done-p} could not be used), and this
Trying to fix composite dependencies in {\traverse}, therefore,
opened a big can of worms.
{\ASDFi} originally contained special-purpose, \textit{ad hoc}, logic
for modules to decide when their components needed to be operated on
(since \lisp{operation-done-p} could not be used), and this
special-purpose logic had some bugs.
Instead of radically re-engineering the logic, we simply repaired it in place
(and later \fare{} refactored it), fixing the bug illustrated in
Figure~\ref{fig:moduleBugExample} (which was taken from the \ASDFii{} test
suite).
(and later {\fare} refactored it), fixing the bug illustrated in
Figure~\ref{fig:moduleBugExample}
(which was taken from the {\ASDFii} test suite).
We determined that we could not change the semantics of performing operations on
composites from synergistic actions to composite actions, without danger of
breaking an arbitrary amount of existing systems.
Unfortunately, we were limited to fixing the dependency bug for the module
case: \ASDFii{} still does not correctly handle the case where an upstream
case: {\ASDFii} still does not correctly handle the case where an upstream
\emph{system} has changed. Here the problem is that we do not have clear
semantics for system changes that are sufficient to detect the need to recompile
both across and within \CL{} sessions. See Section~\ref{sec:future-directions}, where we
both across and within {\CL} sessions. See Section~\ref{sec:future-directions}, where we
discuss some more radical solutions that should still maintain some forms of
backward compatibility.
% \rtof{As I wrote this, I recalled that this illustrates cases where the poor
% \ASDF{} user really \emph{does} need to understand internals of the system.
% {\ASDF} user really \emph{does} need to understand internals of the system.
% For example, the user really does need to understand the odd semantics of
% composite operations in order to know why his \lisp{around} methods don't do
% what he wants... Should we back patch that or just not worry about it. I
......@@ -799,7 +814,7 @@ backward compatibility.
% could add a word about these issues in the section on portability.
% Portability has limited our use of some of the more arcane features of CLOS,
% and \emph{definitely} of the MOP. The former is not so bad as before, as the
% various \CL{} versions all now have much more complete CLOS implementations.
% various {\CL} versions all now have much more complete CLOS implementations.
% What I suggest is that you either add
% something about this to the portability section, or not, and in any case you
% kill this rtof and the discussion below.}
......@@ -1012,7 +1027,7 @@ more than was originally anticipated by either the original authors or us.
% ``everything should be made as simple as possible, but no simpler''
We will
maintain \ASDF{} as the minimal but extensible
maintain {\ASDF} as the minimal but extensible
core functionality of a build system for {\CL} software.
The idea is that
\moneyquote{anything that can be provided as an extension
......@@ -1026,8 +1041,8 @@ because you need that configuration to locate and compile extensions.
Similarly, on Windows, support for shortcuts had to go into the core.
With all the things we added,
{\ASDF} almost doubled in size since we started working on {\ASDFii},
and more than tripled since the original author left.\footnote{
Release 2.005 is 144892 byte long;
and almost quadrupled since the original author left.\footnote{
Release 2.006 is 144996 byte long;
1.369, the last release by Gary King was 77079 byte long;
the last version by Daniel Barlow, in 2004, was 38881 byte long.
}
......@@ -1036,7 +1051,7 @@ the last version by Daniel Barlow, in 2004, was 38881 byte long.
On a positive note, {\CL} helped us keep things simple.
Andreas Fuchs wrote {\POIU}~\cite{QITAB},
an extension for {\ASDF} implementing parallel compilation.
He had to redefine many internals of {\ASDF} for \POIU{},
He had to redefine many internals of {\ASDF} for {\POIU},
and we broke much of it when we wrote {\ASDFii}.
One of us (\fare) became suddenly the maintainer of \emph{both} pieces of software,
so took the opportunity to provide from {\ASDF} all the pieces needed
......@@ -1048,7 +1063,7 @@ adding slots to components to remember original definition-time.
This dependency information was not previously retained by {\ASDF},
which only remembered a digest fit for its specific traversal algorithm.
\POIU{} showed {\CL}, and particularly its object system CLOS,
{\POIU} showed {\CL}, and particularly its object system {\CLOS},
at its best.
First, it was very impressive that
{\POIU} could be written
......@@ -1065,7 +1080,7 @@ very simple and informal.
We were also reminded that software is hard, very hard.
Simple ideas can take literally hundreds of iterations to get right.
Documentation is a pain, and is still a weakness of \ASDFii{}.
Documentation is a pain, and is still a weakness of {\ASDFii}.
\section{Related work}
......@@ -1114,23 +1129,27 @@ Documentation is a pain, and is still a weakness of \ASDFii{}.
% the structure in makefiles. Possibly worth patching this in to earlier
% discussion.
% BUILD TR claims that \make{} is \emph{not} a plan-then-build system, but builds
% BUILD TR claims that {\make} is \emph{not} a plan-then-build system, but builds
% a dependency graph of components and then walks it checking at each point
% whether an update is needed.
% }
There are many related tools for other programming languages; too many to list
here. We have already discussed \make{}~\cite{Feldman79} in
Section~\ref{sec:analogy-with-make}. Omake~\cite{OMake} is an attempt to
improve on \make{}, making it more declarative. Of interest to readers of this
article are features such as automated dependency analysis, sub-project
management, and extension using a DSL (instead of relying on shell commands).
Possibly closer to \ASDF{} in flavor are integrated build systems such as
CONS~\cite{Sidebotham98} and SCONS~\cite{scons}, that aim to unify the entire
build chain. These, too, aim to overcome many of the limitations of make.
The \ant{} system for Java also attempts to go beyond \make{}, in particular in
using an XML dialect to provide more declarative system specifications.
There are many related tools for other programming languages;
too many to list here.
We have already discussed {\make}~\cite{Feldman79}
in Section~\ref{sec:analogy-with-make}.
Omake~\cite{OMake} is a notable modern take on the {\make} concept:
of interest to readers of this article are features
such as automated dependency analysis, sub-project management,
and extension using a DSL (instead of relying on shell commands).
Possibly closer to {\ASDF} in flavor are integrated build systems such as
CONS~\cite{Sidebotham98} and SCONS~\cite{scons},
that aim to unify the entire build chain.
These, too, aim to overcome many of the limitations of make.
The {\ant} system for Java also attempts to go beyond {\make},
in particular in using an XML dialect
to provide more declarative system specifications.
\fixme{Add citation for \texttt{ant}; a cite to the Sun Java web site would be
fine if we can't find a better. I couldn't find a nice short article.}
......@@ -1138,29 +1157,28 @@ using an XML dialect to provide more declarative system specifications.
\subsection{XCVB and ytools}
\label{sec:XCVB}
\rtof{I added this new introduction and tweaked the XCVB discussion a little.
Please make sure I didn't get anything wrong. Note that I \emph{added} a
couple of claims in XCVB's favor: advantage of doing it over instead of
backwards (bug) compatibility, and the fact that you don't need to worry about
image maintenance. I'm not fully sure those are correct!}
% \ftor{I would put them in separate paragraphs.}
In the modern lisp world, two \ASDF{} alternatives provide an interesting
contrast. XCVB~\cite{XCVB} abandons \ASDF{}'s image maintenance task to concentrate on
doing a better job of building software systems.
In the modern Lisp world, two {\ASDF} alternatives
provide an interesting contrast.
XCVB~\cite{XCVB