Unverified Commit d9bd7b0e authored by Eric Timmons's avatar Eric Timmons
Browse files

Tweak README

parent 092ac4be
Loading
Loading
Loading
Loading
+51 −40
Changes for README.org: 51 added lines, 40 removed lines.
Original line number Diff line number Diff line
#+TITLE: ASDF Package Inferred Components
#+TITLE: ASDF Inferred Components

ASDF's Package Inferred System class is pretty great. However, it has some
aspects that annoy me and this project is an attempt to clean those up, while
maintaining as many of the benefits as possible.
The goal of this package is to give you many of the benefits that come from
ASDF's Package Inferred System (local declaration of intra- and inter-system
dependencies) without many of the downsides. For a full comparison of the two,
see [[*Comparison with Package Inferred System][Comparison with Package Inferred System]].

The best features of package inferred systems are:

1. Dependencies between files in the same project are automatically inferred.
2. Dependencies on external systems are declared very close to where they are
   used.

The worst features (IMHO) are:

1. Every single *file* in your project is a potential dependency for other
   systems. Because every file is turned into a system, people using your code
   can say ~(:depends-on :your-system/a/b/c)~ and then they suddenly become
   intimately tied to the implementation details of your project. Sure, you can
   say in your README "Only depend on ~:your-system~ or ~:your-system/a~", but
   why not expose only the systems you want?
2. There is no easy way to extract dependencies for a project. In order to do
   so, you must recurse into every sub-system. That is equivalent to recursing
   into every file and checking it for external dependencies.
3. Some features of ASDF dependency specification are unavailable. You cannot
   use ~:feature~ or ~:version~ dependencies in any of your inferred
   systems. ~:version~ dependencies are pretty easy to hoist to the top level
   system, but ~:feature~ dependencies are much trickier to get right.
4. It is difficult to include intraproject dependencies on anything other than
   Common Lisp source files. If you have a grovel-file from CFFI, there is no
   way to declaratively say that source file ~a/b/c.lisp~ depends on that
   grovel-file being operated on first.
5. It is difficult to introspect a system to determine its components. Similar
   to 2, you need to recurse into every subsystem/file to do so.
6. It is *required* that every CL source file has a corresponding package. This
   can help with modularity on large systems, but can be annoying on smaller
   systems. Plus some people plain don't like having that many packages around.

Most of these cons stem from the fact that the package-inferred-system class
creates an entirely new system for *every* lisp file in your project. This
project attempts to bring a little sanity to the inferred approach by inferring
*components* of a parent system.
It does this by treating all of your source files as *components* of a single
system instead of treating each file as its own independent system.

* Notes

  + This currently requires a patched version of ASDF to work.
  + This requires a very recent (3.3.5+) version of ASDF.

* Quickstart

@@ -222,6 +190,49 @@ project attempts to bring a little sanity to the inferred approach by inferring
   [[https://gitlab.common-lisp.net/asdf/asdf/-/issues/68#note_7941]]. Therefore,
   any dependencies on systems are hoisted up to the parent system.

* Comparison with Package Inferred System
  ASDF's Package Inferred System class is pretty great. However, it has some
  aspects that annoy me and this project is an attempt to clean those up, while
  maintaining as many of the benefits as possible.

  The best features of package inferred systems are:

  1. Dependencies between files in the same project are automatically inferred.
  2. Dependencies on external systems are declared very close to where they are
     used.

  The worst features (IMHO) are:

  1. Every single *file* in your project is a potential dependency for other
     systems. Because every file is turned into a system, people using your
     code can say ~(:depends-on :your-system/a/b/c)~ and then they suddenly
     become intimately tied to the implementation details of your
     project. Sure, you can say in your README "Only depend on ~:your-system~
     or ~:your-system/a~", but why not expose only the systems you want?
  2. There is no easy way to extract dependencies for a project. In order to do
     so, you must recurse into every sub-system. That is equivalent to
     recursing into every file and checking it for external dependencies.
  3. Some features of ASDF dependency specification are unavailable. You cannot
     use ~:feature~ or ~:version~ dependencies in any of your inferred
     systems. ~:version~ dependencies are pretty easy to hoist to the top level
     system, but ~:feature~ dependencies are much trickier to get right.
  4. It is difficult to include intraproject dependencies on anything other
     than Common Lisp source files. If you have a grovel-file from CFFI, there
     is no way to declaratively say that source file ~a/b/c.lisp~ depends on
     that grovel-file being operated on first.
  5. It is difficult to introspect a system to determine its
     components. Similar to 2, you need to recurse into every subsystem/file to
     do so.
  6. It is *required* that every CL source file has a corresponding
     package. This can help with modularity on large systems, but can be
     annoying on smaller systems. Plus some people plain don't like having that
     many packages around.

  Most of these cons stem from the fact that the package-inferred-system class
  creates an entirely new system for *every* lisp file in your project. This
  project attempts to bring a little sanity to the inferred approach by
  inferring *components* of a parent system.

* Future Work

  1. Provide ability to specify component defining forms in file comments. This