Commit 5e0507d5 authored by Francois-Rene Rideau's avatar Francois-Rene Rideau
Browse files

superficial changes

parent 4c71cba2
......@@ -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,32 @@ 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}
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},
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}.
\subsection{Basic {\ASDF} object model}
......@@ -220,6 +226,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
......
......@@ -106,7 +106,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{
......@@ -333,13 +333,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.
......@@ -492,7 +492,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}
......@@ -534,14 +534,14 @@ and then fail for others.
\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.
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
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.
added \lisp{system-relative-pathname} to the {\ASDF} API to make this easier.
......@@ -658,7 +658,7 @@ smoothing the need for synchronization between experts
and lowering the barriers to entry for newbies.
\section{Fixing \texttt{traverse}}
\section{Fixing traverse} % {\traverse} looks weird
\label{sec:bug-fixes}
% \rtof{Moved some material from the backward compatiblity subsection here,
......@@ -707,31 +707,31 @@ and lowering the barriers to entry for newbies.
((:file "file3")))))))
\end{verbatim}
\end{minipage}
\caption{Example system (from the \ASDFii{} test suite), illustrating the
\caption{Example system (from the {\ASDFii} test suite), illustrating the
module dependency bug.}
\label{fig:moduleBugExample}
\end{figure}
One of the most important bugs we fixed in \ASDFii{}, one that illustrates the
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
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
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
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.
{\perform} method for that composite object.
We have no doubt that this design decision seemed reasonable when \ASDF{} was
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'')
......@@ -741,7 +741,7 @@ 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
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.''
......@@ -751,36 +751,36 @@ 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
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
(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
......@@ -794,7 +794,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.}
......@@ -1007,7 +1007,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
......@@ -1031,7 +1031,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
......@@ -1043,7 +1043,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
......@@ -1162,7 +1162,7 @@ There have been repeated calls to make \ASDF{} system definitions more fully
declarative.
Fixing composite component dependencies would repair the most substantial actual
\emph{bug} in \ASDF{}. At the same time, it would be appropriate to improve
introspection by making \traverse{} part of the \ASDF{} API.
introspection by making \traverse{} part of the {\ASDF} API.
Some interested developers might also consider making the \ASDF{} \lisp{TEST-OP}
and \lisp{DOC-OP} first class citizens.
Finally, and perhaps simultaneously most important and least appealing is
......
......@@ -38,8 +38,7 @@ we achieve better {\it a posteriori} coupling of release cycles.
\subsection{Technical Challenge}
Unlike
other build systems, such as {\make},
Unlike other build systems, such as {\make},
\moneyquote{{\ASDF} is an ``in-image'' build system
managing systems that are compiled and loaded in the current {\CL} image}.
......@@ -61,20 +60,20 @@ We believe that this there are a number of reasons for this design decision:
Previous build systems were designed around that constraint,
and {\ASDF} followed their design.
\item Even on modern operating systems that allow this virtualization,
starting a {\CL} process is often a relatively expensive process (depending on
the individual \CL{} implementation).
\item Because of the presence of code to be executed at compile time and the
dependence on a substantial amount of compile-time state,
starting a {\CL} process is often a relatively expensive process
(depending on the individual {\CL} implementation).
\item Because of the presence of code to be executed at compile time and
the dependence on a substantial amount of compile-time state,
it is difficult to decompose the process of building a {\CL} system
into independent pieces and parcel them out to different processes.
\item {\CL} programmers often built very extensive state
in a long-living {\CL} image, and so prefer to keep them alive. \ASDF{}
supports such a use pattern.
\item {\CL} programmers often build very extensive state
in a long-living {\CL} image, and so prefer to keep them alive.
{\ASDF} supports such a use pattern.
\end{itemize}
The Ytools ``chunk manager'' (see Section \ref{sec:related-works})
takes the \ASDF{} approach to an extreme, maintaining
code units smaller than file-size
takes the {\ASDF} approach to an extreme,
maintaining code units smaller than file-size
to maintain the integrity of long-lived {\CL} images.
On the other hand, XCVB (Section \ref{sec:XCVB}) takes a different perspective,
attempting to isolate system maintenance tasks in separate processes.
......@@ -245,7 +244,7 @@ Another problem is that {\unintern} runs the risk of causing ``collateral damage
When a symbol has several bindings associated to it,
such as a function or macro; variable or constant; type or class or condition;
property, etc.
All of these bindings will simultaneously become inaccessible
All of these bindings will simultaneously become inaccessible
when the symbol is uninterned.
Consider a user developing
......@@ -258,7 +257,7 @@ in either of the latter systems,
lest the previously loaded system be in an invalid, unusable state.
Code in these systems may be
linked to obsolete, now-uninterned symbols from the old {\ASDF}.
For these client systems
For these client systems
to function properly, they must be linked against
the symbols from the new {\ASDF}.
......@@ -323,7 +322,7 @@ Classes can be redefined,
slots can be added to them, removed from them, or modified,
and all instances will be automatically updated before their next use
to fit the new definition.
The {\CL} Object System (CLOS) \cite{bobrow_etal88})
The {\longCLOS} ({\CLOS}) \cite{bobrow_etal88})
allows users to control this instance update programmatically
by defining methods on {\uifrc}.
We rely on this functionality in {\ASDFii}
......@@ -393,7 +392,7 @@ and therefore is not compatible with using existing libraries as black boxes.
Future Lisp standards and specifications could learn from Erlang.
{\CL} users could incorporate Erlang-like semantics
in a mostly transparent way
in a most\-ly transparent way
by layering a {\CL} implementation on top of {\CL},
shadowing the usual reader and evaluator to replace them with something
that provides well-defined semantics for hot upgrade,
......@@ -401,7 +400,7 @@ assuming all code is (re)compiled on top of this implementation
rather than directly with the underlying implementation.
This, however, would be a large challenging task and not obviously worth the cost.
Furthermore,
if one was to design and implement
if one were to design and implement
what amounts to a new language on top of {\CL},
would it and should it be {\CL} all again?
Interestingly, in the presence of concurrent threads
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment