/home/by-natures/dev*

データ界隈で働くエンジニアとしての技術的なメモと、たまに普通の日記。

S式変換中のquoteの扱い

(2009年12月15日に、以前のブログで書いた記事です。) S式を変換していて、quoteの扱いにつまずいたので備忘録として...

quoteとは、(quote datum) で、「datumそれ自身を返します。」とR5RSで説明されています。これだけだとよく分かりませんが、シンボルを作りたいときにquoteを用いたり、リストを簡潔に表現したりするのにquoteを用います。(quote datum)の代わりに、'datum としても構いません。

gosh> 'a
a
gosh> (quote a)
a
gosh> (list 'a 'b 5)
(a b 5)
gosh> '(a b 5)
(a b 5)

このquote、シングルクオート「'」を用いると非常に見やすくて便利なのですが、シングルクオートはquoteの略記でしかないため、式を変換したりする場合には注意が必要です。次の簡単な例で、シングルクオートで注意すべき点をご紹介します。

gosh> (define expression '(eqv? 'sym x))
expression
gosh> expression
(eqv? 'sym x)
gosh> (cadr expression)
'sym

この例は(eqv? 'sym x)という式をS式として扱おうとしているものです。expression という変数に、S式(eqv? 'sym x)が束縛されました。これのcadrを取ると、リストとして扱えているため、'symが返ってきています。プログラムを書いているときは、「symはシンボルだ」と思ってプログラムを書いているのですが...

gosh> (symbol? (cadr expression))
#f

'sym がシンボルかどうかを訪ねると、falseが返ってきてしまいました。これは何故かを考える為に、さらに次の問いかけをしてみます。

gosh> (list? (cadr expression))
#t

もうお気づきの方もいるかもしれませんが、先ほどから述べていたように、'datum は(quote datum)の略記であり、(cadr expression)は(quote sym)なんです。これが評価されれば、symというシンボルになるのですが、まだS式を扱っているだけで評価を行っていないため、単なる(quote sym)というリストだと認識されています。

この問題に気づいたときは、リストかどうかで異なる処理をプログラムしていたため、シンボルが来るはずだと思って書いていた部分で思わぬ結果を生じていました。

これで少し時間を取ってしまいましたが、プログラム自体がこのように簡単に扱え、変換できるのはLisp族の大きな魅力だと思います。変数名なんかは変換中は全てシンボルになっていますが、明示的にstringに変換して正規表現を使ってふるい分ける...なんてこともできました。

Lisp族はマクロもとても魅力的ですので(これもやっぱりS式のおかげ!)、時間があるときにゆっくり勉強したいと思います。