見出し画像

Retro-gaming and so on

K&R C

伝説的な本がある。

 
1986年出版の本で出版社はアスキー。
角川傘下になって今や見る影もないが、往年のアスキーはキレッキレの出版社で、「イケてる技術書ならアスキー」ってカンジだったんだ。「C言語でLisp処理系を書こう」なんつー狂ったコンセプトの本を出す辺りでそれは分かるだろう(笑)。そんなモンを一体今どの出版社が出すと言うんだ(笑)。往年のアスキーは「マイナーだろうが尖ったブツなら出版する」とか言うマニアな会社だったんだよな(笑)。その辺が「マイナーな言語には見向きもしない」保守一辺倒のソフトバンクなんかと全然違ってて、「売れるかどうか分からんような本」をヘーキで出す攻撃的な出版社だったんだ。カッコよかった。
言わば髪が生えてるヤツとハゲの違いなんだ。
そう、かつてのアスキーは別に「ラノベの出版社」でも何でも無かったんだ。

さて、どうしてこの本が「伝説的な」本なのか。それは日本で一番使用率が高いLisp処理系、Gaucheの作者である「プログラミング界の王羲之」(と僕が勝手に呼んでいる・笑)、川井史朗さんが「初めてLispに触れて」「いきなり実装する」ように誘った本だから、なんだ。

(Lispに)出会ったのは大学時代でした。一番最初にハマったのが、C で書く Lisp の本がありまして、それを何気なく古本で買って、プログラムリストを打ち込んでいったら「これはおもしろいな」と。

つまり、この本が無ければGaucheは誕生しなかった、と言っていいだろう。川井史朗さんをLispへと誘った、と言う非常に重要な本ではあるんだ。
そう言う本をなんとか入手した。

ところで、この本で「紹介」されているLispコードの例はこんなんだ。



「え?」とか言うようなコードだ(笑)。「deって何やねん」と(笑)。
ちなみに、これはProlog形式のパターンマッチングを行う関数で、現代のLisp、例えばRacketなんかだと次のコードにあたる。

(define atom? (compose1 not pair?))

(define (match? x y)
 (cond ((atom? x) (eq? x y))
    ((atom? y) #f)
    ((or (eq? (car x) (car y)) (eq? (car x) '?))
     (match? (cdr x) (cdr y)))
    ((eq? (car x) '*)
    (or (match? (cdr x) (cdr y))
      (match? x (cdr y))))
    (else #f)))

記号(シンボル)?や*はワイルドカードで、?は単一で任意のシンボル、*は複数のシンボルと符合する。

> (match? 'わたし 'わたし)
#t
> (match? 'たわし 'わたし)
#f
> (match? '(私 は 猫) '(私 は 猫))
#t
> (match? '(私 は 猫) '(私 は 子猫))
#f
> (match? '(私 ? 猫 ?) '(私 は 猫 です))
#t
> (match? '(私 ? 猫 ?) '(私 だって 猫 よ))
#t
> (match? '(私 ? 猫 ?) '(私 は 人間 です))
#f
> (match? '(私 * 猫 ?) '(私 は 猫 です))
#t
> (match? '(私 * 猫 ?) '(私 は 軽い 機敏な 猫 なんです))
#t
> (match? '(私 * 猫 ?) '(私 は だから 人間 ですってば))
#f

多分古いLispのコードでもある程度「意味は分かる」だろう。・・・deってのは気になるけどな(笑)。
繰り返すがこの本が上梓されたのは1986年だ。これは度々引き合いに出してる「これがLispだ!」の原書と同じ出版年になる。

 
「方言だらけのLispを統一しよう」と始まった草の根仕様、Common Lisp第一版が登場したのが1984年。その二年後だとそもそもパソコン用のCommon Lisp処理系はほぼ存在しない、って言ってよく、日本では書籍的には、岩波書店から出たKyoto Common Lisp(現GCL)の実装者達が記述した「Common Lisp入門」くらいしか出版されてない状況だったんだ。

 

しかも、この本は「Common Lisp入門」と言うよりはKyoto Common Lispの解説書ってノリで・・・何故ならCommon Lisp実装がほぼ存在しなかったから、だ。
そんな中だと、当時のPC-9801なんかでは、Lisp-81と呼ばれる処理系がポピュラーで、これはちと、後にEmacs Lispへと発展するMITのMacLisp(Common Lispの前身)とは見た目とかが違い、この本の冒頭で紹介されてるde採用のLispはLisp-81なんかの方に近いカンジだ。
余談だが、このLisp-81ってのはAmazonなんかで見かけるLispの超古本なんかでは見かけるLispなんだけど「どんなLispだったのか」と言うのは、このネット時代に関わらず、全く検索に引っかからない謎のLispになっている。当然、実装も見つからないし、子孫もいない。辛うじてヤフオクマニュアルだけは売られてたみたいだが、本体は全くない・・・多分カセットテープだったんだろ(笑)。








Lisp-81・・・なんとNEC PC-8001用マニュアルだ。OSはCP/Mになってる。

販売は生活向上研究所と言うこれまたワケが分からん会社が出してたらしい。
なお、元々はThe Software Toolworksと言う海外(アメリカ)の会社(本来はゲーム会社らしい)が出したLispらしい、って事までは突き止めた。

とまぁ、1986年、っつーのは今から見るとスゴイ状況だったんだよ(笑)。
しかし、問題はLispだけ、じゃない。
この本、コードとかザーッと眺めてたんだけど、今の感覚で言うと使われてるC言語でさえおかしいんだ。「え?なんだこれ?」とかなってる(笑)。
例えば、次のようなコードが掲載されている。



ここは、表題にも書かれてるが、入力された文字列から空白文字を読みとばす処理、らしい。
さてこのコード。おかしさ、が分かるだろうか。
以前書いたが、静的型付け言語の特徴、として「同じ型の値じゃないと返せない」と言うモノがある。しかし、ここではループ処理(foreverfor(;;)のマクロとして登録されている)から脱出して返す値が片方が真偽値、もう片方がNULLとなってる・・・片方は極論整数だが、もう一方はポインタだ。型が一致してない
なんだこれ、だ。
他にも

  • skipspaceの返り値の型(intとかvoidとか)がそもそも宣言されていない。

なんつーのがあって異様な見た目になっている。
繰り返す。1986年だ。と言うことはC言語でさえANSI規格が制定される前なんだよ。
つまり、ここで使われてるC言語は今我々が通常目にするC言語とも違うブツだ。この頃、実はC言語の規格書、なんつーものも存在せずC言語のリファレンスとして存在してたK&R初版を参考にして作った実装しか存在しなかったんだ。そういう実装を通称K&R Cと呼ぶ。

 

この、リファレンスを参考にして実装を作る、ってのは要は正確な挙動を保証しない。つまり、A社が実装したC言語で作ったコードは必ずしもB社が実装したコンパイラで確実にコンパイル出来るとは限らない、と言う今じゃ考えられない前時代的な状態だったんだ。
実際この本ではCの処理系でNEC PC-9801上で動くMicrosoft C Version 3.00を指定している(他にLattice CMSX-C、LSI Cへと「コードの手直し」を要した上での移植を保証している)。この頃だと「Cはプラットフォームを選ばない」とは言われてても、コンパイラとしてはコンパイルするソースコードが「流用出来る」とは限らなかったんだ。
「標準化」が何故に必要だったのか、痛感する話だろ(笑)?そしてこの本で書かれてるCコードはレガシーもレガシー過ぎるコードで埋め尽くされている(笑)。
例えばこんな関数定義だ。



「え?」とか思わないだろうか(笑)。返り値の型がCELLP型なんだろう、ってこたぁ分かる。escoptって関数を定義しているのも分かる。問題は引数だ。levelって名前の引数が定義されてるのは分かるが型が書いていない・・・・・・。
しかし、その後、行をまたいで、改めて引数(level)の型がintだと定義されてるんだ・・・・・・。
これもK&R Cの特徴だ。ANSI C以降とは大幅に違う関数定義方式なんだ。

「Cの記述法は現代のそれとは大して違わんだろう」とか思ってたんだけど大違いだった(笑)。この本、K&R Cの知識が無いと読み下すのは相当大変だぞ(笑)。舐めてた(笑)。
とは言っても、日本語で読める「C言語によるLisp実装法解説書」がほぼねぇ状況だとこれ頑張って読むしかねぇんだよなぁ・・・・・・。
いや、マジでビックリした、と言う話。1990年以前に出された「C言語の本」を読もうとするなら気をつけろ、それは「貴方が知ってるCとは違う」と言う警告の意味を込めてこの記事を書いた。
ホント、これ読み下すのどうすんべぇ、ってなカンジなんだ(笑)。
オシマイ。

※: 余談だが、この本、出版元がアスキーなせいか「Wizardry色」に溢れてる・・・アスキーが日本版の「Wizardry」販売元だったのは皆知ってるだろう。


Apple II版「Wizardry」のWill o'Wisp

この本で実装するLispの名前は「Will o'Lisp」で(当然、ウィル・オー・ウィスプの洒落・笑)、徐々に機能を追加していくヴァージョン名は「MADI」->「MALOR」->「CALFO」->「MONTINO」->「MADALTO」となる・・・知ってる人は知ってるだろうが、これらは全てRPG「Wizardry」の呪文名だ(笑)。
当時のWizardry人気の一端が垣間見れるだろう(笑)。


同書の「クロージャ」の解説図(笑)。





  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最近の「プログラミング」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事