実践Common lispを読み始めた-第20章 特殊オペレータ
フォームの評価を制御する特殊オペレータ
- QUOTE 評価をしないでS式をデータとして扱えるようにする。
- IF 条件実行の構文要素の基礎になるbool選択の操作。
- PROGN 複数の式を並べられるようにする。
レキシカル環境を操作する
- letとlet*は変数に対してレキシカルな束縛を確立できる。つまり特定のスコープ内で有効な変数が定義できる。
- setqはletとlet*で束縛された変数の設定に使えるので、レキシカル環境にアクセスできる特殊オペレータだといえる。うーん、よくわからない。さまよっていたら、わかりやすい解説を発見LISPをみんなで勉強しよう! : Re: setqはset quote。なるほど、特定のスコープの中でのみ有効な変数を、スコープを変えないようにして中身の値だけ変えられるのがsetqで、setはスコープも変えてしまうわけだ。
CL-USER> (let ((foo 42)) (setq foo (+ 1 42)) foo) 43 CL-USER> foo ; Evaluation aborted CL-USER> (let ((foo 42)) (set 'foo (+ 1 42)) foo) 42 CL-USER> foo 43
多値
多値を返すのはリストを返すの異なり、多値を捕えるための操作を行わない限り、1つめの値以外は捨てられる。
CL-USER> (defparameter *h* (make-hash-table)) *H* CL-USER> (setf (gethash 'a *h*) 10) 10 CL-USER> (setf (gethash 'b *h*) 1000) 1000 CL-USER> (+ (gethash 'a *h*) (gethash 'b *h*)) 1010 CL-USER> (+ (gethash 'a *h*) (gethash 'c *h*)) ;;*h*にはキーcがない ; Evaluation aborted CL-USER>
valuesは引数を多値として返す関数で、values-listはリストを一つとり中身の要素を多値として返す。
CL-USER> (values '(1 2 3)) (1 2 3) CL-USER> (values 1 2 3) 1 2 3 CL-USER> (values-list '(1 2 3)) 1 2 3 CL-USER> (values-list '(1 2 (3 4))) 1 2 (3 4)
逆に多値を変数に格納したり、リストに格納する場合には、multiple-value-bindやmultiple-value-listを使うう。
setfの引数としてvaluesの戻り値を設定すると、複数の変数をまとめて設定できる。
EVAL-WHEN
その他の特殊オペレータ
CL-USER> (defun bar () (load-time-value (get-universal-time))) BAR CL-USER> (bar) 3450841236 CL-USER> (bar) 3450841238 <-値が変わっている CL-USER> (bar) 3450841240 <-値が変わっている CL-USER> (compile 'bar) BAR NIL NIL CL-USER> (bar) 3450841247 CL-USER> (bar) 3450841247 <-値が変わらない CL-USER> (bar) 3450841247 <-値が変わらない CL-USER>