Some control-flow macros in Common Lisp alexandria libs
Previous post recorded my curiosity about the if-let
macro in alexandria
.
Recently, I stumbled upon another file, control-flow.lisp
, and became curious about what’s inside. Once again, I played around with it a bit to explore its potential for future use.
nth-value-or
(alexandria:nth-value-or 1
(values 0 nil 2)
(values 0 1 3)
(values 0 1 4))
This code will return (values 0 1 3)
because (nth 1 (multiple-value-list (values 0 1 3)))
is not nil
.
xor
This one is a bit weird:
(assert (equal '(nil nil) (multiple-value-list (alexandria:xor 1 2))))
(assert (equal '(2 t) (multiple-value-list (alexandria:xor nil 2))))
(assert (equal '(1 t) (multiple-value-list (alexandria:xor 1 nil nil))))
(assert (equal '(nil nil) (multiple-value-list (alexandria:xor 1 2 3))))
(assert (equal '(3 t) (multiple-value-list (alexandria:xor nil nil 3 nil))))
(assert (equal '(nil nil) (multiple-value-list (alexandria:xor nil nil 3 4))))
(assert (equal '(nil nil) (multiple-value-list (alexandria:xor nil 2 3 4))))
It looks like it keeps comparing pairs of values until it finds a pair that evaluates to (t nil)
and then returns the corresponding value.
switch
This one has a couple of siblings: eswitch
and cswitch
.
(alexandria:switch (10 :test 'equal)
(1 (format t "1") 2)
(2 (format t "2") 3)
(3 (format t "3") 4)
((1+ 9) (format t "match") 11))
At first, I thought it might behave like Go’s switch
, but it seems more like a supercharged cond
.
Written on January 15, 2025