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:
and
or
cond
if
when
unless
prog1
case
ccase
ecase
typecase
ctypecase
etypecase
It's also possible to make your own variants. Check definitions.lisp in particular for inspiration.