1. ホーム
  2. common-lisp

[解決済み] Common Lisp の `set`, `setq`, `setf` の違い?

2022-04-14 10:12:04

質問

Common Lispの"set", "setq", "setf"の違いは何でしょうか。

どのように解決するのですか?

もともとLispには語彙変数がなく、動的変数しかありませんでした。また SETQやSETFはなく、SET関数だけでした。

と書かれるようになったもの。

(setf (symbol-value '*foo*) 42)

と書かれていた。

(set (quote *foo*) 42)

が、やがてSETQ(SET Quoted)と略称されるようになりました。

(setq *foo* 42)

その後、レキシカル変数が登場し、SETQはレキシカル変数への代入にも使われるようになったので、もはやSETの単純なラッパーではなくなりました。

その後、誰かがデータ構造に値を割り当てる汎用的な方法としてSETF(SET Field)を考案し、他言語のl値をミラーリングするようになりました。

x.car := 42;

は次のように書きます。

(setf (car x) 42)

対称性と一般性のために、SETFもSETQの機能を提供しました。この時点で、SETQは低レベルのプリミティブ、SETFは高レベルの演算と言うのが正しいだろう。

その後、シンボルマクロが登場しました。シンボル・マクロが透過的に動作するように、代入される変数が本当にシンボル・マクロである場合、SETQはSETFのように動作しなければならないことに気づきました。

(defvar *hidden* (cons 42 42))
(define-symbol-macro foo (car *hidden*))

foo => 42

(setq foo 13)

foo => 13

*hidden* => (13 . 42)

というわけで、現代に至る。SETとSETQは古い方言の萎びた遺物で、おそらくCommon Lispの最終的な後継者からは追放されるでしょう。