メインのPCが壊れた → Common Lispをいじっていた件

仕方なく低スペックのノートPCで生活しているのですが、やはり動作がとろくてストレスが溜まってきます。

メモリを増設しようとしたのですが、購入したメモリとノートPCが合わなくて、結局いまだに「もさもさ」している状態です。
メモリとの相性を確認する時は製造番号までチェックすること > 自分(PC初心者)


そんなこんなで、あまりPCに触りたくなくなってきたので図書館で本を探してみたりすると、何となくCommon Lispの本が目についたので、仕方なく借りてきて眺めている日々です。

ということで今回、初めてCommon Lispをいじってみた(とはいえマクロとかCLOSには未達)のですが、やけに標準の関数が揃っているなぁ、という印象です。

たとえば、Ruby1.9で使えるようになったらしいブロック渡しのArray#index(条件を満たす最初の要素のインデックスを返すやつ)は、既に

Break 5 [7]> (position-if (lambda (x) (and (zerop (mod x 3)) (> x 0))) '(0 1 4 9 16 25))
3

とか用意されていてちょっと驚きでした。まぁ名前空間が分割されていないので覚えにくいなぁ、という気も。


で、いつものごとく「新しい言語に触ってみたら必ず馬鹿の一つ覚え的に作ってみる二分木作成関数」を作ってみました(処理系はGNU Clispを使用)。
木は三要素のリストで表現していて、先頭が値、残りの二つが左右の木です。

6/29 append-treeの定義の際にlabelsを使うよう修正

[1]>
(defun list-to-tree (lst)
 (labels
  ((append-tree (tree val)
    (let ((elm (first tree)) (left (second tree)) (right (third tree)))
     (cond
      ((not elm) (list val () ()))
      ((< val elm) (list elm (append-tree left val) right))
      (t (list elm left (append-tree right val)))))))
 (reduce #'append-tree lst :initial-value ())))
LIST-TO-TREE
[2]> (list-to-tree '(5 7 3 8 4 9 2 6 1))
(5 (3 (2 (1 NIL NIL) NIL) (4 NIL NIL)) (7 (6 NIL NIL) (8 NIL (9 NIL NIL))))

多分、もっとCommon Lispっぽい書き方とか、お作法があるとは思いますが、その辺は追々。