バッククオート

IIJ技術研究所 山本和彦
作成:2002/09/03
更新:2002/09/03

バッククオートの不幸は、いつもマクロと一緒に語られることである。 だから、「バッククオートはマクロで使うものだ」と変な先入観を持たされてしまう。 また、バッククオートのもう一つの不幸は、 Emacs 19 のころの書式が複雑だったことである。 以下の例を見て欲しい。

(defmacro my-buffer-writable (& rest body)
  (` (let ((buffer-read-only nil)
           (inhibit-read-only t)
           (after-change-functions nil))
       (,@ body))))

(macroexpand
 '(my-buffer-writable
   (insert "This is\n")
   (insert "a pen.\n")))

→ (let ((buffer-read-only nil)
         (inhibit-read-only t)
         (after-change-functions nil))
     (insert "This is\n")
     (insert "a pen.\n"))

この例は簡単な方だが、それでも当惑するには十分だろう。

バッククオートを理解するには、まずマクロから切り放す必要がある。 また、昔の複雑は書式は忘れよう。 そうすれば、おそらく次の言葉だけでバッククオートを理解できるはずだ。

「バッククオートとは、クオートの一種」である。 以下の例を見て欲しい。

(defvar my-lpr-call-format `("lpr" "-P" "psprinter"))

通常、クオートで書くところをバッククオートで書いてみた。 この例では、クオートとバッククオートには何ら違いはない。 だから、この例でバッククオートを使う必然性はない。 わざわざこう書いた理由は、 バッククオートとはクオート文字が逆を向いただけだと気軽に思ってもらうためだ。

では、クオートとバッククオートとの違いはなんだろう? それは、クオートはクオートした部分がまったく評価されないことに対し、 バッククオートでは一部を評価できることである。 評価したい部分の前には、"," を付ける。 以下の例をみて欲しい。

'(1 (+ 2 3) 4)
→ (1 (+ 2 3) 4)

`(1 ,(+ 2 3) 4)
→ (1 5 4)

バッククオートの方では、(+ 2 3) が評価されていることが分るだろう。 この機能を利用して、前出の例は以下のようにソフトコーディングに変更できる。

(defvar my-lpr-command "lpr")
(defvar my-lpr-call-format `(,my-lpr-command "-P" "psprinter"))

バッククオートには、"," に加えて、",@" という評価方法もある。 これは、評価した部分がリストになったら、 そのリストの最初と最後の括弧を取り去って、 前後とくっつける動作をする。 ",@" を使えば、先の例はさらにソフトコーディングにできる。

(defvar my-lpr-command "lpr")
(defvar my-lpr-command-args '("-P" "psprinter"))
(defvar my-lpr-call-format `(,my-lpr-command ,@my-lpr-command-args))

上記のようにバッククオートは、単独で使っても便利だ。 というわけで、バッククオートとマクロと一緒に語るのは、 バッククオートにとって不幸である。