LISP
List Processor
Lisp(リスプ)はList Processorの略で、リスト処理に強いプログラミング言語です。Lispはマサチューセッツ工科大学(MIT)
の John McCarthy(なんて読むの?)によって1957年に作られたプログラミング言語です。最初のコンピュータ(といわれている)ENIACが完成したのが1946年ですから、かなり初期からあった言語です。しかし、Lispは現在のコンピュータではあまり使われていません。というか、Lispで動いているプログラムはEmacs以外に知らないんですが…??ほかにLispでこんなプログラムが動いているぞという人は、教えてください…。
<参考文献>自分のレポート
Lispを動かすのに必要なもの
Lispを動かすためには、Lispインタープリタが必要です。インタープリタには、以下のようなものがあるらしいです。
他には、ここ(http://jp.franz.com/jlug/ja/resources/implementations.html)を見るとたくさん乗っています。
- gcl (GNU Common Lisp)
- Emacs
- Scheme
gclは、授業でも使っているインタープリタです。gclはUNIX系のOSで動くらしいのですが、自分はこのWindows版を発見しまして、それを使っています(http://www.cs.utexas.edu/users/novak/gclwin.html)。たった3.4MBytesなので、皆さん使ってみることをオススメします。
他にも処理系はいろいろあるようですが、使ったことがありません^^。Lispは処理系によってかなり動作の仕方が違うようです。gclは「Common」と自ら言っていますので、まあメジャーなんだな〜ということで、使っています。
手始めに、電卓代わりに使ってみる
Lispは記号処理用のプログラミング言語ですが、数値演算を行うこともできます。まず、gclを起動してみましょう。すると、以下のような画面が出てきます。

この">"の部分に命令(式)を打ち込みます。打ち終わったら、Enterキーを押すことによって、その式が評価され、なにかが起こります。
では、早速計算をしてみたいと思います。
123+456
をやってみましょう。Lispでは、このとき、
>(+ 123 456)
と打ち込みます(">"は打たないでね。)そうすると、こうなります。

はい、ちゃんと"579"と答えが出ましたね。
■他にもいろいろ試して見ましょう
>(+)
0
引数を指定せずに(+)とだけ打つと、0が返ってきます。
>(- 1 2 3)
-4
関数(-)に3つ以上の引数を与えた場合は、2つ目以降の数値の絶対値が反転します。つまり、最初の値から次の値(次のリスト)の値を順次引いていくことになるようです。
>(- 1)
-1
ただし、値をひとつしかとらない関数(-)の値は、その逆の絶対値を返します。
>(-)
Error: - [or a callee] requires more than zero arguments.
Fast links are on: do (si::use-fast-links nil) for debugging
Error signalled by -.
Broken at -. Type :H for Help.
また、関数(+)は単独でも、何も足していないという意味で0を返すが、関数(-)は必ずひとつ値を与えてやらねばならないようです。
>>:q
Top level.
>
エラーになった場合、プロンプト表示が">>"になります。これを元に戻すためには、
:q
というコマンドを使うようです。
■関数 /(除算)
に割り切れない数を与えるとどうなるか?
>(/ 1 3)
1/3
>(/ 6 12)
1/2
Lispで除算関数 /
を使用して、割り切れない値を計算させると、驚いたことに結果は分数表示として出力されます。しかも、6/12のように、約分可能な計算を行うと、約分も行ってくれます。ただし、計算する値にひとつでも小数点数を与えると、結果は小数点として出力されるようです。Lispの数値計算については、特殊な処理を行っていることがわかりました。
ちょっとしたプログラムを書いてみる
せっかくですので、少しプログラミングらしいことをして見ましょう!!!
Lispは、Cなどのように、自分で関数を作ることができます。というわけで、ここでは、nの階乗(n!)を返すような関数を自作してみたいと思います。
まず、関数定義defunを使って、階乗の関数factを作ってみます。えと、そもそも階乗の定義は何でしたっけ??階乗とはある数nから1まで、1ずつ引いた数をすべて掛け合わせたものです。階乗の定義を、再帰的に考えると、以下のようになります。

つまり、関数factは、nが0のときは、1を返します。nが0でないときは、n×fact(n-1)を返すということです。関数factのなかで関数factを使う。これは、ちょっと裏技的な風にも見えますが、これは立派な「再起呼び出し」という使い方です。
さてさて、このことをLisp語で書くとこうなります。
(defun
fact (n)
(if (zerop n)
1
(* n (fact(- n 1))))
)
引数がゼロかどうかを判断する述語は zerop
です。条件判断の if などはC言語と使い方は似ていますね。ただし、Lispではやたらとカッコが多くなります!!
なので、このように適度に改行して、見やすくしましょう!!
これを、lisp.l
などとしたテキストファイルで保存します。その後、gclで以下のように呼び出します。
>(load
"lisp.l")
すると、関数factが使えるようになっています。ためしに、いろいろな値を打ち込んで見ましょう。
>(fact 0)
1
>(fact 1)
1
>(fact 5)
120
>(fact 7)
5040
>(fact 120)
66895029134491270575881180540903725867527463331380298102956713523016335572449629
89366874165271984981308157637893214090552534408589408121859898481114389650005964
960521256960000000000000000000000000000
はい、ちゃんと階乗の値が返ってきました。(120!の解ですが…これは、なんと読めばいいのでしょう???)
皆さんご存知の通り、n!は少しでもnが大きくなると値が莫大に大きくなります。あまり調子に乗って、nに大きな数を与えないようにしてください。nに1050なんて値を入れた日には…恐ろしいことになります。
リスト構造を操作してみる
準備中です。
|