Commit 94424e39 authored by Francois-Rene Rideau's avatar Francois-Rene Rideau
Browse files

Some proofreading

parent d714825e
......@@ -58,7 +58,7 @@ such as distributing software, managing bugs, connecting people,
% I cut this because asdf does have :version. I realize that's not
% all of what you are talking about as DLL hell, but think it's better not to go
% down that rabbit-hole here. [2010/08/31:rpg]
%solving dependency versioning issues (aka ``DLL hell''),
%solving dependency versioning issues (aka ``DLL hell''),
etc.
......@@ -112,25 +112,31 @@ The rules are annotated with parameterized shell scripts
that actually perform the build actions.
{\make} is a powerful tool that can express arbitrary programs,
but makefiles can be a mesh of code that defies any simple analysis.
but makefiles can grow into a mesh of code that defies any simple analysis.
{\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 as an extension to {\ASDF},
typically as method definitions for one or more 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,
whereas the C compiler and linker are pure functional file-to-file transformers,
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 are written in Lisp itself.
Being able to do everything in Lisp without cross-language barriers
is a conceptual simplification;
however, you may pay a price for using side-effects.
Supporting a new file type is relatively easy with {\make},
by adding a new rule with an appropriate pattern to recognize
filenames with the conventional extension,
and corresponding shell commands.
With {\ASDF}, supporting a new file type
Supporting a new file type in {\ASDF} is more involved,
requiring one to define a class and a few methods
as extensions to the {\ASDF} protocol.
On the other hand, when building C programs with {\make},
arbitrary side-effects have to be specified
in a different language, in the shell layer of the makefile.
When building {\CL} programs with {\ASDF},
arbitrary side-effects are specified in Lisp itself
inside the components being built.
This is because the C compiler and linker
are pure functional file-to-file transformers,
whereas the {\CL} compiler and loader are imperative languages.
The ability Lisp has to do everything without cross-language barriers
is a conceptual simplification, but of course, it doesn't save you from
the \emph{intrinsic} complexity of such side-effects.
\hide{
\rtof{I don't believe the following helps the reader a lot, and our purpose is only
......@@ -196,7 +202,7 @@ and gives example metadata (authors, versioning, license, etc.).
The {\defsystem} macro parses the system definition into
a set of linked objects, all of them instances of (subclasses of) {\component}.
The main object will be of type {\system}.
Primitive {\component}s of systems are typically
Primitive {\component}s of systems are typically
instances of a subclass of \lisp{source-file},
by default \lisp{cl-source-file}.
There are other predefined component types,
......@@ -218,15 +224,13 @@ 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,
%and had a number of undesirable features.
see Section \ref{sec:input-locations}.
After a system definition is found,
{\operate} generates a \emph{plan} for completing the {\operation}
using the function {\traverse} described below.
The plan will be a list of {\step}s,
each {\step} a pair of an \emph{operation} and a \emph{component};
The plan will be a list of {\step}s;
%each {\step} a pair of an \emph{operation} and a \emph{component};
the list will be topologically sorted such that
all the dependencies of a {\step} appear before that {\step}.
If a plan is successfully generated,
......@@ -310,9 +314,9 @@ For a load {\step}, wanted for its effects on the current Lisp image,
there are no \lisp{output-files}, and
{\opdonep} compares the timestamp of the \lisp{input-files}
to the time they were last loaded into the current image (if ever).
Operations with neither \lisp{input-files} nor \lisp{output-files}
{\Step}s with neither \lisp{input-files} nor \lisp{output-files}
(e.g., where the component is a {\module} or {\system})
are never considered necessary unless forced by their dependencies.
are never considered necessary unless forced by a dependency or sub-component.
\hide{\footnote{
{\defsystem} internally expands
the specification of {\dependsOn} relationships between components
......@@ -337,11 +341,6 @@ if the operation needs to be done on the component,
recurses into {\doFirst} dependencies.
}}
%We will see subtleties of this part of the protocol,
%when we discuss our modifications to {\traverse},
%and the limitations on those modifications
%(see Section \ref{sec:traverse-bug-fix}).
% \fixme{There's a discussion of in-order-to on gmane, apparently.
% \url{http://article.gmane.org/gmane.lisp.cclan.general/674}. Check this
% before calling this done.}
......
This diff is collapsed.
......@@ -42,7 +42,7 @@ 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}.
Other languages' build tools typically rely
Build tools of other languages typically rely
on some external operating system provided shell
to build software that is loaded into virtual machines
({\em processes} in Unix parlance) distinct from the current one.
......@@ -52,32 +52,31 @@ and incompatible changes in interfaces or internals of the build system
are resolved simply by starting a new virtual machine.
{\ASDF} does not start separate processes for compilation.
We believe that this there are a number of reasons for this design decision:
\begin{itemize}
\item {\CL} implementations were running on
We believe that there are a number of reasons for this design decision.
%\begin{itemize}
%\item
First,
{\CL} implementations historically have run on
a vast variety of operating systems,
some of which lacked the capability of virtualizing a Lisp process.
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
%\item
Also,
even on modern operating systems that allow this virtualization,
starting a {\CL} process can sometimes be a relatively expensive process
(depending on the individual {\CL} implementation).
\item Because of the presence of code to be executed at compile time and
% \item
Moreover,
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 build very extensive state
%\item
Finally, {\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}
% \ftor{I don't think this is relevant here, only a distraction.}
%The Ytools ``chunk manager'' (see Section \ref{sec:related-works})
%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.
%\end{itemize}
Because {\ASDF} performs its build tasks in the user's current Lisp process,
upgrading {\ASDF} entails modifying some existing
......@@ -91,11 +90,7 @@ or upgrade an existing {\ASDF} installation to the current code
(if a previous version already exists).
In addition, the code for an {\ASDF} version must recognize
the special case when the very same version is already loaded
so as to make such reloads idempotent.
% I cut this so we wouldn't have to explain how not being idempotent might break
% things. I think (hope) it's self-evident that idempotency here is A Good
% Thing. [2010/08/31:rpg]
% and to avoid unnecessarily breaking things.
so as to ensure such reloads are idempotent.
It does this by relying on a simple version identification string,
to be bumped up at every modification of {\ASDF}.
......@@ -104,7 +99,8 @@ to be bumped up at every modification of {\ASDF}.
The semantics of redefining or overriding a function
is not fully specified by the {\CL} standard.
The many implementations at the time of standardization may have had explicitly different semantics,
The many implementations at the time of standardization
may have had explicitly different semantics,
the semantic difficulties may have been overlooked,
implementers may have called for underspecification
as leaving them more room for optimization,
......@@ -135,7 +131,7 @@ as long as it behaves in a semantically equivalent way.\footnote{
For instance, assuming functions are seldom rebound,
dynamic calls may be implemented just like static calls,
except that the value of the binding is a cache that gets invalidated
between the time the function is rebound and the time the cache is used.
between the time the function is rebound and the time the cache is next used.
As for static calls, they may be implemented
not just by linking a call to the proper code value,
......@@ -150,8 +146,8 @@ and are not specific to either {\CL} or {\ASDF}.
However, these difficulties are particularly relevant in the case of {\ASDF},
because it drives compilation and loading of Lisp code
possibly including new versions of {\ASDF} itself.
{\ASDF}'s code is therefore likely to be in the continuation
of its own function redefinitions,
{\ASDF}'s redefined functions are therefore likely to be in the continuation
of their own function redefinitions,
where the old code will for a short while
be a client to the new code.
Moreover, these difficulties are compounded by the fact that
......@@ -198,7 +194,7 @@ that haven't been standardized.
We cannot work around limitations of MOP standardizations
by using a portability layer such as {\CLOSERMOP}~\cite{costanza:closer},
lest by doing so we create a circular dependency
between the portability layer (loaded using \ASDF{}) and \ASDF{} itself.
between the portability layer (loaded using {\ASDF}) and {\ASDF} itself.
\subsection{Shadowing a symbol}
......@@ -304,7 +300,7 @@ and require client packages to be reloaded to link to the new package object.
{\ASDFii} takes care to define the \lisp{ASDF} package if it doesn't exist,
redefine it properly if it exists, etc.
{\ASDFii} reuses existing packages and symbols
whenever possible, so as not to invalidate previously interned client code, etc.
whenever possible, so as not to invalidate previously interned client code, etc.
This package wrangling was difficult to get right, and
once again, we have to take into account the eager linking done by ECL and GCL.
One reason we could make this package wrangling work
......@@ -312,7 +308,7 @@ is that we do not need to blindly handle the general case
of upgrading arbitrary package definitions to arbitrary new ones.
All we needed to do was to upgrade previous versions of our own packages.
This was simplified by the fact that
our packages do not \lisp{use} any other package that is a moving target.
our package does not \lisp{use} any other package that is a moving target.
If any package \lisp{use}s \lisp{ASDF} and that somehow causes a clash,
it is the responsibility of the authors of that client package
to update their code.
......@@ -354,7 +350,7 @@ may cause the method definition not to be statically compiled
and emit a warning on some implementations.
Protecting the method definition with delayed evaluation (as we finally did)
hushes the warning.
Unfortunately, it also
Unfortunately, it also
causes slightly inefficient runtime compilation on some implementations.
Nevertheless,
it doesn't cause any significant user-visible pause,
......@@ -390,11 +386,11 @@ as the {\CL} standard authors might have feared.
It is probably possible to express the Erlang semantics on top of {\CL},
by explicitly \lisp{funcall}ing either
\lisp{(fdefinition 'foo)} or \lisp{(load-time-value (fdefinition 'foo))}
depending on the call being static or dynamic,
but this is cumbersome, non-idiomatic, and most importantly
depending on the call being static or dynamic.
However this is cumbersome, non-idiomatic, and most importantly
requires existing code to be modified to use the new convention
before it may be safely upgraded,
and therefore is not compatible with using existing libraries as black boxes.
before it may be safely upgraded.
Therefore it 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
......@@ -418,7 +414,6 @@ Lacking such a better-specified Lisp, possibly implemented atop {\CL},
there are ways to work around these limitations;
but not only are they are quite unidiomatic,
they require manual management.
%(since by assumption we rejected implementing them on top of {\CL}).
For instance, we could use some kind of symbol versioning:
use completely different symbols any time we would previously redefine things,
mark old symbols as obsolete and never reuse them.
......@@ -432,8 +427,9 @@ would itself need to be renamed with a new version
since its contents have changed to use new function names.
In a limited way, that is what uninterning symbols does for you,
and what renaming away packages would do, etc.
This technique similarly requires new clients to be recompiled
any time any code is modified.
However, monotonicity requires new clients
not only to be recompiled, but also to be modified
any time any code is changed incompatibly.
This latter approach is semantically safe and technically simple,
but we didn't adopt it, because of its social implications.
......@@ -480,8 +476,8 @@ In the end,
\moneyquote{the general problem with {\CL} is that
its semantics are defined in terms of irreversible side-effects
to global data structures in the current image.}
Not only does this complicate hot upgrade but also
makes semantic analysis, separate compilation, dependency management,
Not only does this complicate hot upgrade,
it also makes semantic analysis, separate compilation, dependency management,
and a lot of things much harder than they should be.
......
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