License: Public Domain , Load it with Quicklisp: (ql:quickload "anaphoric-variants")
Library type: Operator overlay macro , Project complexity: Medium

anaphoric-variants gives access to anaphoric variants of operators through one macro: anaphoric.

The user explicitly provides a variable name, preserving sanity,
in contrast to the traditional use of an evil implicit variable (it).

Some operators can bind additional handy variables when explicitly requested.

Here's a trivial example:

(anaphoric tail
  (when (member 'b '(a b c d))
    (cdr tail)))
==>
(LET ((TAIL (MEMBER 'B '(A B C D))))
  (DECLARE (IGNORABLE TAIL))
  (WHEN TAIL (CDR TAIL)))
=> (C D)

And here's a bit more interesting one:

(anaphoric (key :type type :index index)
  (etypecase '(a b c)
    (list (list* index type key))
    (t (list index "Not a list." key))))
==>
(LET ((KEY '(A B C)))
  (DECLARE (IGNORABLE KEY))
  (ETYPECASE KEY
    (LIST
     (LET ((TYPE 'LIST))
       (DECLARE (IGNORABLE TYPE))
       (LET ((INDEX 0))
         (DECLARE (IGNORABLE INDEX))
         (LIST* INDEX TYPE KEY))))
    (T
     (LET ((TYPE 'T))
       (DECLARE (IGNORABLE TYPE))
       (LET ((INDEX 1))
         (DECLARE (IGNORABLE INDEX))
         (LIST INDEX "Not a list." KEY))))))
=> (0 LIST A B C)

To use anaphoric-variants, simply (:import-from #:anaphoric-variants #:anaphoric). Don't (:use)!

Currently supported anaphoric variants:

It's also possible to make your own variants. Check definitions.lisp in particular for inspiration.