6

Common-Lisp では、この最初/最後のことがわかりません。はい、それがどのように機能するかはわかりますが、なぜそのように機能するのかわかりません。

基本的に、リストの最初の項目を取得するには、 を使用できます(first mylist)。ただし、最後のアイテムが必要な場合は、それ(last mylist)が得られません。代わりに、リストの最後の項目を含むリストが表示されます!

(私は Clozure-CL を使用していますが、これには他にもバグのように見える奇妙な点がいくつかありますが、私は Lisp-n00b であるため、古い「インタープリターが壊れている!」というトリックに引っかからないようにしています。 :) )

たとえば、次のようになります。

? (setq x '((1 2) (a b)))
=> ((1 2) (A B))

? (first x)
=> (1 2)  ; as expected

? (last x)
=> ((A B))  ; why a list with my answer in it?!

? (first (last x))
=> '(A B)  ; This is the answer I'd expect from plain-old (last x)

なぜ最後にこれを行うのかを誰かが理解するのを手伝ってくれますか? これらのアイテムを間違って使用していますか? 本当にfirstオッドボールなのか!?

ありがとう!

4

4 に答える 4

8

Common Lisp では、ドキュメントlastからリストを返すことになっています:

last list &optional n => tail
list---a list, which might be a dotted list but must not be a circular list.
n---a non-negative integer. The default is 1.
tail---an object. 

last は、list の最後の n 個のコンス (最後の n 個の要素ではない) を返します。list が () の場合、last は () を返します。

例えば:

(setq x (list 'a 'b 'c 'd))
(last x) =>  (d)

はい、これは直感に反します。Lisp の他のフレーバーでは、名前が示すように動作します。たとえば、Racket (Scheme 方言) では次のようになります。

(define x '((1 2) (a b)))
(first x) => '(1 2)
(last x) => '(a b)

(define x (list 'a 'b 'c 'd))
(last x) =>  'd
于 2013-07-18T19:14:12.527 に答える
7

最後の要素にアクセスする場合を除いて、最後の要素を返すことはあまり役に立ちません。最後のコンスを返すと、次のようなことができます。

(let ((x (list 1 2 3)))
  (setf (cdr (last x)) '(4))
  x)

=> '(1 2 3 4)

として最後の要素に引き続きアクセスできます(car (last x))

于 2013-07-18T19:58:28.880 に答える
4

Common Lisp の誤った名前の関数lastは、最後のconsを提供します。

tailfunction があるので、おそらく と呼ばれるべきtailpですが、私の推測では、この名前は歴史的/互換性の理由で固定されていると思います。

通常、リストのn 番目の末尾、またはリストの終わりの前のn 番目のコンスを提供します。

于 2013-07-18T19:17:45.867 に答える
4

これはまさにその通りです。操作の補完的なペアではありませんfirst。と により密接に関連しています。指定されたリストから最後の項目を省略した新しいリストを構築するものもあります。lastlastrestnthcdrbutlast

firstlastvsは howgetと比較しgetfて何もなく、setandとは何の関係もありませんsetf

于 2013-07-18T19:47:38.277 に答える