さて、第三章の趣旨は、
"Chapter 3 provides an overview of the Lisp primitives. It can be skimmed on first reading and used as a reference whenever an unfamiliar function is mentioned in the text."
とのこと。なのでリラックスしていく。ただ、CL入門とANSI-CLの復習の意味もこめて写経はしっかりやる。
- 3.1 A Guide to Lisp Style
- lispでは同じ関数であっても多様な書きぶりが可能である。
- どれを選ぶべきかについて、6つの指針がある。それの説明。
- 指針が衝突した場合の判断について。
- 3.2 Special Forms
- andやorを条件分岐で多様するのはBad styleであると。するとPGのANSI-CLはBad style連発だったな。。。ひとそれぞれ?
- Norvigも拡張loop否定派っぽい。
- listをみるのに二つの視点あり。first and restとsequence。この本では後者をよく使う。なぜかというと、first and restでとらえると、listがconsでできているというlispの言語仕様にひっぱられすぎることがおおいから。最後の要素について何かしたいときとかは、sequenceととらえていた方が直接的である。
- progn利用規制を明示。厳しいな。。。
- 「As C.A.R. Hoare put it, "One thing the language designer should not do is to include untried ideas of his own"」これがMacro心構えだよと。なるほど。
- 3.3 Functions on Lists
- 3.4 Equality and Internal Representation
- 3.5 Functions on Sequence
- この3つ、新しい知見は特になし。
- 3.6 Functions for Maintaining Tables
- 属性リストはあまり使わない。hash tableを使うのが主流。理由は、
- 属性リストは常にglobal。二つのプログラムを同時に利用したりすると衝突の回避がやっかい。
- clrhashに対応する機能が無いなど、管理用の機能が整備されていない。
- 属性リストは常にglobal。二つのプログラムを同時に利用したりすると衝突の回避がやっかい。
- 3.7 Functions on Trees
- 3.8 Functions on Numbers
- この2つ、新しい知見はなし。
- 3.9 Functions on Sets
- CLにおけるbit-vector。これは初めて見たかな。PCLで見ていたが、わすれている、という可能性もある。
- 3.10 Destructive Functions
- そうか、Lisp以外の言語では、副作用をもたらすものをfunctionではなくprocedureと呼んでいるのか。それはそれで合理的。
- 3.11 Overview of Data Types
- 3.12 Input/Output
- この2つ、新しい知見はなし。
- 3.13 Debugging Tools
- "..., but it also offers a third: (3) add annotations that are not part of the program but have the effect of automatically altering the running program." これが何を指しているのかが今ひとつわからない。
- 3.14 Antibugging Tools
- バグ警報のためにコーディング作業をあらかじめ費すのは、それなしでデバグ作業する羽目になるより安くつくよ。
- 複雑なデータ構造を扱うときは、一貫性チェッカをつくっとくべし。
- めんどくさいテストケースについては、何時でも実施できるよう手元においておくべし。(regression testing)
- それは複雑なもんじゃなくてもよくて、assertをdefunでまとめておくだけでも十分。
- 3.15 Evaluation
- ああ、そうなのか、funcall,applyとevalというのは「評価する」という意味では同種なのか。REPLな観点からevalを特別視していたけれども、プログラマの観点で、コードの中で評価対象を作成してそれを評価するための機構としては、これらは同列にとらえられるものなのだ。
- そして、コードの中の評価対象って何だっけ? というと、まあ「関数」と「引数」だ。なので、funcall,applyはそれらを引数にできる、と。
- そしてその引数たる「関数」をコード中で作れますよ、というのがlambdaでありclosureということだ。
- なので、昔のLispでは、コードの動的取り扱いにevalを多用していたが、今はfuncall,applyとlambdaを使う、と。
- 大したことではないが、視点がすっきり整理できた。
- 3.16 Closure
- free lexical variablesを補足するのがclosure、という説明だけ。
- とてもコンパクトに説明していてよいのだが、closureがわからない人が、これでわかるようになるのは無理だろう。
- 3.17 Special Variables
- うぉ。この節、コンパクトにlexical variablesとspecial variableの要点を説明している。
- これはこれですっきり。
- でも触れてないことも多いし、この説明だけでわからない人が理解するのは無理。
- わかっている人のためのものだろう。
- Norvigの説明を自分なりにアレンジしつつまとめる。
- CLはデフォルトはlexical variables。
- lexical variablesのスコープは、レキシカル。すなわちコードで範囲を抜けると、そのvariablesに名前でアクセスすることはできない。ここまでは他の言語と一緒。
- ただし、CLのlexical variablesはclosureに捕捉され得るので、捕捉されている場合は、プログラムの実行がスコープを抜けた後も、存在することはできる。もちろんスコープは抜けているので名前ではアクセスはできない。しかし存在しているので、closureがそれを操作する機能をもっていれば、closureが無くなるまでそれは存在し操作できる。これがエクステント。closureが存在しない言語では、スコープとエクステントはlexical variablesにおいても同じとなる。ここが他の言語と違うところ。
- special variablesのスコープはグローバルである。なので、プログラム中のどこからでも参照できる。ここまでは他の言語のglobal variablesと一緒。
- ただし、CLのspecial variablesは、letなどによって局所的に動的にshadowingできる。なので、special variablesのスコープは、グローバルだがlocal (dynamic) shadowing付きであるといえる。ここが他の言語と違うところ。
- そしてこのshadowingのextentはスコープと同じである。コードのゾーンを抜ければ、shadowingは無効になる。それゆえspecial variablesのextentは動的(dynamic)であるという。
- まとめると
lexical variables : scope = lexical, extent = indefinite (as closure)
special variables : scope = global , extent = dynamic (as shadowing)
- CLはデフォルトはlexical variables。
- 3.18 Multiple Values
- 複数の値を返したいときってあるよね。-> Listとかstructureで返せばいいよね。->でも、そうするとそれらの構造を定義したり、それらを関数の中で生成しなきゃいけないよね。-> I'm lisper. めんどくさいのはイヤ。-> 多値発祥。
なるほど。。。 - 3.19 More about Parameters
- &optional, &keyなど自身のことをlambda-list keywordsと呼ぶよ。
- complement、便利だな。
- 3.20 The Rest of Lisp
- ま、基本は自分でやるべしだよ、この本はAIの本だし、という感じ。
うむ。とりえあず、最初の100ページはクリアした。
PART II Early AI PROGRAMS に進もう。
0 件のコメント:
コメントを投稿