by shigemk2

当面は技術的なことしか書かない

リスト遊び 7-2 while

前回
リスト遊び 7-1 ローカル変数 - by shigemk2

繰り返し

(while 継続条件式
  式1
  式2
  ...
)

whileは特殊関数であり、第一引数の継続条件式がnilでない間、
残りの引数は繰り返し評価する。whileは常にnilを返す。
sumをwhileで実装しなおす。

(defun sum (lst)
  (let ((ret 0))
    ;; lst が nil なら、終了し、最後のretを返す
    (while lst
      (setq ret (+ (car lst) ret))
      (setq lst (cdr lst)))
    ret))
sum
(sum '(9 9))
18

replをwhileを使って書き直す

(defun repl (lst old new)
  (let (ret)
    (while lst
      (cond
       ((eq old (car lst)) ;; oldにひっかかるセルが存在するなら
       (setq ret (cons new ret))) ;; consする
      (t (setq ret (cons (car lst) ret))))
    (setq lst (cdr lst)))
  ret))
repl
(repl '(1 2 3 1 2 3) 1 0)
;; ただし、当然のことながらconsしていくと先頭にどんどん後のセルが追加
;; される
(3 2 0 3 2 0)
(defun repl (lst old new)
  (let (tmp ret)
    (while lst
      (cond
       ((eq old (car lst)) ;; oldにひっかかるセルが存在するなら
       (setq tmp (cons new tmp))) ;; consする
      (t (setq tmp (cons (car lst) tmp))))
    (setq lst (cdr lst)))
    (while tmp ;; もう1回ループをかけて、consしてセルの順序を逆さにする
      (setq ret (cons (car tmp) ret))
    (setq tmp (cdr tmp)))
  ret))
repl
(repl '(1 2 3 1 2 3) 1 0)
(0 2 3 0 2 3)

リストはセルの並びであり、セルではないnilで終端されている。
データ列を終端する役割を果たす特殊な値は番兵(sentinel)と呼ばれる
(セルの終端はnilであることを利用してwhileをかけている)

リスト遊び―Emacsで学ぶLispの世界 (ASCII SOFTWARE SCIENCE Language)

リスト遊び―Emacsで学ぶLispの世界 (ASCII SOFTWARE SCIENCE Language)