posted on 2019-02-03 15:00
I believe, that software should evolve and evolve quickly. One of the reasons why Common Lisp seems strange to newcomers is its ecosystem. It takes a long time to add a new library and make it useful to other common lispers.
Just pretend that you've made a brand new library and want to show it to the world. Now you have two options.
Include it into the Quicklisp and probably wait for 1 month before announcing the library on the Reddit or StackOverflow.
Put the library on the Github and ask everybody to download it and put somewhere where ASDF will be able to find it. Not very user-friendly, especially if your library has dependencies which aren't on the Quicklisp yet.
Now ask yourself a question, what if you've chosen the first option, and some user found a critical bug in your library?
The answer is: "Your users will have to wait another month until the next release of the Quicklisp."
Quicklisp is a perfect distribution for very stable software, but if we want our ecosystem to grow, we need something that can move faster. That is why I decided to spend all my free time working on the https://ultralisp.org.
Ultralisp is a Quicklisp compatible distribution, but it has two core features:
It let you (and anybody else) to add their libraries from the GitHub in few clicks.
It builds the next version within 5 minutes after a library was added or updated.
There are other features as well. Some of them are already implemented, others only planned and exist as the GitHub issues. You can help this project by using it, complaining about it and developing it.
Ultralisp was made not only to be used as a yet another quicklisp distribution. You can run your own instance of the Ultralisp. It is as easy as doing docker-compose run app.
If you are a company who uses Common Lisp, then you can set up a private Ultralisp server inside your infrastructure. However, don't forget to become a sponsor of the project ;-)
Using libraries from Ultralisp is as easy as adding it to the list of quicklisp distributions. You can do it in the REPL with this command:
(ql-dist:install-dist "http://dist.ultralisp.org/" :prompt nil)
However, I recommend you to pin distribution or libraries versions in every project. The easiest way to do this is to use Qlot. With Qlot you'll be able to pin version numbers and commit a config into the repository. This will give you stable builds which don't depend on future releases of Quicklisp or Ultralisp.
Here is the simplest config for the Qlot:
dist ultralisp http://dist.ultralisp.org/ ql :all :latest ultralisp :all :latest
It says, that if some system is present in the Ultralisp, it will will have priority over the same system from the Quicklisp.
After running qlot install or qlot update, Qlot will create a qlfile.lock file with pinned versions of the Quicklisp and Ultralisp. It will look like that:
("quicklisp" . (:class qlot.source.ql:source-ql-all :initargs (:distribution "http://beta.quicklisp.org/dist/quicklisp.txt" :%version :latest) :version "2019-02-02")) ("ultralisp" . (:class qlot.source.ql:source-ql-all :initargs (:distribution "http://dist.ultralisp.org/" :%version :latest) :version "20190202213040"))
Commit both qlfile and qlfile.lock into you source control system.
From time to time you'll need to run qlot update to update versions in the qlfile.lock, and run all your project's tests to ensure that it still works with newer distributions. If you discover that something went wrong, you can pin an older version of Ultralisp in the qlfile, just replace the line:
ultralisp :all :latest
With the line:
ultralisp :all 20190130205039
Or you can pin a single library by adding a line:
ultralisp cl-pgpass 20190202203038
if it stopped to work for you after some changes in recent versions.
We are all responsible for improving tooling around Common Lisp. If you feel that something can be made better, just do it. I hope that together we will make Common Lisp more convenient and attractive for the newcomers.