トップ > Script-Fuスクリプトの制作 >
プログラミング言語Schemeの基礎を学ぶ(その3)

  

プログラミング言語Schemeの基礎(続き)

前の記事の『プログラミング言語Schemeの基礎を学ぶ(その2)』からの続きです。 引き続き、Script-Fuスクリプトを制作するにあたって知っておきたいSchemeの基礎的な内容について解説します。

この記事では、Schemeの特徴といってもいい "リスト" について解説します。 リストを知らなければ、Script-Fuスクリプトを制作するのは難しいでしょう。

リストとは

リストとは、文字通り複数の情報が並んだものです。 例えば従業員の情報を表すリストであれば、

  1. 太陽 昇
  2. 頂上 高志
  3. 未来 明子

のように氏名がズラッと並んだものがリストになります。

リストと聞いてどんなモノをイメージすべきか

『リストとは、文字通り複数の情報が並んだもの』と説明しました。 さらに、従業員のリストを例に挙げました。

その結果、みなさんは今、人名がズラッと並んだ名簿のようなものを思い浮かべていることでしょう。 しかし、名簿を思い浮かべるとリストの理解の妨げになります。

思い浮かべるべきは、入れ子になった箱です。 箱の中に別の箱が入れられ、さらにその中には別の箱が入っている様子です。 どの箱も仕切りで2つの枠に分けられています

2つに仕切られたそれらの箱は、コンスセルと呼ばれます

太陽 昇
頂上 高志
未来 明子
<空っぽ>

最初のコンスセルの枠1には "太陽 昇" と書かれた紙が入っています。 もう一方の枠2には2つ目のコンスセルが入れられています。

2つ目のコンスセルの枠1には "頂上 高志" と書かれた紙が入っています。 もう一方の枠2には3つ目のコンスセルが入っています。

3つ目のコンスセルの枠1には "未来 明子" と書かれた紙が入っています。 もう一方の枠2には何も入っていません。

このように、コンスセル(箱)の中に別のコンスセルが収まっている様子を想像してください。

リストを使ってみる

では、実際にリストを利用してみましょう。 スクリプトファイル myscript.scm を以下のように修正してください。

  1. (define (myscript)
  2. (let*
  3. (
  4. (outnumber 9)
  5. (innumber (list 20 30))
  6. )

  7. (set! outnumber (myfunc-addnumber innumber))

  8. (gimp-message (string-append "Number is " (number->string outnumber)))
  9. )
  10. )

  11. (define (myfunc-addnumber x y)
  12. (+ x y)
  13. )

  14. (script-fu-register
  15. "myscript" ; 登録する関数の名前
  16. "My Script" ; メニュー項目のラベル
  17. "自作の練習用スクリプトです" ; メニュー項目の説明
  18. "My Name" ; 作成者の名前
  19. "My Name" ; 著作権者の名前
  20. "January 1, 2023" ; 作成日(改訂日)
  21. "" ; メニュー項目を有効にするための条件
  22. )

  23. (script-fu-menu-register
  24. "myscript" ; 対象の関数の名前
  25. "<Image>/Filters" ; メニュー項目の位置
  26. )
 

修正箇所は2箇所あり、1箇所目は5行目で、

(innumber  outnumber)

を、

(innumber  (list 20 30))

に変更しています。 それまでは変数 innumberの初期値に変数 outnumberの中身をセットしていましたが、これを変更し "(list 20 30)" の結果を初期値とするようにしました。

手続き listはリストを作成するための手続きであり、"(list 20 30)" という命令で作成されるリストを入れ子のコンスセルで表現すると、

20
30
<空っぽ>

となります。 変数 innumberには、このリストが初期値として格納されます

修正箇所の2箇所目は8行目で、

(set! outnumber (myfunc-addnumber 10 20))

を、

(set! outnumber (myfunc-addnumber innumber))

に変更しています。 関数 myfunc-addnumberに渡す引数を 10 と 20 から、変数 innumberの中身に変更しました。

変数 innumberの中身は 20 と 30 から構成されるリストです。 つまり、リストに含まれている 20 と 30 を渡して、結果の 50 を得ようという考えです。


では、実行してみましょう。 どうなるでしょうか。

1. エラーが発生する
1. エラーが発生する

上図のようにエラーが発生します。 エラー内容は、

  1. "not enough arguments"

となっています。 エラー内容を直訳すると、

  1. "引数が不足しています"

という意味になります。 引数が足りないゾ、と言って怒っています。

エラーが発生した原因

自作の関数 myfunc-addnumberは14行目を見ればわかるように、

(define (myfunc-addnumber x y)

と定義されています。 関数の名前の後ろに x と y が記述されていることから、受け取る引数は2つだということがわかります。

しかし8行目では、

(set! outnumber (myfunc-addnumber innumber))

のように変数 innumberだけを渡しています。 つまり、引数は1つしか渡していないのです。 引数を2つ受け取る関数に引数を1つしか渡していないためエラーとなったのです。

しかも、変数 innumberに格納されているのはリストであり、入れ子のコンスセルで表現すると、

20
30
<空っぽ>

という代物です。 関数 myfunc-addnumberにしてみれば、2つの引数を受けとろうとしているのに予想外に2重の箱を渡されたようなものです。


エラーが発生した原因はわかりました。 2つの引数を渡さなければいけないのに、2重の箱を1つだけ渡していることが原因です。 これを修正し、最初のコンスセルの中身の 20 と2番目のコンスセルの中身の 30 をそれぞれ取り出して渡すようにしましょう。

修正後のスクリプトファイル myscript.scm の内容は以下のようになります。

  1. (define (myscript)
  2. (let*
  3. (
  4. (outnumber 9)
  5. (innumber (list 20 30))
  6. )

  7. (set! outnumber (myfunc-addnumber (car innumber) (car (cdr innumber))))

  8. (gimp-message (string-append "Number is " (number->string outnumber)))
  9. )
  10. )

  11. (define (myfunc-addnumber x y)
  12. (+ x y)
  13. )

  14. (script-fu-register
  15. "myscript" ; 登録する関数の名前
  16. "My Script" ; メニュー項目のラベル
  17. "自作の練習用スクリプトです" ; メニュー項目の説明
  18. "My Name" ; 作成者の名前
  19. "My Name" ; 著作権者の名前
  20. "January 1, 2023" ; 作成日(改訂日)
  21. "" ; メニュー項目を有効にするための条件
  22. )

  23. (script-fu-menu-register
  24. "myscript" ; 対象の関数の名前
  25. "<Image>/Filters" ; メニュー項目の位置
  26. )
 

修正箇所は8行目で、

(set! outnumber (myfunc-addnumber innumber))

を、

(set! outnumber (myfunc-addnumber (car innumber) (car (cdr innumber))))

と修正しています。 新たな手続き car と cdr が登場しました。

手続き car

手続き carは、リストの最初のコンスセルの枠1の中身を取り出すための手続きです。

  
car は "カー" と発音します。

今回のリストの、

20
30
<空っぽ>

であれば 20 が取り出されます。

手続き cdr

手続き cdrは、リストの最初のコンスセルの枠2の中身を取り出すための手続きです。

  
cdr は "クダー" と発音します。

今回のリストの、

20
30
<空っぽ>

であれば、

30
<空っぽ>

が取り出されます。 つまり、取り出されるものもリストなのです。 大切なことなのでもう一度いいます。 リストに対する手続き cdrで取り出されるのはリストです


手続き carと手続き cdrの意味がわかりました。 それでは、修正したスクリプトを実行してみましょう。

2. ウィンドウ下部に "Number is 50" と表示される
2. ウィンドウ下部に "Number is 50" と表示される

上図のようにウィンドウ下部に "Number is 50" と表示されます。 やりました、思い通りの結果です。

では、変更点である8行目が、どのように解釈され実行されたのか見ていきましょう。 8行目は、

(set! outnumber (myfunc-addnumber (car innumber) (car (cdr innumber))))

と修正しました。 手続き carはリストの最初のコンスセルの枠1の中身を取り出しますので、

(set! outnumber (myfunc-addnumber 20 (car (cdr innumber))))

と解釈されます。

続いて、手続き cdrの部分を見てみましょう。 手続き cdrはリストの最初のコンスセルの枠2の中身を取り出しますので、

(set! outnumber (myfunc-addnumber 20 (car (list 30))))

と解釈されます。 なお "(list 30)" は、

30
<空っぽ>

のことです。

さらにその外側にある手続き carによって、

(set! outnumber (myfunc-addnumber 20 30))

と解釈されます。 つまり、リストではなく、リストの中身を引数として渡している状態になりました。 結果、最終的に、"Number is 50" というメッセージが表示されました。

手続き cadrを使えば短く記述をすることができる

作成中のスクリプトは、少し省略して短く記述することができます。 具体的には、手続き carと手続き cdrの組み合わせの効果を、1つの手続き cadrで実現できるのです。

  
cadr は "カダー" と発音します。

手続き cadrはリストの2番目のコンスセルの枠1の中身を取り出すためのものです。 今回のリストの、

20
30
<空っぽ>

からは、30が取り出されます。

実際に手続き cadrを使ってみましょう。 スクリプトファイル myscript.scm を以下のように修正してください。

  1. (define (myscript)
  2. (let*
  3. (
  4. (outnumber 9)
  5. (innumber (list 20 30))
  6. )

  7. (set! outnumber (myfunc-addnumber (car innumber) (cadr innumber)))

  8. (gimp-message (string-append "Number is " (number->string outnumber)))
  9. )
  10. )

  11. (define (myfunc-addnumber x y)
  12. (+ x y)
  13. )

  14. (script-fu-register
  15. "myscript" ; 登録する関数の名前
  16. "My Script" ; メニュー項目のラベル
  17. "自作の練習用スクリプトです" ; メニュー項目の説明
  18. "My Name" ; 作成者の名前
  19. "My Name" ; 著作権者の名前
  20. "January 1, 2023" ; 作成日(改訂日)
  21. "" ; メニュー項目を有効にするための条件
  22. )

  23. (script-fu-menu-register
  24. "myscript" ; 対象の関数の名前
  25. "<Image>/Filters" ; メニュー項目の位置
  26. )
 

修正したのは8行目で、

(set! outnumber (myfunc-addnumber (car innumber) (car (cdr innumber))))

を、

(set! outnumber (myfunc-addnumber (car innumber) (cadr innumber)))

に変更しています。

では、実行してみましょう。 どうなるでしょうか。

1. ウィンドウ下部に "Number is 50" と表示される
1. ウィンドウ下部に "Number is 50" と表示される

上図のようにウィンドウ下部に "Number is 50" と表示されます。 修正前と同じ結果です。

このように、2番目のコンスセルの中身を取り出す命令である、

(car (cdr innumber))

は、

(cadr innumber)

と短く記述できる、という話題でした。

枠1・枠2は正式にはcar部・cdr部と呼ばれる

この記事では、コンスセルの2つの枠のことを、枠1・枠2と表現してきました。 しかし、プログラミング言語Schemeの正式な用語では、

  1. car部
  2. cdr部

と呼ばれます。 例えば、

太陽 昇
頂上 高志
未来 明子
<空っぽ>

というリストであれば、car部は、

太陽 昇

のことであり、cdr部は、

頂上 高志
未来 明子
<空っぽ>

のことを指します。

これ以降は、正式な表現である、car部cdr部と表記します。

caddrやcadddrってないの?

3番目のコンスセルのcar部を取り出すための手続き caddr(カダダー)や、4番目のコンスセルのcar部を取り出す手続き cadddr(カダダダー)もあります。

冗談みたいですが本当にあるんです。 例えば、

太陽 昇
頂上 高志
未来 明子
<空っぽ>

というリストであれば、手続き caddrは、

未来 明子

を返します。

ただし、Script-Fuでのプログラミングでは、

  1. car(カー)
  2. cdr(クダー)
  3. cadr(カダー)

の3つを知っていれば十分なように思います。

手続き listを使わずにリストを作ってみよう

作成中のスクリプトでは、

(innumber  (list 20 30))

のように、手続き listを利用してリストを作成しています。 手続き listを利用するのは悪いことではありませんが、ここでは別の方法についても紹介しておきます

  
他人が作成したScript-Fuスクリプトを読む場合などに知っておいた方がいいと思ったので紹介することにしました。

リストを作成する別の方法とは、手続き quoteを使う方法です。 ただし、手続き quoteを使いたくて使うわけではありません。 手続き listを使わずに、かつ、簡単にリストを作るには手続き quoteを使うしかないのです。

少々難し話になりますが、順を追って説明します。 実際にスクリプトを実行しながら話を進めていきましょう。 なお、スクリプトファイルから読み込ませるのではなく、Script-Fu コンソールから実行します

では、Script-Fu コンソールからスクリプトを打ち込んでみましょう。 まずは、リストとは関係のない四則演算するだけのスクリプトです。

1. '(- 10 (+ 1 3))'と打ち込む
1. '(- 10 (+ 1 3))'と打ち込む

上図のようにScript-Fu コンソールを開き、[参照(B)...]ボタンの左側の入力欄に、


(- 10 (+ 1 3))

 

と打ち込んでください。 最後にEnterキーを押すのを忘れないでください

2. Script-Fu コンソールの上部に 6 が表示される
2. Script-Fu コンソールの上部に 6 が表示される

上図のようにScript-Fu コンソールの上部に 6 と表示されます。 1 と 3 が加算された結果である 4 が 10 から引かれた結果です。

今回実行したスクリプトでは、まずは加算の命令である "(+ 1 3)" が実行されます。 その結果は 4 ですので、続いて、

(- 10 4)

と解釈されて実行されます。 結果はもちろん 6 になります。 ここまでは難しいことはありません。

ではここで、スクリプトをちょっとだけ変えてみましょう。

3. '(- 10 4)'と打ち込む
3. '(- 10 4)'と打ち込む

上図のようにScript-Fu コンソールから、


(- 10 4)

 

と打ち込んでください。

4. Script-Fu コンソールの上部に 6 が表示される
4. Script-Fu コンソールの上部に 6 が表示される

上図のようにScript-Fu コンソールの上部に 6 と表示されます。 打ち込んだスクリプトは変えましたが、結果は同じになりました

ここで一度整理しておきましょう。 最初に実行したスクリプトの、

(- 10 (+ 1 3))

という命令の中にある加算の命令 "(+ 1 3)" の部分を変更し、

(- 10 4)

と打ち込みましたが、結果は変更前と同じになりました。 なお、結果が同じになることに驚きはないと思います

結果が同じというなら、今回の変更点である、

(- 10 (+ 1 3))

という行を、

(- 10 4)

に変更したことには、一体どういう意味があるのでしょうか。 それとも意味などなかったのでしょうか。 大丈夫、意味はあります。 今回の変更による意味は、

  1. 手続き +を実行していないのでスクリプトの動作が速くなった

ということです。 命令 "(+ 1 3)" の結果はわかっているんだから、最初から "4" と記述すればいい、ということです。

変更前のスクリプトである、

(- 10 (+ 1 3))

は、『1 と 3 と足したものを 10 から引きなさい』という指示です。 一方、変更後の、

(- 10 4)

は、『10 から 4 を引きなさい』という指示です。 実行する命令が1つ減っている分だけ動作が速くなるのです


では、リストの話題に戻りましょう。 リストを題材に、同じように結果がわかっている部分を置き換えてみましょう。 引き続き、Script-Fu コンソールからスクリプトを打ち込んでいきます。

5. '(cadr (list 1 2 3))'と打ち込む
5. '(cadr (list 1 2 3))'と打ち込む

上図のようにScript-Fu コンソールから、


(cadr (list 1 2 3))

 

と打ち込んでください。

6. Script-Fu コンソールの上部に 2 が表示される
6. Script-Fu コンソールの上部に 2 が表示される

上図のようにScript-Fu コンソールの上部に 2 と表示されます。 手続き cadrは2番目のコンスセルのcar部を取り出しますので 2 が取り出されました。

では続いて、手続き listの命令だけを実行してみましょう。 置き換えたい部分が、まさにココです。

7. '(list 1 2 3)'と打ち込む
7. '(list 1 2 3)'と打ち込む

上図のようにScript-Fu コンソールから、


(list 1 2 3)

 

と打ち込んでください。

8. Script-Fu コンソールの上部に (1 2 3) が表示される
8. Script-Fu コンソールの上部に (1 2 3) が表示される

上図のようにScript-Fu コンソールの上部に (1 2 3) と表示されます。 ここで注目すべきはリストの表現です。 見ての通り、'(' と ')' で囲まれています

そうです、リストはカッコで囲まれて表現されるのです。 文字列が二重引用符 (") で囲まれているように、リストは カッコで囲まれて表現される、というわけです。

では、そろそろ本題です。 前出のスクリプトの手続き listの部分を置き換えてみましょう。

(list 1 2 3)

の部分を、

(1 2 3)

に置き換える、という意味です。

9. '(cadr (1 2 3))'と打ち込む
9. '(cadr (1 2 3))'と打ち込む

上図のようにScript-Fu コンソールから、


(cadr (1 2 3))

 

と打ち込んでください。

10. Script-Fu コンソールの上部に "Error: illegal function" が表示される
10. Script-Fu コンソールの上部に "Error: illegal function" が表示される

上図のようにScript-Fu コンソールの上部に "Error: illegal function" と表示されます。 エラーが発生し、スクリプトは実行されませんでした

エラーの原因は、みなさんお気づきの通りに、

(cadr (1 2 3))

"(1" が命令の始まりと解釈されたからです。 つまり、"1" という手続きを実行しようとしたのです。 そんな手続きは存在しないためエラーとなりました。

前述のように、文字列が二重引用符 (") で囲まれるのと同じように、リストはカッコで囲まれて表現されます。 でも、カッコは命令の始まりでもあるのです。 さあ、困りました。 "(1 2 3)" は命令ではなくリストですよ、とSchemeに伝えなくてはなりません。

そこで登場するのが手続き quoteです。 手続き quoteは、『ここからここまでは命令とは解釈しないてください』とSchemeに伝えるための手続きです。

では、実際に手続き quoteを使ってみましょう。

11. '(cadr (quote (1 2 3)))'と打ち込む
11. '(cadr (quote (1 2 3)))'と打ち込む

上図のようにScript-Fu コンソールから、


(cadr (quote (1 2 3)))

 

と打ち込んでください。

12. Script-Fu コンソールの上部に 2 が表示される
12. Script-Fu コンソールの上部に 2 が表示される

上図のようにScript-Fu コンソールの上部に 2 と表示されます。 無事、期待通りの結果を得ることができました。

説明が長くなりましたが、手続き listを使わずにリストを作成する方法を解説することができました。 ここで一度整理すると、

(list 1 2 3)

という記述は、

(quote (1 2 3))

のように書き換えることができる、ということです。 意味は同じではありませんが、結果は同じになります

手続き quoteは省略して表記できる

手続き quoteは頻繁に利用される手続きです。 そのため、短く表記する方法も用意されています。 例えば、

(quote (1 2 3))

という記述は、

'(1 2 3)

と、省略して記述することができます。 つまり、

(list 1 2 3)

という記述は、

(quote (1 2 3))

と記述しても同じ結果となり、さらに、

'(1 2 3)

と省略して記述することもできます。 リストを作成するには、3通りの書き方があるということです

リストとは見えない紐でつながった箱のようなもの

前述の通り、リストと聞いて想像すべきは、入れ子になった箱です。 ですが、実際のリストの構造は『入れ子の箱のようなモノ』ではありません。

ここで、リストの本当の構造を説明しておきたいと思います。 リストの構造をより正確に表現するなら、『見えない紐でつながった箱』となるでしょうか。

- 最初のコンスセル -
car部 "太陽 昇"と書かれた紙が置かれている場所
cdr部 <2つ目のコンスセルの場所>
- 2つ目のコンスセル -
car部 "頂上 高志"と書かれた紙が置かれている場所
cdr部 <3つ目のコンスセルの場所>
- 3つ目のコンスセル -
car部 "未来 明子"と書かれた紙が置かれている場所
cdr部 <空っぽ>

最初のコンスセルのcar部には "太陽 昇" と書かれた紙が置かれている場所が書かれた紙が入っています。 もう一方のcdr部には2つ目のコンスセルの場所が書かれた紙が入っています。

2つ目のコンスセルのcar部には "頂上 高志" と書かれた紙が置かれている場所が書かれた紙が入っています。 もう一方のcdr部には3つ目のコンスセルの場所が書かれた紙が入っています。

3つ目のコンスセルのcar部には "未来 明子" と書かれた紙が置かれている場所が書かれた紙が入っています。 もう一方のcdr部には何も入っていません。

このようにコンスセルのcar部には、情報の場所を示す情報が入っています。 同じくcdr部には、次のコンスセルの場所を示す情報が入っています。 つまり、『見えない紐でつながった箱のようなもの』です。

  
情報処理技術者向けに言えば、コンスセルにはcar部・cdr部ともにアドレスが格納されています

上記のように、リストは見えない紐で数珠つなぎになっている情報の集まりです。 決して入れ子のコンスセル(箱)のような構造ではありません。

ただし、コンスセル(箱)の中に別のコンスセルが収まっている "入れ子" を想像したほうが理解しやすいと思います。 リストの操作が理解しやすくなるように、あえて、"入れ子のコンスセル" という正しくない表現をしています。

  

手続き consでリストの先頭に情報を追加する

リスト関連の最後の話題として、手続き consを紹介します。 手続き consは2つの引数を受け取り、それをcar部・cdr部に収めたコンスセルを作成するための手続きです。

なお、手続き consはコンスセルを作成するための手続きであり、リストを操作するための手続きではありません。 ありませんが、リストはコンスセルが見えない紐でつながっているようなものですので結果としてリストに影響を及ぼすことになります

難しい理屈は抜きにして、実際に手続き consを利用してみましょう。 スクリプトファイル myscript.scm を以下のように修正してください。

  1. (define (myscript)
  2. (let*
  3. (
  4. (outnumber 9)
  5. (innumber (cons 10 (list 20 30)))
  6. )

  7. (set! outnumber (myfunc-addnumber (car innumber) (cadr innumber)))

  8. (gimp-message (string-append "Number is " (number->string outnumber)))
  9. )
  10. )

  11. (define (myfunc-addnumber x y)
  12. (+ x y)
  13. )

  14. (script-fu-register
  15. "myscript" ; 登録する関数の名前
  16. "My Script" ; メニュー項目のラベル
  17. "自作の練習用スクリプトです" ; メニュー項目の説明
  18. "My Name" ; 作成者の名前
  19. "My Name" ; 著作権者の名前
  20. "January 1, 2023" ; 作成日(改訂日)
  21. "" ; メニュー項目を有効にするための条件
  22. )

  23. (script-fu-menu-register
  24. "myscript" ; 対象の関数の名前
  25. "<Image>/Filters" ; メニュー項目の位置
  26. )
 

修正箇所は5行目で、

(innumber  (list 20 30))

を、

(innumber  (cons 10 (list 20 30)))

と修正しています。

手続き consは2つの引数を受け取りますが、今回は、

10

と、

(list 20 30)

という2つの引数を受け取っています。 2つ目の引数はリストであり、入れ子のコンスセルで表現すると、

20
30
<空っぽ>

となります。 このように、手続き consはリストを引数として受け取ることもできます

手続き consは受け取った2つの引数の中身を収めたコンスセルを作成しますので、結果は、

10
20
30
<空っぽ>

となります。 つまり、最終的に、"Number is 30" というメッセージが表示されるはずです。

それでは、修正したスクリプトを実行してみましょう。

1. ウィンドウ下部に "Number is 30" と表示される
1. ウィンドウ下部に "Number is 30" と表示される

上図のようにウィンドウ下部に "Number is 30" と表示されます。 予想通りの結果です。 このように、手続き consを利用することでリストの先頭に情報を追加することができます

リストとリストを結合するには

手続き consはリストの先頭に情報を追加するのに適しています。 では、リストとリストを連結させるにはどうすればいいのでしょうか。

リストとリストを結合するには、

(innumber  (append (list 1 2) (list 20 30)))

のように手続き appendを使います。 上記のスクリプトの結果を、入れ子のコンスセルで表現すると、

1
2
20
30
<空っぽ>

となります。

次の記事へ

長くなってきましたので、ここで一区切りします。 続きは次の記事を参照ください

  

まとめ

プログラミング言語Schemeの最大の特徴がリストです。 リストについての知識がなければScript-Fuスクリプトを制作するのは困難です。

リストとは、見えない紐でつながった複数の箱のようなものです。 それぞれの箱はコンスセルと呼ばれ、情報を指し示すcar部と次のコンスセルを指し示すcdr部から構成されます。

新たにリストを作成するには、手続き listを使います。 なお、手続き quoteを使うこともできますし、省略して '(1 2 3) のように記述することもできます。

手続き 説明
list リストを作成する
quote 内部の記述が命令ではないことを示す
※リストそのものをスクリプト中に記述できる

リストの先頭に情報を追加するには、手続き consを使います。 また、リストとリストを結合するには手続き appendを使います。

手続き 説明
cons 受け取った2つの引数からコンスセルを作成する
※リストの先頭に情報を追加するのに便利
append 受け取った2つのリストを結合する

リストの先頭のコンスセルのcar部を取り出すには手続き carを使います。 同様に、先頭のコンスセルのcdr部を取り出すには手続き cdrを使います。

手続き cadrもあり、これは2番目のコンスセルのcar部を取り出します。 手続き caddrでは3番目のコンスセルのcar部が、手続き cadddrでは4番目のコンスセルのcar部が取り出されます。

手続き 説明
car
(カー)
リストの先頭のコンスセルのcar部を取り出す
cdr
(クダー)
リストの先頭のコンスセルのcdr部を取り出す
cadr
(カダー)
リストの2番目のコンスセルのcar部を取り出す
caddr
(カダダー)
リストの3番目のコンスセルのcar部を取り出す
cadddr
(カダダダー)
リストの4番目のコンスセルのcar部を取り出す
メニュー