Next: , Previous: , Up: Lists   [Contents][Index]


5.4 Building Cons Cells and Lists

リストはLispの核にあるので、リストを構築する多くの関数があります。consはリストを構築する基本的な関数です。しかしEmacsのソースコードでは、consよりlistのほうが多く使用されているのは興味深いことです。

Function: cons object1 object2

この関数は、新しいリスト構造を構築するための、もっとも基本的な関数です。この関数は、object1CARobject2CDRとする、新しいコンスセルを作成して、それから新しいコンスセルをreturnします。引数object1object2は、任意のLispオブジェクトを指定できますが、ほとんどの場合、object2はリストです。

(cons 1 '(2))
     ⇒ (1 2)
(cons 1 '())
     ⇒ (1)
(cons 1 2)
     ⇒ (1 . 2)

リストの先頭に1つの要素を追加するために、consがよく使用されます。これは、リストに要素をコンスすると言います。2たとえば:

(setq list (cons newelt list))

この例で使用されているlistという名前の変数と、以下で説明するlistという名前の関数は、競合しないことに注意してください。任意のシンボルは、両方の役割を果たすことができます。

Function: list &rest objects

この関数は、objectsを要素とするリストを作成します。結果となるリストは、常にnil終端されます。objectsを指定しない場合、空リストがreturnされます。

(list 1 2 3 4 5)
     ⇒ (1 2 3 4 5)
(list 1 2 '(3 4 5) 'foo)
     ⇒ (1 2 (3 4 5) foo)
(list)
     ⇒ nil
Function: make-list length object

この関数は、各要素がobjectの、length個の要素からなるリストを作成します。make-listmake-string(Creating Stringsを参照してください)を比較してみてください。

(make-list 3 'pigs)
     ⇒ (pigs pigs pigs)
(make-list 0 'pigs)
     ⇒ nil
(setq l (make-list 3 '(a b)))
     ⇒ ((a b) (a b) (a b))
(eq (car l) (cadr l))
     ⇒ t
Function: append &rest sequences

この関数は、sequencesのすべての要素を服務リストをreturnします。sequencesには、リスト、ベクター、ブールベクター、文字列も指定できますが、通常は最後にリストを指定するべきです。最後の引数を除くすべての引数はコピーされるので、変更される引数はありません(コピーを行なわずにリストを結合する方法については、Rearrangementnconcを参照してください)。

より一般的には、appendにたいする最後の引数は、任意のLispオブジェクトかもしれません。最後の引数は、コピーまたは変換されません。最後の引数は、新しいリストの最後のコンスセルのCDRになります。最後の引数もリストならば、このリストの要素は、実質的には結果リストの要素になります。最後の要素がリストでない場合、最後のCDRが(真リストで要求される)nilではないので、結果はドットリストになります。

以下はappendを使用した例です:

(setq trees '(pine oak))
     ⇒ (pine oak)
(setq more-trees (append '(maple birch) trees))
     ⇒ (maple birch pine oak)

trees
     ⇒ (pine oak)
more-trees
     ⇒ (maple birch pine oak)
(eq trees (cdr (cdr more-trees)))
     ⇒ t

appendがどのように機能するか、ボックスダイアグラムで見ることができます。変数treesはリスト(pine oak)にセットされ、それから変数more-treesにリスト(maple birch pine oak)がセットされます。しかし変数treesは継続して元のリストを参照します:

more-trees                trees
|                           |
|     --- ---      --- ---   -> --- ---      --- ---
 --> |   |   |--> |   |   |--> |   |   |--> |   |   |--> nil
      --- ---      --- ---      --- ---      --- ---
       |            |            |            |
       |            |            |            |
        --> maple    -->birch     --> pine     --> oak

空のシーケンスは、appendによりreturnされる値に寄与しません。この結果、最後の引数にnilを指定すると、それより前の引数のコピーを強制することになります。

trees
     ⇒ (pine oak)
(setq wood (append trees nil))
     ⇒ (pine oak)
wood
     ⇒ (pine oak)
(eq wood trees)
     ⇒ nil

これは関数copy-sequenceが導入される以前は、リストをコピーする通常の方法でした。Sequences Arrays Vectorsを参照してください。

以下は、appendの引数としてベクターと文字列を使用する例です:

(append [a b] "cd" nil)
     ⇒ (a b 99 100)

apply (Calling Functionsを参照してください)の助けを借りることにより、リストのリストの中の、すべてのリストをappendできます。

(apply 'append '((a b c) nil (x y z) nil))
     ⇒ (a b c x y z)

sequencesが与えられない場合、nilがreturnされます:

(append)
     ⇒ nil

以下は、最後の引数がリストでない場合の例です:

(append '(x y) 'z)
     ⇒ (x y . z)
(append '(x y) [z])
     ⇒ (x y . [z])

2番目の例は、最後の引数はシーケンスですがリスとではない場合で、このシーケンスの要素は、結果リストの要素にはなりません。かわりに、最後の引数がリストでないときと同様、シーケンスが最後のCDRになります。

Function: reverse list

この関数は、要素はlistの要素ですが、順序が逆の新しいリストを作成します。元の引数listは、変更されません

(setq x '(1 2 3 4))
     ⇒ (1 2 3 4)
(reverse x)
     ⇒ (4 3 2 1)
x
     ⇒ (1 2 3 4)
Function: copy-tree tree &optional vecp

この関数はツリーtreeのコピーをreturnします。treeがコンスセルの場合、同じCARCDRをもつ新しいコンスセルを作成してから、同じ方法によりCARCDRを再帰的にコピーします。

通常、treeがコンスセル以外の場合、copy-treeは単にtreeをreturnします。しかし、vecpが非nilの場合、この関数はベクターでもコピーします(そしてベクターの要素を再帰的に処理します)。

Function: number-sequence from &optional to separation

これは、fromからseparationづつインクリメントして、toの直前で終わる、数字のリストをreturnします。separationには正または負の数を指定でき、デフォルトは1です。tonil、または数的にfromと等しい場合、値は1要素のリスト(from)になります。separationが正でtofromより小さい場合、またはseparationが負でtofromより大きい場合、これらの引数は空のシーケンスを指示することになるので、値はnilになります。

separationが0で、tonilでもなく、数的にfromとも等しくない場合、これらの引数は無限シーケンスを指示することになるので、エラーがシグナルされます。

引数はすべて数字です。浮動少数の計算は正確ではないので、浮動少数の引数には用心する必要があります。たとえばマシンに依存して、(number-sequence 0.4 0.8 0.2)が3要素のリストをreturnするのに、(number-sequence 0.4 0.6 0.2)が1要素のリスト(0.4)をreturnすることがよく起こります。リストのn番目の要素は、厳密に(+ from (* n separation))という式により計算されます。したがって、リストに確実にtoが含まれるようにするには、この式に適切な型のtoを渡すことができます。別の方法として、toを少しだけ大きな値(separationが負の場合は、少しだけ小さな値)に置き換えることもできます。

いくつか例を示します:

(number-sequence 4 9)
     ⇒ (4 5 6 7 8 9)
(number-sequence 9 4 -1)
     ⇒ (9 8 7 6 5 4)
(number-sequence 9 4 -2)
     ⇒ (9 7 5)
(number-sequence 8)
     ⇒ (8)
(number-sequence 8 5)
     ⇒ nil
(number-sequence 5 8 -1)
     ⇒ nil
(number-sequence 1.5 6 2)
     ⇒ (1.5 3.5 5.5)

Footnotes

(2)

リストの最後に要素を追加するための、これと完全に同等な方法はありません。listnameをコピーすることにより、新しいリストを作成してから、neweltをそのリストの最後に追加する、(append listname (list newelt))を使用することができます。すべてのCDRを辿って、終端のnilを置き換える、(nconc listname (list newelt))を使用することもできます。コピーも変更も行なわずに、リストの先頭に要素を追加するconsと比較してみてください。


Next: , Previous: , Up: Lists   [Contents][Index]