#はじめに
前回に引き続き、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やら・・・ごめんなさい。