Posted at
NucoDay 18

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

More than 1 year has passed since last update.


はじめに

 

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