Common Lisp: A Gentle Introduction to Symbolic Computation

1. はじめに

Common Lisp: A Gentle Introduction to Symbolic Computation はデイヴィッド・トウレツキが作成した Common Lisp の入門書です。プログラミングの入門書として書かれたので、ゆっくりと関数や変数などの概念を教えてくれます。第3章から各章の中では読者が解く問題があり、章の最後に大きな問題が一つあります。その章は学んだ概念をまとめて使う問題です。

最初からとてもゆっくり進んで、Lisp でプログラミングの基礎をコードなしで教えます。

プログラミング環境とかエディターなどの情報を教えず、生徒たちに必要なリーソースをあげることを講師に任せます。はじめにコードがなく、プログラミング環境の情報がないので、始まりはゆっくりすぎ、1人で勉強する人には情報不足する感じがします。もしこの本で1人で Common Lisp を勉強したいと思えば、まず Emacs を学んだ方がいいです。最初の76ページはコードや本格的な問題がないので、早く進んで、もし何機わからなかったら振り返った方をお勧めします。

以上の弱点があっても、トウレツキさんの本を読んでも利があるのでしょうか?

もしプログラミングにも Emacs にも初心者だとしたら、ないと思います。Emacs を学ぶことだでも大きな壁になります。この本がとても良くても、初めが難しすぎて進めなくなる可能性が高いです。覚悟しても、Common Lisp の勉強には、まず Emacs の勉強から始めないといけないと強く推進します。Doom や Spacemacs のような Emacs のディストロをダウンロードし、チュートリアルの動画から使い方を学び、Emacs を自信よく使えるようになってから Common Lisp を勉強してください。

Emacs を知っていたら、トウレツキさんの本で Common Lisp を勉強した方がいいのか?

はい!

フールスタックのウェブプログラマーとしては、Javascript と Python を使っています。ウェブのプログラミングが好きなんだけど、フレームワークを使いすぎ、ういをつくりすぎてそういうスペシャリストになりそうで、基礎な知恵や経験が不足になっているかなと思います。ただただこういう仕事をしてお金を稼ぐことにしか興味がないわけじゃなく、プログラミング自体が好きで上手になんでもできるようになりたいです。

その基礎の知恵を身につけるために、Common Lisp を学ぶことにしました。なぜなら、Haskell や Ocaml のような関数プログラミング言語だと思い込んでいました。しかし、本を読んでいた間に、一般プログラミング言語だとわかってきました。Common Lisp では、なんのプログラミングのパラダイムを使うかプログラマー次第です。だったら、Common Lisp を学んでも新しい概念や知恵を身につけるのかなと少し心配したが、トウレツキさんの本を読んだら誤解しませんでした。

じゃあ、ウェブプログラマーとして、何を覚えたでしょうか?

2. マッピとフィルターと再帰

マッピとフィルターとサイキのような関数プログラミングの技術を学ぶことは僕の目的の中の一つでした。再帰は関数プログラミングだけで使うわけじゃないけど、JS や Python と比べると、関数プログラミング言語の中の方で割と使っている気がします。JS でも Python でもマップとフィルターを使えるけど、特に Python ではあまり Python っぽくないので使わない方がいいよと良く言われます。そして、JS は命令形プログラミングに適応なので、ちゃんとマップとフィルターの使い方を勉強するために Common Lisp を選びました。

トウレツキさんにがっかりさせられませんでした。 DODOLISTDOTIMES の反復演算子は第10章まで出てきません。その代わり、データセットを扱う最初に教えてくれる技術は「applicative programming」、つまりマップとフィルターの関数プログラミングの道具です。完璧です。関数プログラミングの章の最後の問題では簡単なリストを基づいたデータベースをクエリーするための原始の API を作ります。

次の章の中ではトウレツキさんが再帰を教えます。前にサスマンとアベルソンの Structures and Interpretations of Computer Programs で再帰を少し勉強したけど、僕の数学力が弱すぎて説明や問題を理解できなくて諦めました。なので、再帰は僕にまだわからないことが多かったです。

いいことに、トウレツキさんはゆっくりと優しく再帰の使い方と使用する場合を教えてくれます。僕は再帰のエクスパートだと言えないけど、再帰の章を読んだ後、少し自信ができました。

関数プログラミングと再帰を強調してくれるトウレツキさんの教え方に総体的にとても満足しました。

3. データ指向プログラミング 対 抽象

去年からジョナサン・ブロとケーシー・ムラトリとマイク・アクトンが教える「データ指向プログラミング」というパラダイムのパラダイムの影響を受けました。簡単に言えば、その3人はオブジェクト指向プログラミングでよく使っている抽象がいいソフトを作るにダメだと言います。なぜかといえば、その抽象はデータを現実に存在しているものにモデリングされるので、ソフトが遅くなり、信頼できなくなると言います。更に、重なっている抽象は分かりにくくなると言います。

Lisp はどんな抽象を作りたくてもできる柔軟性が特徴です。Lisp の基礎のデータ構造である連結リストは他のデータ構造と比べてら遅くて不効率(この本でも出てくるテーマ)だけど、プロトタイピングに優れています。プロジェクトの始まりに、最初に連結リストを使用し、もし最適化が必要であれば他のデータ構造にした方がいいとお勧めされます。

しかし、上手に抽象ができても、そうすべきというわけではありません。頭がいい抽象に頼るんじゃなく、Lisp で必要な時だけに抽象を作り、主にデータ構造を考えながらプログラミングができるでしょうか?

「できる」とは、この Gentle Introduction を読んだ僕の初歩的な判断です。

3.1. データ構造の例:チックタックトー

チックタックトーは Common Lisp を勉強するための古いからプロジェクトです。Youtube で Common Lisp でチックタックトーを作る動画を観ました。なんか難しいなと思ったけど、なんでそんなに難しそうなのかよく分かりませんでした。

偶然に変数を代入する章の最終プロジェクトはチックタックトーです。パソコンの AI プレーヤーでもあるトウレツキさんのチックタックトーを作る方法を覚えたら、簡単なデータ構造を使った方は現実で出てくるものにモデリングされたデータ構造を使うより、分かりやすく、作りやすくて質がいいコードができると、強く納得できました。

3.1.1. 複雑な方法

;; Using a 2D array
(defparameter *board*
  (make-array '(3 3) :initial-element '-))

;; Using nested lists
(defparameter *board*
  (list (list nil nil nil)
        (list nil nil nil)
        (list nil nil nil)))

この複雑な方法はゲームボードは現実のゲームボードを直接に2D 配列かネストしたリストで作られ、プレーヤーのアイコンは X か O のストリングになり、空スペースが NIL として代用されます。直接で当たり前のデータモデリングです。

3.1.2. トウレツキの方ほう

(defun make-board ()
  (list 'board 0 0 0 0 0 0 0 0 0))

トウレツキの方法ではゲームボードがフラットリストになり、プレーヤーのアイコンが1か10、空スペースが0として代表されます。このデータモデルは現実を直接に代表しなくて、ちゃんとデータ構造を考えないで作るわけないでしょう。

このデータ構造を使うことだけで、残りのコードに巨大な影響を与えます。リストは配列より扱いやすく、フラットリストは特に2D 配列より使いやすいです。ストリングでプレーヤーのアイコンと空スペースを代表したら、勝利条件をモデルするのが複雑になり、AI を作ろうとしたらさらに難しくなるだろう。もう一方、トウレツキの方法で簡単な数学で勝利条件と AI をモデルできます。数字のフラットリストのデータ構造にすることで、コードの複雑性を完全に変わります。

チックタックトーの問題はいいデータ構造を使ったらどうなることに特に勉強になったけど、簡単なデータ構造に関しての問題はいくつかあります。

総体的に、僕にはトウレツキさんが教えてくれるデータ構造のレッスンがすごく勉強になり、感動させてくれました。どうにかデータ指向プログラミングのムラトリと抽象マスターであるサスマンのプログラミングの哲学を組み合わせられる希望を残りました。

4. その他

トウレツキさんは大事なリスト処理の演算子、どうやってユーザーの入力を受けられるか、どうやってデータをプリントできるのか、構造体・配列・ハッシュテーブルの使い方とかの基礎の基礎も教えてくれます。最終章ではマクロの簡単な使い方を教えてくれます。

Lisp の中にあるけど教えていないこともあります。クラスやオブジェクト指向プログラミングする方法はその一つです。Common Lisp は CLOS があるけど、僕は関数プログラミングに興味があったので問題なかったです。 DEFCLASSDEFMETHOD は後で勉強してもいいです。

5. 最終の判断

Common Lisp: A Gentle Introduction to Symbolic Computation はとてもいい Common Lisp の入門書です。始まりが遅く、現在の県境の中で Emacs を学ばないといけないけど、トウレツキさんの本は Common Lisp の基礎とデータ構造とかの概念を上手に教えてくれました。Common Lisp だけじゃなく、どのプログラミング言語でも使えることをいっぱい教えてくれました。

Common Lisp に興味があって、トウレツキさんの本を読む価値があるか悩んでいたら、安心してください。ぜひ、お勧めします。

最終判断: 8/10

本を今でも買えるけど、こちれのサイトでも無料でダウンロードできます

Profile Photo

Author

Added

2024年8月21日

Technologies
common-lisp common-lisp
book-review book-review