3

elispについて質問があります。例えば:

(setq trees '(maple oak pine birch))
      -> (maple oak pine birch)
(setcdr (nthcdr 2 trees) nil)
      -> nil
trees
      -> (maple oak pine)

(nthcdr 2 trees)私は新しいリストを返すと思いました-(pine birch)そしてそのリストをsetcdr式に入れます。これはの値を変更するべきではありませんtrees。誰かが私にそれを説明できますか?

4

3 に答える 3

4

のドキュメント文字列を読むとnthcdr、元のリストへのポインタである「nth」「cdr」へのポインタが返されるだけであることがわかります。したがって、元のリストを変更しています。

ドキュメント文字列:

Take cdr N times on LIST, return the result.

編集うわー、「ポインタ」は混乱をかき立てるようです。はい、Lispにはポインタがあります。

lispのリスト構造を説明するために使用されるボックス図を見てください(これはまさにそのことに関するEmacsのドキュメントです):

     --- ---      --- ---      --- ---
    |   |   |--> |   |   |--> |   |   |--> nil
     --- ---      --- ---      --- ---
      |            |            |
      |            |            |
       --> rose     --> violet   --> buttercup

それらすべての矢印を見てください、それらはほとんどそれらが物事を指しているように見えます。リストをcdr取得すると、2番目のボックスが参照するもの(別名「ポイント」)が取得されます。これは、アトム、文字列、または別のconsセルです。ちなみに、ウィキペディアのCARとCDRのエントリをチェックしてください。

それを参照と呼ぶ方が良いと感じる場合は、その用語を使用してください。

cdr確かに、それが参照しているもののコピーを返しません。これは、 RNAerを混乱させていたものです。

于 2013-02-06T06:35:17.597 に答える
3

R:「ほら、空に!ラムダ信号!市民がラムダマンに困っている!」

LM:「わかりました!そして、彼らが必要とするボックスアートだけを持っています。」


Lispsでは、リストは単一にリンクされたデータ構造であり、consセルと呼ばれる要素で構成されています。これらの各セルは、

  1. 値へのポインタ
  2. 次のセルへのポインタ

これらは歴史的な理由からそれぞれcarcdrと呼ばれています。3要素のリストを表す従来のボックスアートは次のとおりです。

Structure:    (car . cdr -)--->(car . cdr -)--->(car . cdr)
                |                |                |      |
                v                v                v      v
Values:         1                2                3     nil

carand関数を使用するcdrと、この低レベルの抽象化からのリストを操作して、それぞれのセルの値を返すことができます。したがって、carセルの「値」を返し、cdrリストの残りの部分を逆参照します。便宜上nthcdrの上の一般化です。cdr

によって返される値はcdr、このレベルで変更可能な生データ構造への参照です。cons-cellのcdrの値を変更すると、リストの基本構造が変更されます。

与えられた:

 let A = '(1 2)    ~= (1 . -)-->(2 . nil)

 let B = '(3 4)    ~= (3 . -)-->(4 . nil)

のcdr(cdr A)をBに設定すると、AとBが破壊的に連結され、Aは次の構造になります。

 A                   B     
 (1 . -)-->(2 . -)-->(3 . -)-->(4 . nil)

すでに示したようにnil、セルのcdrの値は、リストの最後を表します。これ以上、トラバースできるものはありません。Aのcdrをに設定するとnil、リストがロボトミー化され、Aが

A                  
(1 . nil)  <- [Not pointing to anything - the rest of the list shall go wanting]

これは、あなたが行ったこととほぼ同じです。低レベルの関数を使用して、基になるデータ構造を変更しました。:)セルのcdrの1つをに設定することによりnil、リストの最後を削除しました。

于 2013-02-06T10:25:42.067 に答える
0

これは「突然変異」と呼ばれます。そして、Haskell以外のどこにでも存在します。

データ構造を変更する関数とそれを複製する関数があります。

于 2013-02-06T10:24:57.843 に答える