anaphoric-variants
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:
andorcondifwhenunlessprog1caseccaseecasetypecasectypecaseetypecase
It's also possible to make your own variants. Check definitions.lisp in particular for inspiration.