LoginSignup
2
0

More than 5 years have passed since last update.

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

Posted at

はじめに

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

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0