ここでは厳密な話は抜きにして雰囲気でLispを説明します。
・リテラル
123 "Lisp"
Lispでは、ほかの言語同様、数値や文字列を扱えます。
・シンボル
car abc null?
Lispでは、英数字、記号の列はシンボルと呼ばれます。シンボルは変数名、関数名になりますが、Lispでは名前そのものもデータとして扱えます。また、同じつづりのシンボルは完全に同じものを表します。
・リスト、S式
(a b c) (list a 1 2)
「(」で始まり、シンボルやリテラルが並び「)」で終わるものをリストと呼びます。
(car (quote (a b c))) (+ (* a b) (* c d))
リストの中にはシンボルやリテラル以外にリスト自身も書くことができます。リストはS式(Symbolic expression)とも呼ばれ、Lispの重要なデータ構造です。Lispという名前は実はList Processorの略語です。S式については後でもう少し詳しく説明します。
・関数
(multiply (add 1 2) 5)
LispではプログラムもS式で表します。リストの最初の要素を関数名、以降の要素を実引数として扱います。上のS式はC言語などで書くと、
multiply(add(1,2),5)
となります。
関数の定義も関数で行います。下はnという引数を取るfactという関数をdefineという関数で定義しています。
(define (fact n) (if (= n 0) 1 (* (fact (- n 1)) n))))
ただし、上のように1行で書くとプログラムの意味が分からないので、下のようにインデントして書きます。インデントや閉じカッコは面倒だと思うかもしれませんがEmacsなどのエディタが面倒を見てくれるので、実際にプログラムを書く際にはあまり気になりません。
(define (fact n) (if (= n 0) 1 (* (fact (- n 1)) n))))
このfact関数の定義をC言語で書くと以下のようになります。
int fact(int n) { if (n == 0) return 1; else return n * fact(n - 1); }
S式はLispのプログラムを書く以外に、いろいろなデータを扱うために使えます。例えば、以下のようなHTMLは、
<html> <head> <title>Lisp Web</title> </head> <body> <h1>Lisp Web Page</h1> <table> <tr><td>1</td><td>Lisp1.5</td></tr> <tr><td>2</td><td>Scheme</td></tr> <tr><td>3</td><td>Common Lisp</td></tr> </table> </body> </html>
このようなS式で表現できます。
(html (head (title "Lisp Web")) (body (h1 "Lisp Web Page") (table (tr (td 1)(td "Lisp1.5")) (tr (td 2)(td "Scheme")) (tr (td 3)(td "Common Lisp"))))))
S式はリスト(何かが並んだもの)の中にリストが書けますので、いろいろなデータをS式で表すことができます。
S式はコンピュータ上でどのように実装されているのでしょうか。
Lispのメモリ空間には、セルと呼ばれるポインタが2つ入る箱がたくさん用意されています。歴史的理由で左の箱をcar(カーと読むようです)、右の箱をcdr(クダーと読むようです)と呼びます。
carやcdrには、ほかのセルへのポインタのほか、シンボルやリテラルへのポインタが入ります。また、終わりを表すnilという特別なシンボルがあります。
S式の表現の基本は「(car . cdr)」ですので、図2の一番上の例は「(a . (b . nil))」となります。3番目の例は「(a . (b . (c . nil)))」となりますが、このような単純な並びが多いので、nilで終わるS式は「(a b), (a b c)」のように表現します。
リスト構造に不慣れな方は、このような絵を書きながらLisp関数の処理を追って行くと理解しやすいと思います。私が初めてLispに触れたときにも、このような絵を何度も何度も紙に書ながら理解していきました(笑)。
Copyright © ITmedia, Inc. All Rights Reserved.