Saturday, October 17, 2009

Okay, so I decided to do a bit of hacking tonight that involved installing cffi. Before I started, for the first time in a long time, I actually upgraded SBCL and blew away my ~/.sbcl directory. Then I typed it:

(require 'asdf-install)
(asdf-install:install 'cffi)

Those commands managed to pull down 21 different packages! In itself, that might be the right thing to do for something that has a lot of dependencies, but after looking in ~/.sbcl/systems I found that I had:

So, that included five different unit test packages, plus the three different unit test frameworks (Lift, RT, and Stefil) dedicated to running them. I also got Swank thrown in. Honestly, I was waiting for the free set of Ginsu knives. ("But wait, there's more...!")

Here's the thing, people. When I install a package, I don't want your unit tests. Or the unit test framework necessary to run them. That's all just cruft that takes time, space, energy, etc. I mean, I'm glad that people are using unit tests and all, but as a user of your package, I shouldn't have to care about unit tests. Presumably, when developing/releasing your package, you ran your tests. That's all good. But if they passed for you, they'll also pass for me. Unless I'm going to start hacking your package, they're just a nuisance for me. If I am going to start hacking your package, I'm probably going to pull the source directly from git or darcs or CVS or Subversion, not asdf-install. At a minimum, can we all agree to remove dependencies on Lift, RT, and Stefil.

If I really want to run your tests, and I have installed them using asdf-install, I'm perfectly willing to install those other packages using a separate asdf-install command.

As for Swank, while I love it, again, if I want it in my environment, I'll install it separately, thank you very much.

Summary: Please keep your package dependencies to a minimum. If you really need to have a package that pulls in a huge set of dependencies to create a full environment (e.g. Swank and such), please separate your core library functionality from the top-level environment package and allow those of us with minimal tastes to simply install your core library functionality by itself.

I personally am glad for any packaging effort that anyone does in their free time. I most willingly trade my download and installation time for any effort put into more testing, more documentation, better code.

After all, what you are ranting about is open source software, and "open source" indeed means hackable. To be hackable, the unit tests and the environment required to run them is needed. Thus, it is the right thing to have them be dependencies.

If you want a binary-only, low-footprint Lisp distribution, create one yourself or buy a commercially supported Lisp.

If you are smart enough to code in Lisp, you are never a mere user. You are a potential contributor. That is one reason you should have the tests. And that tests are documentation is not theory, it is practice. And the fact that a test passed for me does not mean it will pass for you. And last, I am proud of my testcases and want to show them to the other lispers, to show how testing is done. Test-first design is the biggest invention that has happened since the 80:s, and not enough lispers have got it yet, in my humble opinion.

Hans, thanks, but I am well aware of how open source works. In fact, during the day, I work for an open source company (Vyatta). :-) I'm not suggesting I want a binary-only distribution. I simply would like it if packages pulled in a minimal set of dependencies such that installing something as simple as CFFI doesn't result in 5 useless packages of units tests, and 3 different test frameworks. That's just dumb.

Antifuchs, thanks! I'll take a look at clbuild.

MattC, yes, unit tests can serve as excellent examples. I fully agree. All I'm saying is, if I want them, I'll install them. That is, I'm not suggesting that unit tests should not be available (even under asdf-install, though I still doubt I would install them that way if I wanted them). I'm merely suggesting that packages should not install them by default. They are not necessary to run the package. Therefore, they are optional and extraneous in many cases.

Henrik, thanks for your confidence in my intelligence. And yes, we're all potential contributors. But I'm also a potential Linux contributor, and I'm thankful that my Linux distribution doesn't pull in every bit of source that might be used to build the system. While I might contribute to a number of projects, in reality, I contribute to only a very few, and then only as I find something I really need and have time. In those cases, I'm more than happy to install extra code necessary to build the system.

Test suites are one step beyond checksums for downloads. They are needed particularly because Lisp libraries are distributed as source. How can you tell if the source library you downloaded is valid and will work the way you expect? As opposed to a completely broken version of the library accidentally packaged up as a tarball? Run the test suites.

The test suites are also helpful if you end up needing support for these free downloads. Who can be sure that you have exactly the same point release of Lisp compiler, same OS environment, and exactly the same point release of every other Lisp (and foreign) library loaded into your image?

How can you be sure the bug is in the library and not your code or some other part of your environment? If things don't work the way you expect, the first thing you should do is run the tests.

I am with you. If I wanted all of the tests, I would have installed the dev package instead. That said, I just realized that the way ASDF-Install handles multiple ASD files means I should have bundled the part of my FFT library that uses pcall/Bordeaux-threads separately from the rest. Oops.

Yes we did. Unfortunately it's not as simple as that though. There are so many CL implementations and possible recipient architectures that as a non-commercial package developer you can't test for all possible CL/OS/arch combinations. Therefore if you're going to use my package you'd better run the tests first to make sure you're not wasting your time.

But you're right. ASDF is a fairly sucky package system and it would be nice to have a choice about installing the dev pieces.

s11 said: Packages are correctly expressing their test systems' dependencies on test frameworks. For example, the cffi system does not depend on RT, whereas the cffi-tests system does.

It's fine for a test package (e.g. cffi-tests) to depend on a test package. It isn't fine for cffi to depend on cffi-tests. I'd be shocked if a set of unit tests were actually important code for the functioning of the system. If that's the case, then the test really isn't a test. By definition, it's really part of the code itself. So, for instance, I'm simply suggesting that cffi break the dependency between it and cffi-tests. Ditto with babel and babel-tests, lift and lift-test, metabang-bind and metabang-bind-test, etc. As an alternative, I suggested that people at least break the dependency between the test package and the test framework, but that's a second-place answer, IMO.

Steve Knight said: Yes we did. Unfortunately it's not as simple as that though. There are so many CL implementations and possible recipient architectures that as a non-commercial package developer you can't test for all possible CL/OS/arch combinations. Therefore if you're going to use my package you'd better run the tests first to make sure you're not wasting your time.

Yes, but if I like your package, I'm probably going to install it multiple times, on multiple different machines, using a similar CL implementation. And after I have run the tests once, I'm probably not going to run them again. They're just bloat for me at that point. Again, I'm fine with you distributing tests and I'm fine with you suggesting that people install and run them as a part of installing your package. I simply think it's bogus to create a dependency from the main package to a test package, which then creates a dependency on a test framework, and on and on.

Part of this overall problem is caused by ASDF not being as rich as it probably could be, but part of it is simply sloppy packaging on the part of authors.

The right way to do this, IMO, is to make two packages, foo and foo-tests for example. But instead of having foo depend on foo-tests, have foo-tests depend on foo. Installing foo only installs foo an any real dependencies. Installing foo-tests brings in foo, if not installed already, and anything required for the tests to run (frameworks like RT, Lift, Stefil, etc.).

Something like Swank can completely shaft my ability to connect to my production servers due to version incompatibilities. This is very annoying and I do not use swank via asdf in any of my code for this reason.

I do find it very useful to get the tests.

The tests are (hopefully) a very accurate source of documentation. I refer to tests frequently enough that it would be a bind to have to download them separately. I guess most prefer choice. But should we also separate the documentation as yet another package. It all gets a bit cumbersome, especially as most Lisp libraries are relatively small.