[asdf-devel] In defense of ASDF & Semantic versioning

Daniel Herring dherring at tentpost.com
Thu Nov 21 05:36:53 UTC 2013


On Tue, 19 Nov 2013, Faré wrote:

> Thanks to #+foo, #.(if (find-symbol "FOO" :bar) ...)
> and (eval-when ...), CL can deal with source-level compatibility
> in ways that C cannot.

Moving a bit off-topic, GNU Autoconf takes probing for function 
availability and behavior further towards a science than perhaps any other 
system in use.  [Its a shame that M4 and portable shell scripting were 
required for pragmatic reasons.  That said, many lispers would learn some 
interesting macro lessons by studying Autoconf's use of M4.]

Also, runtime probing for functionality actually are often used in C/C++ 
programs, though usually not understood by most of the dev team.  These 
probes frequently take the form of dlopen/dlsym and their Win32 
equivalents.  Also, many APIs like NPAPI, OpenGL, CUDA, and CPUID have 
their own extension registry systems.

FWIW, my little "read-macros" package demonstrated some functionality to 
simplify writing read-time conditional code without pushing everything on 
*features*.

http://git.tentpost.com/?p=lisp/read-macros.git


Back on-topic, semantic versioning systems such as advocated by GNU 
libtool try to provide a conservative estimate on portability.  In such 
environments, it is not uncommon for a project to make a new release 
simply because a dependency bumped a version number.  This is a primary 
motivation for the autoconf-style detection of behavior rather than 
trusting in names and version numbers.  If behavior is detected, then a 
new version may simply require recompilation instead of a new source 
release.


One approach to solving "DLL-hell" is to essentially avoid shared 
libraries altogether.  Significant progress can be made by having an 
application fully specify the revisions of all dependencies.  Then these 
can be delivered atomically with the application, and a build system can 
assemble them.  This in the path used by most commercial MSWin 
applications, several Java and Javascript frameworks, etc.  Problems arise 
when two dependencies require different versions of a common third 
dependency, especially when that third dependency needs to have 
"singleton" behavior for consistency.


On Tue, 19 Nov 2013, Anton Vodonosov wrote:

> But my point - it's not enough to just bump major
> version number, as semantic versioning suggests.
>
> If author of "somelib" library wants to make an API incompatible
> change, it is better to release new ASDF system "somelib2"
> and put code into new package somelib2.

This concept resonates with me.  The existence of a new API version should 
not preclude further releases of older API versions.  Branching, and thus 
API versions, should not be restricted to a simple linear progression. 
Most semantic versioning systems partially acknowledge this through the 
use of "minor" and "micro" version numbers.  (A git-like tree would be 
better...)

Towards this end, I had started investigating a set of macros and/or 
features to simplify the process of embedding version information directly 
into the CL package names themselves.  Unfortunately, I didn't find any 
clean solution that met my goals.  Here are a couple emails on the 
subject.

http://article.gmane.org/gmane.lisp.libcl.devel/110
http://article.gmane.org/gmane.lisp.libcl.devel/123
[Note: LibCL and its mailing lists are now defunct.]


Another possible source of ideas is the FreeBSD's new "pkg-ng" system. 
Apparently they found a nice solution to integrate binary packages with 
locally-compiled source ports.


All that said, semantic versioning is tried and true, easy to implement, 
and a useful improvement on the current ASDF status quo.  Other approaches 
such as behavior testing and nonlinear are harder to implement and should 
play nicely with a semantic versioning system.  Thus I am all in favor 
with ASDF adopting a reasonable semantic system today.


Whatever we do, please implement an escape hatch for the end user to 
override the versioning system's idea of compatibility.  These things 
often have obscure failure modes and/or prevent nuanced usage.  Just like 
CL::internal symbols, it is nice to have a straightforward way to void the 
warranty and bypass the normal safety mechanisms.

- Daniel


More information about the asdf-devel mailing list