なにかあったら出力

(format t "~:[~;~:*~S~]" <なにか>)

#1: nil/non-nil で分岐

"~:[こっち~;そっち~]" という format 文字列を置いとくと、そこに与えられる引数が nil なら "こっち" が、non-nil なら "そっち" が出力される。

(format t "~:[nil だぉ・・・~;non-nil だぉ!!~]" nil)
nil だぉ・・・
=> nil

(format t "~:[nil だぉ・・・~;non-nil だぉ!!~]" t)
non-nil だぉ!!
=> nil

#2: 分岐に使った引数をもっかい使う

"~:[...~;...~]" で分岐するのに引数を1つ喰ってしまうので、"..." の部分で引数を出力しようとするとその次の引数が表示されてしまう。

(format t "~:[nil: ~S~;non-nil: ~S~]" nil 'foo)
nil: foo
=> nil

(format t "~:[nil: ~S~;non-nil: ~S~]" t 'foo)
non-nil: foo
=> nil

そこで ~:* と書いておくと、さっき使った引数をもっかい使えるようになるので

(format t "~:[nil: ~:*~S~;non-nil: ~:*~S~]" nil)
nil: nil
=> nil

(format t "~:[nil: ~:*~S~;non-nil: ~:*~S~]" :non-nil)
non-nil: :non-nil
=> nil

#3: まとめ

欲しいのは「non-nil な値だったらそれを出力」という指定。

(format t "~:[~;~:*~S~]" 'I-AM-NOT-NIL!!!)
I-AM-NOT-NIL!!!
=> nil

ちなみに今までこうやってた。

(format t "~A" (if 'ARE-YOU-NIL? (format nil "~S" 'ARE-YOU-NIL?) ""))
ARE-YOU-NIL?
=> nil

format は書き方知ってるとすっきり書ける。でも知らないと if とか使った方が早いし、書いてある format 文字列の挙動もわからない。

追記(2009-06-23 09:48)

(format t "~@[~S~]" <なにか>)

で万事オッケー。NANRI さんに感謝。