実践Common lispを読み始めた-第22章 黒帯のためのLoop
繰り返し構文を書くための言語らしい。
マクロがDSL(Domain Specific Language)を作るためにあるというのをLispのセミナーのときに講師の黒田さんがおっしゃっていたが、Loopもその一例なのかもしれない。
Loopでできること
- ループしている間にCollect, Count, Sum, Minimize, Maximaizeする。Collectというのは収集したものを要素としたListを作ることと思っていいのかな。Count, SumはともかくとしてMinimize, Maximizeというのは最小値と最大値をとるということなのか?最小化、最大化と日本語でかかれていてもよくわからない。
- 任意のLisp式を実行できる。
- ループの終了条件を決定
- 条件付きで実行
これらに加えて、
- ループ内で使用するローカル変数の生成
- ループの前後に実行する任意のLisp式の実現。
なのだそうだ。
反復の制御
forかasを使う。
数えるループ
- from, downfrom, upfrom
- to, upto, below, downto, above
コレクションやパッケージについてループする
- for節にin, onを使う
(loop for i in (list 1 2 3 4) collect i);リスト要素から一つ一つ全部とりだす。
=とthenによる反復
一気にAlgol風な感じ
ローカル変数
withを使う
変数を分配する
CL-USER> (loop for (a b c) in '((1 2 3) (4 5 (6 7)) (8 9)) do (format t "a: ~a; b: ~a; c: ~a~%" a b c)) a: 1; b: 2; c: 3 a: 4; b: 5; c: (6 7) a: 8; b: 9; c: NIL NIL
値の累積
動詞 | 機能 |
---|---|
collect | 取り出した値を要素としたリストを作る |
append | リストに追加する |
nconc | 破壊的なappend |
count | 数 |
sum | 合計 |
maximize | 最大値 |
minimize | 最小値 |
無条件実行
ループの中で、collectとかmaximizeとか決まった処理じゃなくて、任意のことをしたい場合。do節を使う。
(loop for i from 1 to 100 do (print 1))
条件実行
無条件実行を説明したら当然、条件実行も知りたくなる。
ポイントは、
- do節を使う場合はその先で条件分岐を書いてしまえばOK。
- 累積節を条件実行したい場合はdo節を使えないので、loopに用意されている条件構文を使う
- 条件構文はif, when, unlessの3つがある。ifとwhenの振る舞いは同じ。
CL-USER> (defparameter *alist* '(tokyo osaka kyoto yokohama)) ;都市名のリスト *ALIST* CL-USER> (defparameter *ahash* (make-hash-table)) ;hash tableを作る *AHASH* CL-USER> (setf (gethash 'osaka *ahash*) 'kansai-international-airport) ;hashに都市名に対応する国際空港をセット KANSAI-INTERNATIONAL-AIRPORT CL-USER> (setf (gethash 'tokyo *ahash*) 'narita-international-airport) ;東京と大阪はあるけど、京都と横浜には同一府県にない。(実は東京も違うけど成田ということしておく) NARITA-INTERNATIONAL-AIRPORT CL-USER> (loop for key in *alist* when (gethash key *ahash*) collect key) ;空港がある都市だけを表示 (TOKYO OSAKA) CL-USER>