Scheme
lisp
入門
NucoDay 18

Lisp(Scheme)超絶入門備忘録2

はじめに

 
前回に引き続き、scheme入門(備忘録)です。
相変わらずLisp経験者は読むだけ無駄です、早速やっていきます。

シンボル

 
シンボルとは?
文字列をロケーションで管理するデータ型とのこと。
シンボル同士を比較するときは、eq?などでロケーションを比較が使用可能で、高速に比較処理ができるとか・・・

端的に言うとバリューじゃなくてロケーションだけ見るよ!ってことかな。
詳しくは改めて学習しようと思います。。。。

リスト

 
ようやくリスト、一旦触ってみます。
 
リストの構成要素であるペア(コンスセル)については後述、なにはともあれ簡単に動かしてみます。
リストの定義は、値を並べて括弧で囲って書きます。python等の言語とは異なり、カンマで区切る必要はないです。
しかし(3 4)のような形式だと3が手続きと認識されてエラーとなります。 

インタプリタからしたら(print 1) これと同じ扱い。 3 なんて手続きねーよってこと。

よってシンボル、またはlist関数、make-list関数を使う必要があります。
加えて簡単なリスト操作系の関数も使用してみました。

  (print '(1 2 3)          ; (1 2 3)

  (print (list 1 2 3))     ; (1 2 3)

  (print (make-list 3 1))  ; (1 1 1)


  (define x (list 2 4 3 1 5))
  (define y (list 6 7 8 9 0))

  ; listかどうか
  (print (list? x))        ; #t

  ; listの長さ
  (print (length x))       ; 5

  ;指定位置要素の抽出
  (print (list-ref x 3))   ; 1

  ; 反転
  (print (reverse x))      ;(5 1 3 4 2)

  ;listの連結
  (print (append x y))     ; (2 4 3 1 5 6 7 8 9 0)


 
 

シンボルでのリスト定義をした場合に x がバリューではなくシンボルとして格納されてしまうので注意が必要です。

(define x 4)

(print(list 1 2 3 x)) ;(1 2 3 4)

(print'(1 2 3 x))     ;(1 2 3 x)

 

コンスセル

 
では改めて、ペア(コンスセル)についてちょっと確認していきます。

'(1 2 3 4 5)について

1,2,3,4,5と一見それぞれのバリューがキーに格納される様なイメージが持てますが、
その脳みそは捨ててください。
リストは全てペア(carとcdr)の集まりから構成されいる、といった感じです。
 

左側をcar(カー)、右側をcdr(クダー)、この纏りをペア(コンスセル)と呼びます。
いや、どこまでがcar?cdr?ペア?ってなりますよね・・・・

説明が下手くそなのでさっさと動かして確認していきましょ。

(define x '(1 2 3 4 5))

(print (car x)) ; 1

(print (cdr x)) ; (2 3 4 5)

xのcar、cdrの出力結果は上記です。

carはペア(x)の最初の要素
cdrはリストの残りの部分となります。
carとcdrを箱と捉え、その2つの箱の組み合わせがペア

こんな感じですかね!!

次にxから 2 を出力してみます。
前述の通りxのcdrが (2 3 4 5) ということは
このcdrはリスト、ペアとなるから、そのcarが 2 になるはずだ!!
ついでにそのcdrが(3 4 5) のはずだ!!
 
 

(define x '(1 2 3 4 5))

(print (car(cdr x))) ; 2

(print (cdr(cdr x))) ; (3 4 5)


はい、おk。
なるほど、こんな感じでコンスセルの構成が理解できました、やったぜ。
 
 

もちろんリストのペアには終点があります。
そしてcarとcdrは常に1対1でペアとして存在する為、 x のcarが5になるとき、cdrとなる要素は空リストとなります。
再帰的な処理とかに便利な構成ですね。

(define x '(1 2 3 4 5))

(print (cdr x))                     ;(2 3 4 5)

(print (cdr(cdr x)))                ;(3 4 5)

(print (cdr(cdr(cdr x))))           ;(4 5)

(print (cdr(cdr(cdr(cdr x)))))      ;(5)

(print (cdr(cdr(cdr(cdr(cdr x)))))) ;()

続いてcons関数でリストにペアを追加してみます。

(define x '(1 2 3 4 5))

(define y (cons 7 x))

(print y)       ;(7 1 2 3 4 5)

(print (car y)) ; 7

まとめ

今回はリストの構造やら何やらをメインに学習してみました。
二分木構造ってやつですかね。ちょっとこれを活かして何かしら書いてみたいと思います。
そして次回こそlambdaやらmapやら・・・ごめんなさい。