一般化変数

一般的に、どんな値および属性もオブジェクトのスロット(またはスタック) で表現される。 スロットの値を引き出すかまたは変えるときは、 2つの基本的な命令、accessupdateで行わなければならない。 オブジェクトの全てのスロットに対して2つの異なった基本命令を定義する代りに EusLispでは、Common Lispのように、一般化変数コンセプトに基づいた 画一的な更新命令を備えている。 このコンセプトのなかで、共通書式は、値のアクセス書式あるいはスロットの位置指定 として認識される。 したがって、それぞれのスロットに対してアクセスする書式を覚えてさえおけば、更新は そのアクセス書式とsetfマクロを組み合わせることにより 実現できる。 例えば、car値をリストの外に取り出すのと同じ様に(setf (car '(a b)) 'c) としてsetfを使用したとき、(car x)xのcarスロットのなかの 値を置き換えることに使用することができる。

この方法は、ユーザーが定義したオブジェクト全てに対して 適用できる。 クラスや構造体が定義されるとき、それぞれのスロットに対する accessやupdate書式は、自動的に定義される。 それらの書式は、それぞれマクロとして定義されている。その名前は、 クラス名とスロット名の連結となる。 例えば、consのcarは(cons-car '(a b c))で処理することができる。

(defclass person :super object :slots (name age))
(defclass programmer :super person :slots (language machine))
(setq x (instantiate programmer))
(setf (programmer-name x) "MATSUI"
      (person-age x) 30)
(incf (programmer-age x))
(programmer-age x)   --> 31
(setf (programmer-language x) 'EUSLISP
      (programmer-machine x) 'SUN4)

行列要素も同じ手法でアクセスすることができる。

(setq a (make-array '(3 3) :element-type :float))
(setf (aref a 0 0) 1.0 (aref a 1 1) 1.0 (aref a 2 2) 1.0)
a --> #2f((1.0 0.0 0.0) (0.0 1.0 0.0) (0.0 0.0 1.0))

(setq b (instantiate bit-vector 10))  --> #*0000000000
(setf (bit b 5) 1)
b --> #*0000010000

特定のオブジェクトに特別なsetfメソッドを定義するために defsetfマクロを用意している。

(defsetf symbol-value set)
(defsetf get (sym prop) (val) `(putprop ,sym ,val ,prop))



2016-04-05