1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Common LispのRead処理(1)

Posted at

@HaruoWakakusa さんのRead処理について、3点ほど気になった点があったのですが、Lisp屋さんとして一番ディープな話を書きます。

Readマクロの本質

バッククォート
cons(make_symbol("QUASIQUOTE"), cons(expr, NIL)

コンマ
cons(make_symbol("UNQUOTE"), cons(expr, NIL))

コンマ@
cons(make_symbol("UNQUOTE-SPLICING")

ここまでは、あってます。

この後、Read処理の中で、展開しないといけません。
展開する処理が、記事に書かれていなかったので、それをやっていますか?という点が一番気になりました。

実験

* '`(a ,b ,@c)
`(A ,B ,@C)

うわ。SBCLは、まさかのダメだ、こりゃ。

Clojureでやってみる

Clojure 1.11.3
user=> '`(a ,b ,@c)
(clojure.core/seq 
(clojure.core/concat
(clojure.core/list (quote user/a))
(clojure.core/list (quote user/b))
(clojure.core/list (clojure.core/seq 
(clojure.core/concat
(clojure.core/list (quote clojure.core/deref))
(clojure.core/list (quote user/c)))))))

バッククオート(`)の前にクオート(')をつけると、評価が抑制されるので、Readが読んだ結果が見えます。

clojure.core/ という名前空間が、ややこしいので、省略してみます。

(seq
   (concat (list (quote user/a))
               (list (quote user/b))
               (list (seq (concat (list (quote deref))
                          (list (quote user/c)))))))


こんな感じになりました。

注目すべき点は、この中に、QUASIQUOTE, UNQUOTE, UNQUOTE-SPLICINGが一切入っていないという点です。

Read処理の一番最後で、QUASIQUOTE, UNQUOTE, UNQUOTE-SPLICINGを全部変換して取り除いてしまい、appendやlistやlist*やconsなどに展開しないといけません。

決して、eval処理の中で、QUASIQUOTEというマクロを呼んで展開する訳ではないのです。

『Read処理中に全て展開してしまうから、Readマクロ』と呼ぶのです

でも、動くよという反論について(理由はうまく説明できない)

もうLispを勉強したのが数十年ほど前で、その時ほど、覚えていないので、良い例が思いつきません。
検索したら以下のサイトに使用例がありました。引用しますね。

(define-macro (bar)
  (let ((x 10) (y '(1 2 3)) (z 'foo))
    `(list ,x `(,',z ,,@y))))

こんな感じで、バッククオートを2重にかけます。
3重にも書けるし、4重にも書けます。

私も実は昔、「バッククオートを2重に書ける」事を知りませんでした。
当時私は、やはりevalの中で、QUASIQUOTEというマクロを呼んで展開していました。

例は忘れてしまいましたが、
(a)Read処理の中で展開してしまう方法
(b)eval処理の中でQUASIQUOTEを展開する場合
では、結果に差が出る事があるのです。

そうです、バッククオートを2重や3重に書いた場合に、そのバグが発生します。

おわり

Read処理の最後で、QUASIQUOTE類は、展開して取り除いてくださいね。
それが私が考える、正しいReadの処理方法です。
(もし間違っていたらすみません)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?