■
特定の日(2008-01-20)のブログエントリーに大量にスパムコメントが来る。よくわからないので移動。
Software Design 2008/01 Emacs 特集
なかなか良い。elisp と java との比較は苦しいが。
ところで、最近入れた emacs 22.1.1 の環境では、 emacs の組み込み関数でも describe-function で参照すると、
C のコードが参照できるらしい。
以下は elisp の関数 atom と listp の部分。elisp の 組み込み関数はこんな感じのようだ。上記の特集と組み合わせると Emacs を読み解けるかもしれない(時間が欲しい)。
DEFUN ("listp", Flistp, Slistp, 1, 1, 0, doc: /* Return t if OBJECT is a list, that is, a cons cell or nil. Otherwise, return nil. */) (object) Lisp_Object object; { if (CONSP (object) || NILP (object)) return Qt; return Qnil; }
以下も参考になる。
ライフゲーム
dokaku.org のお題より。(投稿したけどログインし忘れてた、、)
Common Lisp (CLOS) で書いてみた。
感想として。ライフゲームという小さい宇宙、実装してみるとなかなか楽しかった。
以下は実はどう書くに投稿するにはいろいろと格好悪いコードである。
特に個人的には配列を処理するようなコードが不慣れで下手。
昔から、何故かライフゲームは隅から順番に更新していくと思い込んでいて、
「更新する順番によって結果がかわるのではないか?」と疑問に思っていた。
実際は、次の盤の状態の計算結果を一時的に変数に格納して、
その後全体を更新する、という2ステップがあるのだった。
やはり手は動かしてみるものだ。
(defclass board () ((width :accessor board-width :initarg :w) (height :accessor board-height :initarg :h) (cells :accessor board-cells :initarg :cells))) (defmethod print-object ((board board) stream) (print-unreadable-object (board stream) (format stream "board~%") (loop for y from 0 below (board-height board) do (loop for x from 0 below (board-width board) do (format stream "~a" (if (cell board x y) "X" "."))) (format stream "~%")))) (defun make-board (w h) "constructor" (make-instance 'board :w w :h h :cells (make-array (list w h) :initial-element nil))) (defun make-random-board (w h) (let ((board (make-board w h))) (loop for y from 0 below (board-height board) do (loop for x from 0 below (board-width board) do (setf (cell board x y) (< (random 10) 3)))) board)) (defmethod cell ((board board) x y) "accessor" (aref (board-cells board) (mod x (board-width board)) (mod y (board-height board)))) ;; (setf (cell board x y) value) (defsetf cell (board x y) (value) `(setf (aref (board-cells ,board) (mod ,x (board-width ,board)) (mod ,y (board-height ,board))) ,value)) (defmethod cell-neighbours ((board board) x y) (list (cell board (1- x) (1- y)) (cell board x (1- y)) (cell board (1+ x) (1- y)) (cell board (1- x) y) (cell board (1+ x) y) (cell board (1- x) (1+ y)) (cell board x (1+ y)) (cell board (1+ x) (1+ y)))) (defmethod cell-survivep ((board board) x y) (let ((c (cell board x y)) (n (count-if #'identity (cell-neighbours board x y)))) (cond ((and (not c) (= n 3)) t) ;; born ((and c (or (= n 3) (= n 2))) t) ;; keep (t nil)))) ;; die (defmethod update ((board board)) (let ((next (loop for y from 0 below (board-height board) append (loop for x from 0 below (board-width board) collect (list x y (cell-survivep board x y)))))) (loop for elt in next do (destructuring-bind (x y v) elt (setf (cell board x y) v)))) board)