実践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>