SICPラン④(p31~1.2 手続きとそれが生成するプロセス)

これまでは、プログラミングの組み立て方を学んできた。算術演算子を用いた単純な手続きを組み合わせ、ときに特殊形式のifを用いて複雑な手続きを組み立てた。(例えば、ある整数の平方根を求める手続き)

ここからは、それらの手続きをどのようにして用いればより効果が得られるかを学ぶ。いわば定石の習得に入る。

 

1.2.1 線形反復と反復

n! = n・(n-1)・(n-2)・・・3・2・1

階乗を計算する方法は二つ

①n・(n-1)!
 1×2 の答えに、数字をかけていく。そしてnまでカウントアップしていく、

という方法がある。

①に関しては、掛け算の連鎖により式が展開されその後縮約されていく。これを再帰(recursive process)プロセスと呼び、次に、インタプリタは計算のため計算プロセスを保持しておく必要がある。つまり展開する式の長さと計算に必要なステップ数はnに比例していることがわかる。ここまで含めて線形再帰プロセス(linear reucrisve process)と呼ばれる。

②の方法は、①と違って展開式が伸びることはない。なぜなら積に対してカウンターとなる数をかけ、カウンターがnになった時点でそれが階乗の答えとなる。このように展開式は伸びないが、ステップ数は①と同様にnに比例する。これを線形反復プロセス(linear iterative process)と呼ぶ。

練習問題 1.9
>|scheme|

(define (+ a b))
(if (= a 0) b (inc (+ (dec a) b)))

||<
上記の式の場合、式は再帰プロセスとなる。
しかし、以下の式においては

>|scheme|

(define (+ a b))
(if (= a 0) b (+ (dec a) (inc c)))

||<
ifの条件式以下で式が展開し、それは反復プロセスとなる。

SICPラン③(p26~1.18. 例: ブラックボックス抽象化としての手続き)

 作られた手続きは、中身が詳細に知られる必要がない。簡単な例だとニュートン法で用いたsquareで、返り値として引数の二乗がかえってこれば良いのであって、どのように実装されているのかは知る必要がない。ブラックボックスで構わないのである。

そして、一連の手続きのネストを作ると、その他の手続きにおいても同じ名前で使うことができる。(つまりある数の平方根を求める手続き以外でも、improveやgood-enough?などが利用できるようになる。sqrt以外の手続き、いわゆるサブ手続きをsqrt内に局所化することで実現する。これをブロック構造という*1。)

(define (sqrt x)
  (define (good-enough? guess x)
    (< (abs (- (square guess) x)) 0.001))
  (define (improve guess x) (average guess (/ x guess)))
  (define (sqrt-iter guess x)
    (if (good-enough? guess x)
        guess
        (sqrt-iter (improve guess x) x)))
  (sqrt-iter 1.0 x))

そしてさらにsqrt内で変数xを自由変数として扱うと、そのスコープ内における各手続きに明示的に値を渡す必要がなくなる。

(define (sqrt x)
  (define (good-enough? guess)
    (< (abs (- (square guess) x)) 0.001))
  (define (improve guess) (average guess (/ x guess)))
  (define (sqrt-iter guess)
    (if (good-enough? guess)
        guess
        (sqrt-iter (improve guess))))
  (sqrt-iter 1.0))

xの値の探索は、その手続きが定義されている手続きの環境内で探索される。その範囲をレキシカルスコーピング(lexical scoping)という。(第三章で詳しく扱う)
 

*1:ちなみに、ブロック構造はAlgol 60という数値計算用の構造化言語から生まれた概念であるらしい。1958年にIFIP(International Federation for Infomation Processing)がAlgolを開発し、1960年にAlgol 60の仕様が策定された。実用というよりも、論文などにおいてのロジック記述に多用されているようである

SICPラン②(p22~ 1.1.7. 例: ニュートン法による平方根)

今まで出てきた「手続き」というのは、数学の関数によく似ている。しかしそれらには決定的に異なることがある。「手続き」では物事をどのようにして行うのかについて述べており、関数では物事の性質を述べているという違いである。(命令的知識と宣言的知識というらしい)
例として、平方根の関数の定義は
 \sqrt{x}=y\geq0 かつ  y^2 = x であるような  y
とされている。これは、平方根の性質を述べているだけでじゃあ具体的にどのように導出するのか、ということを「手続き」という。
そこで、ニュートン法による近似値導出をおこなう。これが手続き。

(define (square x)
  (* x x))
(define (sqrt-iter guess x)
  (if(godd-enough? guess x)
     guess
     (sqrt-iter (improve guess x) x)))
(define (improve guess x)
  (average guess (/ x guess)))
(define (average x y)
  (/ (+ x y) 2))
(define (godd-enough? guess x)
  (< (abs (-(square guess) x))0.001))
(define (sqrt x)
  (sqrt-iter 1.0 x))

Ex 1.6: ifを特殊形式ではなく、condを使って新たにnew-ifを定義した場合の挙動の説明

(define (square x)
  (* x x))
(define (new-if predicate then-clause else-clause)
	(cond (predicate then-clause)
		  (else else-clause)))
(define (sqrt-iter guess x)
  (new-if(godd-enough? guess x)
     guess
     (sqrt-iter (improve guess x) x)))
(define (improve guess x)
  (average guess (/ x guess)))
(define (average x y)
  (/ (+ x y) 2))
(define (godd-enough? guess x)
  (< (abs (-(square guess) x))0.001))
(define (sqrt x)
  (sqrt-iter 1.0 x))

この時、処理が終わらない。特殊形式としてのifは、述語式が真のときに一つ目の引数を評価し、偽の場合にのみ二つ目の引数を評価する。しかし手続きとして定義されたnew-ifはすべての引数を最初に評価するので、sqrt-iterが評価され無限ループになる。

SICPラン①(p20~)

SICPを読む過程で解いた問題の解答や、理解したことなどを書く。なお私はCSの学位などとは全く無縁であるので、参考になるものはなく間違っていることが多いと思う。

Exercise 1.3:三つの数値のうち大きい二つを選び、それらの二乗和をかえす(三つは任意の異なる整数)

(define (square x) (* x x))
(define (sum x y z)
  (cond ((and (> x y ) (> y z )) (+ (square x) (square y)))
        ((and (> x y ) (> z y )) (+ (square x) (square z)))
        ((and (> y x ) (> x z )) (+ (square y) (square x)))
        ((and (> y x ) (> z x )) (+ (square y) (square z)))
        ((and (> z x ) (> x y )) (+ (square z) (square x)))
        ((and (> z x ) (> y x )) (+ (square z) (square y)))))

Exercise 1.4:以下の手続きの挙動の説明

(define ( a-plus-abs-b a b )
  (( if ( > b 0 ) + - ) a b ))

という式の挙動は、a-plus-abs-bという手続きを定義している。そしてその手続きは、bの正負を判断し、正の場合は+、負の場合は-というオペレータを返す。最後に、そのオペレータはaとbのオペレータとなっている。オペレータの部分が複合式(今回だとifの条件式の部分を指す)でも、問題なく評価は行われる。ifのconsequent部分をb - に置き換えるとnot a procedureというエラーが出る。

Exercise 1.5:以下の手続きについて、適用順序評価と正規順序評価による違いの説明

(define (p) (p))
(define (test x y)
  (if (= x 0 ) 0 y ))
<||
Applicative-Order Evaluation(AOE)だと、引数を評価してから手続きを適用するので、上記の式だとpはpのまま際限なく評価され続ける。一方Normal-Order Evaluation(NOE)だと、基本演算子のみの式になるまで簡約するので条件式が適用されるので、無限に評価されることは生じない。

コトバンクにおける不可解な記載

ほんの興味から「イオン(ion)」の語源について調べていた。全く科学系の事柄に関しては昏いのであるが、今回少し調べてみたので備忘録的に記す。

結論から言うと、イオン(ion)はギリシャ語の「行く(ienai)」をもとに、ファラデー(Michael Faraday, 1791-1867)が、電気分解の際に移動する物質に対して名付けたものである*1

その際に陽イオンを「下がる」を意味するcation、陰イオンを「上がる」を意味するanionと名付けた。(ここのあたりで、なぜ陽イオンを「上がる」、陰イオンを「下がる」としたのかは調べられていない。)

ここで、コトバンクにおいて不可解な説明がなされていた。ファラデーの電気分解の実験には同じように触れているのだが、陽極と陰極にひきつけられる物質を、「行く」ものとしてイオンと名付けたとしている。そこで、陽極(anode)に引き寄せられるものを陰イオン、つまりanionと名づけ、陰極(cathode)に引き寄せられるものを陽イオン、つまりcationと名付けたとしている。しかし、これは関係が逆ではないのか。なぜ陽極をanodeと名付けたのか。『気ままに有機化学』のようにその振る舞いから名付けられた後に陽極、陰極ともに名付けられたのではないのか。

 

*1:”化学用語の起源(1)『気ままに有機化学』HP”。

コンラッド『闇の奥』、サン=テグジュペリ『夜間飛行』を読んだ。

コンラッドに関しては、映画『地獄の黙示録』でベトナムに舞台をうつしてリメイクされている。初めは、植民地主義に対する批判的姿勢をとるものだと思ったが(実際その読みは正しいのだろうけど、物語の主張したいこととは異なる気がする)、私の感想で言えば、アフリカというフィールド(コンラッドの実体験に基づくものであり、その時代におけるアフリカに対する認識を念頭において)を考えるとそれは、人間の原初的な恐怖を味わったひとの語る物語である。当時の未知というと、それは現代とは比べられないほど知られていないものであり、全くの異世界であった。その中において、自身と同じ世界に属し同じ原理で動いていたはずのクルツ氏が、未知の世界で大いなる影響力をふるっているという事態に遭遇する。その真実の姿に近づくまでの恐怖、知りたいけれども、知ってしまったが最後、自分自身はどのようになるのだろうか。未知のものに触れた自分は、これまで属してきた世界を離れ、クルツ氏のようになってしまうのか。自身の存在が揺るがされてしまうような現実に触れるまでの船乗りマーロウの心情の吐露は半ば自嘲気味に茶化す様子も感じられる。それは、未知のものに触れて自身の存在がゆるがせにされたものの、何とか生きている自分、しかし確実に未知の世界に触れる前の時分とはちがう自分を意識している。そのギャップから生ずる安堵感、違和感が彼の語り口に浪漫的な冒険話の趣を与え、自分で体験することでしか把握できないという彼の言明のとおり、語られることと自分の語り口から生ずる違和感も感じていた。

サン=テグジュペリ『夜間飛行』

飛行機を飛ばす使命を帯びたリヴィエール氏とそこで働くファビアン。リヴィエール氏が作り出す仕事の世界。そこは非人道的なものであり一切の人情の介入を許さない。仕事というと何か陳腐なものに思えるかもしれないが、命を失う危険をはらむ仕事である。しかしどうしてか非常に美しい。それはファビアンが墜落直前に雲海の上に飛び出し、満点の星空が頭上をゆったりと瞬くのを眺めそれに心奪われるシーンを見れば一目瞭然であろう。それは宮崎駿の『紅の豚』の飛行機の墓場、『風立ちぬ』の最後の煉獄のシーンを思い起こさせる。非情な夢の残骸は、美しさを放ち心をとらえた。ファビアンは夢の残骸の予兆を感じたのだろうか。死の瀬戸際で、ほぼ死に傾いているときにその美しさはいやがうえにも増すのだろうか。

『闇の奥』ではクルツ氏に対するマーロウの思いを、『夜間飛行』ではファビアンの雲海に出るまでの心理描写の機微、そして彼の妻がリヴィエール氏に与えた影響を、次にもうちょっと考えて読む。

ジョージ・オーウェル『動物農場』山形浩生訳 早川書房

1945年に初版が出版されたもので、原題はAnimal Farm: A Fairy Taleである。邦訳自体はたくさんあるので、様々な訳者のものでも楽しめると思われる。(以下のリンクがフリーのもの)

blog.livedoor.jp

本書のあらすじ

人間の農家に虐げられてきた動物たちは、その貧しく搾取されている現状を打破するため力を合わせ立ち上がる。無事支配からの解放を得た動物たちは、勤労を旨として農場を「動物農場」と改名する。そのうち知力の優れたブタが指導者となって「動物農場」の指導に当たることになるが、次第に権力を握ったブタは...

というものであり、本書の帯に掲げられた「あらゆる権力は腐敗する。それは歴史の必然なのか。」というコピーは、端的に本書を表しているといえる。

この本が、1917年のロシア革命とレーニン率いるボリシェビキ党によるソ連邦の成立、その後のスターリントロツキーによる権力闘争とスターリンの粛清政治をなぞらえているという解釈は多くの同意を得られるだろうし、オーウェルも序文案で述べている。

 

では、ここでオーウェルが述べたかったのは、ソ連型の社会主義の顛末を皮肉に風刺して見せることで自身の社会主義理念を正当化することだったのか。この時期、つまり第二次世界大戦が終わりを迎えた頃のソ連の位置づけを見ると少し見通しがよくなるかもしれない。

詳しくは不勉強なので申し上げられないが、ソ連第二次世界大戦における役割の大きさは、確かなものであった。それゆえ、ソ連が進める社会主義体制への批判は、ソ連の行うプロパガンダと相まってほとんどなかった。そのような状況のなか、オーウェルは本書を書きあげる。しかし世間はというと上記のような状況で、あからさまにソ連を批判する本を出版する出版社はなかなか現れなかった。また、当時のイギリスの新聞の様子や知識人の「ソ連の無批判の称賛(本書160頁)」は、言論の自主的な検閲を意味した。つまり体制への批判的な投書の秘匿や出版の差し止め、拒否を行ったのである。このような振る舞いは、言論の自由の自主的な放棄であり、オーウェルのいう「資本主義の民主主義も西欧版社会主義も」その擁護者たる地位を捨て去ったのである。この先に待つべきものは何か。それは本書で描かれていたように、権力の極端な肥大化である。ブタのいう事になにか疑問を抱いても考えることをせず、もしくは見て見ぬふりをするという姿勢は、ソ連への批判をやめたイギリスの姿をなぞらえることができるのである。止まることなく思考を続けよ。知識人が自由を擁護せずに、その臆病さから保身のため自由を手放す姿勢をオーウェルは批判しているのであった。

 

ここで疑問に思ったことをつらつらと書く。

①人類の大きな原則とされる「自由」を守るために、個人はどこまで自己を犠牲にすべきなのか。保身のために利己的な行動をとっても仕方ないのではないか。将来において自身に降りかかる不利益を考慮すれば、自由を放棄する行動は制限されるだろうという主張は、それこそ主観的なものであるので、そんなものは知ったこっちゃない、と言われるのではないか。

②「知る」「考える」ことに限界があるのではないか。つまり現代においては過剰なほどに情報があふれかえっている。情報の入手が容易になったおかげで、我々はそれらの情報を吟味する時間が無くなっているのではないか。丸山眞男のいうところの「知識の断片化」である。このような状況になると、思考し続けることは果たして正しいのであろうか。思考の強度が低下した中で下される判断の正当性は問われるべきではないのか。

③西欧型の表現の自由が、他国で、特にアジアで引き起こす問題はどのように捉えられるか。(これは次の記事で考えたい。)

 

考えれば考えるほど歩むスピードは遅くなってしまうが、何を恐れることがあるだろうか。