(defun get-binding (var bindings) "バインディング情報bindings の中に 変数varのバインディング情報が 入っているかどうかを調べる" (assoc var bindings)) (defun binding-var (binding) (car binding)) (defun binding-val (binding) (cdr binding)) (defun make-binding (&key var val) (cons var val)) (defun lookup (var bindings) (binding-val (get-binding var bindings))) (defun add-binding (var val bindings) (cons (make-binding :var var :val val) bindings))連想リストではなく,構造体のリストを用いても実現することが可能です.構 造体の場合には,binding-var, binding-val, make-bindingは自動的に生成さ れます.
(defstruct binding var val) (defun get-binding (var bindings) (find var bindings :key #'binding-var)) (defun lookup (var bindings) (let ((x (get-binding var bindings))) (if x (binding-val x))))この場合,以下のように値が返ります.
<cl> (match '(?a ?a) '(x y)) FAIL <cl> (match '(?a ?a) '(x x)) (#s(BINDING :VAR ?A :VAL X)) <cl> (match '(?a ?a) '(y y)) (#s(BINDING :VAR ?A :VAL Y)) <cl> (match '(x y z) '(x y z)) NILリストではなく,ハッシュ表を用いる方法では,
(defun get-binding (var bindings) (let ((v (gethash var bindings))) (if v (cons var v) nil))) (defun lookup (var bindings) (gethash variable bindings)) (defun add-binding (var val bindings) (setf (gethash var bindings) val) bindings)という具合に定義すればよさそうです.変数が多くなった場合には,ハッシュ 表を用いる方法が有効であろうが,数が少ない場合には連想リストで十分であ る. いずれにせよ,基本関数の定義内容を変えることで内部表現の変更が マッチング関数へ影響を及ぼさないように定義することは可能である.