コンテキストがないと、これを理解するのは非常に困難です。
例:
(setq list1 (list 1 2 3 4))
これで、4 つの数値のリストができました。変数list1
は最初のコンスを指します。
破壊的なリバースを見ると、コンスセルを変更する可能性のある操作について話しています。このリストを元に戻す方法はいくつかあります。
たとえば、コンスセルを取り、それらを逆にすることができます。最初のコンスセルは最後です。次に、そのコンス セルの cdr を に変更する必要がありNIL
ます。
CL-USER 52 > (setq list1 (list 1 2 3 4))
(1 2 3 4)
CL-USER 53 > (nreverse list1)
(4 3 2 1)
ここで、変数list1
は同じコンス セルを指していますが、その cdr は変更されています。
CL-USER 54 > list1
(1)
変数が反転したリストを指していることを確認するために、プログラマは変数を更新し、nreverse
操作の結果に設定する義務があります。list1
最後の短所を示す観察可能な結果を利用したくなるかもしれません。
上記は、Lisp 開発者が通常期待するものです。リバースのほとんどの実装は、そのように機能するようです。しかし、ANSI CL 標準では、どのようnreverse
に実装する必要があるかは指定されていません。
では、代わりに CAR を変更するとはどういう意味でしょうか?
の代替実装を見てみましょうnreverse
:
(defun nreverse1 (list)
(loop for e across (reverse (coerce list 'vector))
for a on list do
(setf (car a) e))
list)
上記の関数は、コンス セルのチェーンをそのままにしておきますが、carを変更します。
CL-USER 56 > (setq list1 (list 1 2 3 4))
(1 2 3 4)
それでは、新しいバージョンのnreverse1
.
CL-USER 57 > (nreverse1 list1)
(4 3 2 1)
CL-USER 58 > list1
(4 3 2 1)
これで違いがわかります。list1
まだリスト全体を指しています。
要約: さまざまな実装がnreverse
可能なことに注意する必要があります。変数が最後のコンスを指す通常の動作を悪用しないでください。の結果を使用するだけでnreverse
、すべて問題ありません。
補足: 2 番目のバージョンはどこで使用された可能性がありますか?
Lisp マシンでの Lisp 実装の中には、コンパクトなベクトルのようなリストの表現が可能だったものがあります。そのような Lisp 実装でそのようなリストを nreverse する場合、実装者は効率的な vector-like nreverse を提供できます。