実践Common Lisp p100-182

読みました。感想。

  • Schemeだけ書いてた時はリストだけあれば生きていけるって思ってましたがそうでもないんだなぁと思いました。
  • キーワード引数がややこしい。でも:keyとか:testとか共通してるのがいっぱいあるからそのうち覚えるはず。
  • NCONCとかSUBSTITUTEとかCONCATENATEとかとかいろいろあって大分こんがらがってきました。こういうのは見て書きながら脳に覚えさせるしかないんだろうけど。でも自分で作らなくていいんだからその分楽ですよね。自分で作る場合は名前決めて名前覚えて作るまでしなくちゃいけないわけだし。
  • with-open-fileすごい。マクロすごい。
  • パスネーム面倒くさい。すごく面倒くさい。
  • ディレクトリツリーの巡回は便利ですね。でもslimeでC-c C-kだとエラーでます。C-c C-lだとちゃんとできます。ここら辺の違いがよく分からないんですよね。マクロ定義を含むファイルとかもC-c C-lだとちゃんとloadできるけどC-c C-kだとコンパイルできない。だからコンパイルさせたいように書くときはその辺を意識して書かないといけないのかなぁ。などと思ってるのですが全然見当違いな事を考えてたりしてるかもしれないのでちょっと怖い。
  • データ構造にリストを使ってプログラムのプロトタイプを書くっていうのはとても有効な気がしました。
  • マクロ楽しい。

こんな感じです。今SICP含めて4冊並行して本読んでるんですが、全部できれば3月中に終わらせるように読んでるので結構きついです。

今日はこれだけ。

実践Common Lisp p63-100

読みました。感想とか一生懸命書くようにすると読み進めるのが遅くなりそうなのであまり書きません。

ただ、実践Common Lispと直接関係ないんですが、コードを書いてて気になった点があります。
Emacsの問題なんですが、しかもまたインデントなんですが、バッククォートの後だとインデントがおかしくなります。

(defmacro do-primes ((var start end) &body body)
  (with-gensyms (ending-value-name)
    `(do ((,var (next-prime ,start)
           (next-prime (1+ ,var)))
          (,ending-value-name ,end))
      ((> ,var ,ending-value-name))
      ,@body)))

こんな風に。たぶんcl-indent.elを弄れば直りそうなので後でやりたいと思います。
とりあえずの回避法として、

(defmacro do-primes ((var start end) &body body)
  (with-gensyms (ending-value-name)
    `
    (do ((,var (next-prime ,start)
               (next-prime (1+ ,var)))
         (,ending-value-name ,end))
        ((> ,var ,ending-value-name))
      ,@body)))

こんな風に書くとちゃんとインデントしてくれるみたいなんですが、こういう書き方ってたぶんしないですよね。もしかしたらCommon Lispをよく書く人だとすごくきもく感じたりするんでしょうか。上のよりはましだと思うんですが。


(3/9 5:30)
cl-indent-patches.elというものがあるそうで、これをload-pathが通っているところに放り投げ、.emacs

(require 'cl-indent-patches)

としたらバッククォート時でもインデントしてくれるようになりました。
こちらを参考にさせていただきました。

emacsでのifのインデント続き

あああやっと解決しました。ここの続きです。

.emacsのなかでの

(setq auto-mode-alist
      (append '(
        ...
        ("\\.lisp$" . lisp-mode)
        ...
       ) auto-mode-alist))

を試しに

(setq auto-mode-alist
      (append '(
        ...
        ("\\.lisp$" . emacs-lisp-mode)
        ...
       ) auto-mode-alist))

にして.emacsに(put 'if 'lisp-indent-function 3)としてみたらちゃんとインデントしてくれました。だからlisp-modeに設定がうまく引っかかってなかったみたいです。2日かけたのに原因が下らなすぎて恥ずかしい。でも一応できたので書いておきます(Emacsの勉強にもなったし)。
ただそうすると.elファイルとかの編集のときの整合性がとれないからできればlisp-modeでやりたいところ(まあ*.elファイルとかはgvimで編集してるんですが)。今はやる気出尽くして枯れてるのでそのうちやりたいです。

あと世の中にはcl-indent.elというものがあるらしく、それをload-pathが通ってるところに放り込んで、cl-indent.elの最後に

(provide 'cl-indent)

を追加してバイトコンパイルして、.emacs側で

(require 'cl-indent)
(setq lisp-indent-function (function common-lisp-indent-function))

などとやってみるとloopマクロなんかもうまくインデントしてくれるようになりました。これで心置きなくCommonLispが書けます。


あとアドバイスくれたtrotrさんありがとうございました。