読者です 読者をやめる 読者になる 読者になる

リストに取り組んだ

scheme

carとcdrとcons

リストを扱う基本操作。

  • car(カー)Contents of Address Register
    • 先頭の要素を取得
  • cdr(クダー)Contents of Decrement Register
    • 先頭を除いた要素を取得
  • cons(コンス)construct
    • リストの先頭に新しい要素を追加して返す

名前の由来

http://www.shido.info/lisp/scheme3.htmlより

car は Contents of the Address part of the Register の略で、一方、 cdr は Contents of the Decrement part of the Register の略です。これは、Lisp が実装された初期のハードウェアのメモリーの部位の名前です。このことからコンスセルの実態がメモリー領域であることが伺えます。ちなみに、cons は構成するという意味の英単語 construct の略です。

コード

(car '(7 8 9))
;result => 7
(cdr '(7 8 9))
;result => (8 9)
(cdr '(8 9))
;result => (9)
(cdr '(9))
;result => ()

car・cdrとも空リストに対して適用するとエラーになるので注意する。

あと、これも注意。
パラメータが逆だと入子になってしまう。

(cons '(1 2) 3)
;result => ((1 2) . 3)
(cons '(1 2) '(3 4))
;result => ((1 2) 3 4)

今読んでいるところに、大事な事が書いてある気がします。

【P43】より

リストは、内部的には2つのポインタを持つ対(pair)の連なりとして表現されています。
リストのcar、cdrを取ることは、それぞれリストの先頭の対の左側と右側のポインタをたどることです。

参照として下記のwikiの「リスト」の項ににわかりやすく図と解説が載っていた。
http://ja.wikibooks.org/wiki/Scheme

なるほど。

consは空リストに対しても行えるので

(cons 1 '())
;result => (1)

という書き方ができる。

入れ子にしてネストすれば「(1 2 3) 」のような長いリストができるけど、listという手続きが用意されているとのこと。

listと通常のデータは大きな違いがあって

  • listは「1 2 3」からリストを生成する
  • (1 2 3)はリストを渡しているだけ。

結果は同じでも評価プロセスの違いがあるという意識は大事。

ドットリストと正式なリスト

リストにも幾つかの表記がある事を知りました。
覚えたのは下記2つのリスト

  • ドットリスト
  • 正式なリスト

リストはpairになっていて、car部とcdr部があるという事を覚えたのですが、最後が空リストでないリストというのもありうるそうです。それが「ドットリスト」で、最後が空リストで終わっていると「正式なリスト」と呼ぶ。

なるほど。

実例

【ドットリスト】

(cons 1 2)
;result => (1 . 2)

【正式なリスト】

(cons 1 '(2))
;result => (1 2)

そうかー、最初の方でconsで逆に指定するのに注意と書いたけど、表現方法の違いなんですね。
たった2ページだけど、濃厚だなぁ。。。

この2つは書き方は違うけど、同じ正式なリストを表現していることになると。

'(1 . ())
;result => (1)
'(1)
;result => (1)

これも同じ

'(1 . (2))
;result => (1)
'(1 2)
;result => (1)

なるほど。なんか少しだけリストが分かった気がします。

リストの空を精査

null?とpair?っていう手続きがあるみたい。メソッド名がはてなで終わるってRubyみたい。
おっと、Schemeを学習する時今までやってきた言語の事は忘れるんだった(^^;

が少しだけ・・・ RubyLispに影響を受けていると聞いたことがあるのですが、この命名規則の習慣も影響も受けた一部なのかなぁ??

  • null?
    • 引数が空リストであれば真、空リストでなければ偽を返す
  • pair?
    • 引数が空でないリストであれば真、空でないリストでなければ偽を返す

コード例

(null? '(1 2))
;result => #f
(null? '())
;result => #t
(pair? '(1 2))
;result => #t
(pair? '())
;result => #f

よし!!今日は5つの手続きを覚えました。

  • car
  • cdr
  • cons
  • null?
  • pair?

気に入ったもの

  • 「くだー」という発音

今日はこれで終了。