by shigemk2

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

リスト遊び 8-3 関数と仮引数

リスト遊び 8-2 setcar と setcdr - by shigemk2

lispの変数はポインタを保持する箱である。
関数呼び出しの祭は、引数が仮引数へコピーされるが、
これはポインタを複製しているに過ぎない。

また、Lispにおける単なる変数から変数への代入である。
関数の内部で、仮引数に何か値を代入しても、副作用を起こすことはない。

;; 副作用が起きないケース
(setq zoo '(dog pig))
(dog pig)
(setq x 2)
2
(defun func (l n)
  ;; あくまでポインタのコピーに代入しているに過ぎない。
  (setq l '(rat))
  (setq n 3))
func
;; zooに保持されているポインタは変化しない
(func zoo x)
;; コピーに代入しているので、もとのデータに変更は起きない
zoo
(dog pig)
x
2

関数の外で生成されたセルのCARやCDRを関数内で変化させると、
外部変数の内容が変更され、副作用が発生する。

(setq zoo '(dog pig))
(dog pig)
;; 関数内から仮引数lを使ってfuncの外で生成されたリストにアクセス
(defun func (l)
  ;; 先頭のセルのCARを変化させている
  (setcar l 'rat))
func
(func zoo)
rat
zoo
;; 前は(dog pig)だったセルが変更になっている。
(rat pig)

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

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