HyperSpecの #' adjoin のドキュメントを見ると、例のセクションに次のように表示されます。
(setq slist '()) => NIL
(setq slist (adjoin '(test-item 1) slist)) => ((TEST-ITEM 1))
(adjoin '(new-test-item 1) slist :key #'cadr) => ((TEST-ITEM 1))
代わりに、次のことを期待していました。
(adjoin '(new-test-item 1) slist :key #'cadr) => ((NEW-TEST-ITEM 1) (TEST-ITEM 1))
私の予想は、HyperSpec (17.2.1)の次のテキストによるものです。
オブジェクト O が、次の図にリストされている演算子 F によって、シーケンス S の各要素 Ei に対して反復的に考慮されている場合、S 内の O の存在が F によってテストされる方法を制御すると便利な場合があります。制御は、:test または :test-not 引数で指定された関数に基づいて提供されます。
そしてさらに:
オブジェクト O は Ei と直接比較できない場合があります。:key 引数が指定されている場合、これは各 Ei を引数として呼び出される 1 つの引数の関数の指定子であり、比較に使用されるオブジェクト Zi を生成します。(:key 引数がない場合、Zi は Ei です。)
:key 引数で指定された関数は、O 自体では呼び出されません。ただし、関数が複数のシーケンスで動作する場合 (たとえば、set-difference で発生する場合)、O は、他のシーケンスの要素で :key 関数を呼び出した結果になります。
したがって、slist (シーケンス、S) as'((TEST-ITEM 1))
と O as があり'(new-test-item 1)
ます。O が隣接する必要があるかどうかを確認するために、関数#'cadr
が S の要素に適用されます。最初の要素は'(test-item 1)
です。したがって、そのテストは次のようになります。
(cadr '(test-item 1)) => 1
ここで、O, ,を S の E1 に( が指定されていない場合に使用される等価関数)'(new-test-item 1)
で適用した結果と照合すると、結果はO が隣接していることを意味するはずです。少なくとも私はそう思います。私は何を誤解していますか?#'cadr
#'eql
:test
false