REASONABLE-UTILITIES (RUTILS) is yet another general purpose utilities package for COMMON-LISP.


The other utility packages in CL-land include: CL-UTILITIES, METATILITIES, ARNESI and ALEXANDRIA to name a few. There are following motivations for creating another collection:

1. Virtually everyone talks about utilities in CL (probably, due to Paul Graham's On Lisp, that starts with a chapter on the importance of utilities). But the existing utility packages are not enough visible and widespread either due to: not enough utility :), poor names, or lack of community involvement. The best and, probably, quite usable package is, in my opinion, ALEXANDRIA, which has a great team of developers, but basically suffers from 2 shortcomings:

  • bad name (not recognized as a utilities package)
  • the idea to be a "good citizen" in the CL world and not include code from other well-established, but specific utilities packages (SPLIT-SEQUENCE, ITERATE, ANAPHORA, ...)

The second problem is most important, for the utility package should be as much all-around, all-encompassing one as possible. Because it should be used in most of the libraries, and library authors, for obvious reasons, don't like to add dependencies. This is one of the causes of not enough spread of such very useful packages, as ITERATE: one or two usages of the ITER macro often don't justify the dependency on an additional package. Yet, if all various utilities are collected under one roof, it should be a much more reasonable choice to depend on it.

2. Yet the reverse of coin of all-encompassing utilities' package is bloat. It is a common complain about the CL standard, that it lacks modularity, and the utilities' package can as well suffer from the same problem. But the solution to it is found and implemented using the CL package mechanism: every part of functionality (like list or hash-table handling) is segmented into it's own package. Every package name is formed according to the following template: RUTILS. (like: RUTILS.LIST, RUTILS.ITER). So it's a 1 dependency (1 ASDF system) - multiple packages, that can be used on demand, depending on the project's needs. Besides, there are umbrella packages, that include most of the useful functionality, omitting only experimental stuff. A style distinction of different naming conventions is also taken into consideration, so both long and short names are allowed to coexist and be selected according to one's preferences. So there are such umbrella packages as: RUTILS.USER and RUTILS.USR.

3. Support for growth of CL

Our aim is to include in this package as much of the work done in the previous periods and scattered over the Internet, as possible. Those utilities are unified in this package and a lot of effort is put into better documenting them.

Besides we want to support some (or several) community process for developing the CL environment and incorporating into it new ideas, that are proved important and useful.

One of such processes is CDR and we aim to provide an implementation of every CDR proposal, that targets "user-space" (i.e. does not require efforts on the implementation side).

Besides there is RUTILS.EXPERIMENTAL package, that will include some of the ideas, that are not yet tested enough, but might become valuable in the future.

Finally, the most important goal of this project is to gather around it a big community of Lisp enthusiasts, that will be able to make their impact in improving it. That is why it is planned to establish a web-site, that will allow posting and discussing of the suggestions of features to be added to the collection.

As well additional maintainers for the project are needed.

4. What is included and excluded


Additional control constructs:

  • Basic (control.lisp)
  • Anaphoric utilities
  • Symbols' and literals' manipulation (core.lisp)
  • A general BIND macro
  • ITER macro with keywords support (see iter.txt)
  • PKG: read time manipulation of package visibility (see pkg.txt)

Enhanced handling of:

  • Arrays
  • Conditions
  • Lists
  • Functions
  • Hash-tables (+ GENHASH, CDR 2)
  • Numbers (incl. CDR 5)
  • Objects
  • Sequences (+ an implementation of the SEQ protocol, loosely based on Clojure, see seq.txt. + SPLIT-SEQUENCE, see split-sequence.txt)
  • String handling
  • Tree handling


  • Support for concurrency. The reason is not, that we consider this not useful or general-purpose enough, but rather, that it's a whole new paradigm, and the scope of RUTILS is too small to comfortably accommodate it. Look at:
  • Functional features. As in the above, it's as well a whole other paradigm. It has a limited, but reasonable support in CL. Other features should be unified in it's own package, and maybe RUTILS can serve as a model for such package or even accommodate it in the future. Look at:
  • Collections are as well a separate area in CS, so it requires a lot of effort to maintain and develop a comprehensive package in it. Look at:
  • MOP. MOP abstraction layer is a CDR and it is as well an essential part of CL. It is implemented in CLOSER-MOP, and there are plans to integrate it in the future.

Additional notes

See LICENSE for usage permissions.

See AUTHORS for credits.

The following symbols are added to *FEATURES*:

  • :iter
  • :split-sequence
  • :seq