さて、いよいよ細かい実装の話に入っていこうと思ったのだが、Common Lisp では多言語処理(エンコーディング処理)に優れたライブラリとして babel というのがある。なんと Debian ではこれが Synaptics で用意されている。ちょっとやってみたら、実に簡単にインストールされ、sbcl との連携も完璧。そして少なくとも sbcl ではサロゲートペアも処理できてしまうのだ。以下はその紹介。

まずは、Synaptics でキーワード cl-babel で検索し、インストールする。このとき一緒に cl-alexandria と cl-trivial-futures のライブラリもインストールされる。これも Debian 以外で自分でインストールしようとすると、結構嵌るときがあるんだよね。Debian + sbcl は素晴らしい。cl-alexandria は様々な小さなユーティリティプログラムがあるライブラリで、cl-trivial-futures は Common Lisp の *features* を処理系非依存にするため(MacOS X 用?)のものらしい。

次に、sbcl を立ち上げて、babel を require する。
* (require :babel)
すると、コンパイラーからのメッセージがいっぱい出て、でも最後はこんな感じで完了する。
; compiling (IN-PACKAGE #:BABEL)
; compiling (DEFUN SHARP-BACKSLASH-READER ...)
; compiling (DEFUN MAKE-SHARP-BACKSLASH-READER ...)
; compiling (DEFMACRO ENABLE-SHARP-BACKSLASH-SYNTAX ...)
; compiling (DEFUN SET-SHARP-BACKSLASH-SYNTAX-IN-READTABLE ...)

; /root/.cache/common-lisp/sbcl-1.0.40.0.debian-linux-amd64/usr/share/common-lisp/source/babel/src/ASDF-TMP-sharp-backslash.fasl written
; compilation finished in 0:00:00.102
;
; compilation unit finished
;   printed 5 notes
NIL
さて、以下のデモンストレーションを見てほしい。これは Common LISP users jpのBabelの記事(g000001さんより訂正のコメントをいただきましたので反映しました)を参考にしたものだ。
* (babel:list-character-encodings)

(:CP932 :EUCJP :CP1251 :UTF-32 :UTF-16 :UTF-8B :UTF-8 :ISO-8859-16 :ISO-8859-15
 :ISO-8859-14 :ISO-8859-13 :ISO-8859-11 :ISO-8859-10 :ISO-8859-9 :ISO-8859-8
 :ISO-8859-7 :ISO-8859-6 :ISO-8859-5 :ISO-8859-4 :ISO-8859-3 :ISO-8859-2
 :ISO-8859-1 :EBCDIC-US :ASCII)
* (babel:string-to-octets "日本語" :encoding :utf-16)

#(255 254 229 101 44 103 158 138)
* (babel:string-to-octets "𠀋𡈽" :encoding :utf-16)

#(255 254 64 216 11 220 68 216 61 222)
* (let ((vector (make-array 8 :initial-contents '(255 254 229 101 44 103 158 138)
 :element-type '(unsigned-byte 8))))
(babel:octets-to-string vector :encoding :utf-16))

"日本語"
* (let ((vector (make-array 10 :initial-contents '(255 254 64 216 11 220 68 216 61 222)
 :element-type '(unsigned-byte 8))))
(babel:octets-to-string vector :encoding :utf-16))

"𠀋𡈽"
*
なんと、日本語のサロゲートペアまできちんと処理できている。オクテットの最初の 255 254 は 0xFF 0xFE だから、リトルエンディアンを示すBOMである。実は、サロゲートペアを処理できなかったら、いろいろ薀蓄を傾けながら、プログラムをつくろうと思っていたのだが、車輪の再開発はつつしむべきであろう。Debian + SBCL + Babel を前提として、以後の話を展開することにする。