% Function SUBST, SUBST-IF, SUBST-IF-NOT, NSUBST, NSUBST-IF, NSUBST-IF-NOT
Function SUBST
, SUBST-IF
, SUBST-IF-NOT
,
NSUBST
, NSUBST-IF
, NSUBST-IF-NOT
subst
new old tree &key key test test-not => new-tree
subst-if
new predicate tree &key key => new-tree
subst-if-not
new predicate tree &key key => new-tree
nsubst
new old tree &key key test test-not => new-tree
nsubst-if
new predicate tree &key key => new-tree
nsubst-if-not
new predicate tree &key key => new-tree
new - オブジェクト
old - オブジェクト
predicate - 関数名のシンボルか、
1つの引数をとりgeneralized-booleanを返却する関数
tree - ツリー
test - 2つの引数を取りgeneralized-booleanを返却する関数の指定子
test-not - 2つの引数を取りgeneralized-booleanを返却する関数の指定子
key - 1つの引数を取りgeneralized-booleanを返却する関数の指定子、
またはnil
new-tree - ツリー
subst
, subst-if
, subst-if-not
は、
treeの置換操作を行います。
各関数はtreeに対してtestを満たすような特定のold要素か、
あるいは部分式を満たすものを検索します。
nsubst
, nsubst-if
, nsubst-if-not
はそれぞれ
subst
, subst-if
, subst-if-not
と似ていますが、
元のtreeを修正するところが違っています。
subst
はtreeのコピーを作成し、
全てのサブツリー、葉、親のcar
部、cdr
部、すべてに対して
oldとtestが満たされる部分をnewに置換します。
nsubst
は、subst
の破壊的バージョンです。
treeのリスト構造は、それぞれのtreeの葉に対して、
oldとtestが満たされる葉の部分を
newで破壊的に置換することによって変更されます
subst
, subst-if
, subst-if-not
は、
もし関数が成功すると、
指定された要素のそれぞれの出現をnew要素で置き換えられたものか、
あるいは部分式で置き換えられたものの新たなコピーが返却されます。
もし変更が生じなかったときは、元のtreeが返却されるかもしれません。
元のtreeが変更されないとしても、
返却値のツリーは元のツリーと
ストレージを共有しているかもしれません。
nsubst
, nsubst-if
, nsubst-if-not
は、
元のtreeを修正し返却します。
しかし関数の結果は、treeとeq
で等しくないかもしれません。
(setq tree1 '(1 (1 2) (1 2 3) (1 2 3 4))) => (1 (1 2) (1 2 3) (1 2 3 4))
(subst "two" 2 tree1) => (1 (1 "two") (1 "two" 3) (1 "two" 3 4))
(subst "five" 5 tree1) => (1 (1 2) (1 2 3) (1 2 3 4))
(eq tree1 (subst "five" 5 tree1)) => implementation-dependent
(subst 'tempest 'hurricane
'(shakespeare wrote (the hurricane)))
=> (SHAKESPEARE WROTE (THE TEMPEST))
(subst 'foo 'nil '(shakespeare wrote (twelfth night)))
=> (SHAKESPEARE WROTE (TWELFTH NIGHT . FOO) . FOO)
(subst '(a . cons) '(old . pair)
'((old . spice) ((old . shoes) old . pair) (old . pair))
:test #'equal)
=> ((OLD . SPICE) ((OLD . SHOES) A . CONS) (A . CONS))
(subst-if 5 #'listp tree1) => 5
(subst-if-not '(x) #'consp tree1)
=> (1 X)
tree1 => (1 (1 2) (1 2 3) (1 2 3 4))
(nsubst 'x 3 tree1 :key #'(lambda (y) (and (listp y) (third y))))
=> (1 (1 2) X X)
tree1 => (1 (1 2) X X)
nsubst
, nsubst-if
, nsubst-if-not
は、
treeのツリー構造を変更するかもしれません。
なし。
なし。
substitute
,
nsubstitute
,
3.2.1. コンパイラーの用語,
3.6. 横断の規則と副作用
:test-not
パラメーターは非推奨です。
関数subst-if-not
とnsubst-if-not
は非推奨です。
subst
は一例として次のように定義できます。
(defun subst (old new tree &rest x &key test test-not key)
(cond ((satisfies-the-test old tree :test test
:test-not test-not :key key)
new)
((atom tree) tree)
(t (let ((a (apply #'subst old new (car tree) x))
(d (apply #'subst old new (cdr tree) x)))
(if (and (eql a (car tree))
(eql d (cdr tree)))
tree
(cons a d))))))