LISP で Queue を実装その2
LISP で Queue を実装その1 - Shammerismの失敗を回避するためにクラスを使用。
? (defclass queue () ((internal-list :reader get-internal-list :writer set-internal-list))) #<STANDARD-CLASS QUEUE> ? (defmethod en-queue ((q queue) object) (let ((original-queue (if (slot-boundp q 'internal-list) (get-internal-list q) nil))) (let ((new-queue (append original-queue (list object)))) (set-internal-list new-queue q)))) #<STANDARD-METHOD EN-QUEUE (QUEUE T)> ? (defparameter test-queue (make-instance 'queue)) TEST-QUEUE ? (en-queue test-queue 'a) (A) ? (en-queue test-queue 'b) (A B) ? (get-internal-list test-queue) (A B) ?
en-queue の中で null check をしなかった場合、「Slot INTERNAL-LIST is unbound」のエラーになるので null check をしている。まあ、これは初期値を nil で定義しておいてもいいかも。そのように書き換えた方がいいか。そうすれば en-queue はよりシンプルにできる。中身を取り出す de-queue は以下のようになった。空のときには nil を返すように気を付ける必要がある。
? (defmethod de-queue ((q queue)) (let ((return-object nil)) (when (slot-boundp q 'internal-list) (let ((original-list (get-internal-list q))) (setf return-object (car original-list)) (set-internal-list (cdr original-list) q))) return-object)) #<STANDARD-METHOD DE-QUEUE (QUEUE)> ?
en-queue と de-queue を繰り返して実行してみた。とりあえず、LISP で Queue を実装その1 - Shammerismで想定していたことはできていると思ってよさそうだ。
? (defparameter test-queue (make-instance 'queue)) TEST-QUEUE ? (de-queue test-queue) NIL ? (en-queue test-queue 0) (0) ? (en-queue test-queue 1) (0 1) ? (en-queue test-queue 2) (0 1 2) ? (de-queue test-queue) 0 ? (en-queue test-queue 0) (1 2 0) ?