2014年10月15日の日記です

目次

10-15 「計算機言語」が生まれた日(1956)
10-15 変数名の話


「計算機言語」が生まれた日(1956)  2014-10-15 11:49:21  コンピュータ 今日は何の日

▲目次へ ⇒この記事のURL

今日は、計算機言語が生まれた日。

…というのは、非常に曖昧な言い方だな。


計算機言語っていうのは、つまりはプログラム言語のことね。

ただし、2進数で示される「機械語」は含まないものとします。


あれは、電気を ON/OFF するスイッチを制御するための信号だから。

また、機械語と1対1で対応しているアセンブラも、今は含まない。

(計算機言語に含む場合もあるけど、話の都合上含まないものとしてほしい)



つまり、プログラム言語とは、人間にわかりやすい形で示された「言語」を元に、機械を制御する「機械語」を直接生成するものです。




1950年代初頭、プログラム内蔵式のコンピューターは研究目的ではなく、実用になりつつありました。

そして、プログラムが思った以上の難題であることが明らかになってきます。


ここで、コンピューターは非常に高性能だから、コンピューターの力を使ってコンピューター自身をプログラムしよう、という構想が現れます。

自然言語(英語)を使って、おかしなところのない厳密な方法で仕様書を書くと、それをコンピューターが解釈して自分自身をプログラムする、というアイディアです。


これは「自動プログラミング」と呼ばれ、学術的な研究などが始まりました。



でも、意見は大きく二つに分かれます。

プログラムは想像力が必要なもので、機械にはできっこない、という懐疑派と、想像力が必要なのは仕様書を策定する部分で、そこから先の部分は機械でもできる、という推進派です。


IBM は推進派でした。

何よりも、主力商品となりつつあったコンピューターを売るためには、効率の良いプログラム方法が必要なのです。


懐疑派と推進派の論争を終わらせる方法はただ一つ。実際に自動プログラミングが可能なことを示せばよいのでした。


IBM は、この分野の研究開発を始めます。




1954年、IBM のジョン・バッカスは、問題を限られた範囲で解決するプログラム言語を考案します。


仕様書を理解する、と言っても、広範囲な仕様書では理解させるのも大変です。

そこで、当時のコンピューターの主要な利用目的であった、科学計算目的にターゲットを絞ります。


科学計算では、非常に複雑な式を扱う必要がありました。

しかし、それらの式は複雑すぎて、機械語に直すだけで一苦労なのです。


たとえば、 Y = X**2 + 5*X +4 …という、簡単に表せる数式があったとしましょう。

(X**2 は Xの2乗の意味です)


これを IBM 704 では次のように書く必要がありました。



LDQ X
MPY X
STQ Y
LDQ num5
MPY X
STQ tmp
CLA tmp
ADD Y
ADD num4
STO Y


数式ひとつ表すのにこんな苦労が必要。この部分の苦労だけでも解放できれば!


#上のプログラム、IBM704 を使ったことがあるわけではないので、自信なし。

 一応マニュアル参照しているので大きく間違っては無いと思います。

 なお、掛け算は結果を 70bit で返しますが、上のプログラムでは下位 35bit のみ使用しています。




数式を英語で FORMULA と呼びます。ここを変換、TRANSLATE する。

この言語は、FORTRAN と名付けられます。


FORTRAN は、IBM 704 をターゲットとして開発されました。


科学計算では、繰り返しもよく使われましたので、繰り返しを簡単に記述できる命令があります。


でも、数式と繰り返しを除けば、命令はほぼ IBM704 の機械語と同じです。

見た目こそ「高級命令」に見えるのですが、機械語と1対1対応なのです。



実現可能性を確かめながら、FORTRAN の文法を完成するまでに2年が費やされ、1956年に文法などを記した「Programmer's Reference Manual」が先に完成します。


実際に動作する言語処理系が完成するのは翌 1957年。


さて、このマニュアルの発行日が、1956年の今日、10月15日となっています。

(3ページ目の右上に書かれています)




FORTRAN で「自動プログラミング」が可能であることが示された後、翌1958年にはより便利な命令を増やした FORTRAN II が作られます。


FORTRAN の成功に続いて、研究目的の LISP(1958)、ビジネス向けの COBOL(1959) も作られ、さらに 、学生の勉強用に BASIC(1964) など、多くの言語が考案されています。


#余談になりますが、3D プリンタの元祖となるモデル記述言語、APTも 1958年に完成しています。


しかし、これらの言語は、今から見ると「いきあたりばったり」な文法体系です。

たしかに目的は達成できるのですが、命令の組み合わせ方が制限されていたり、論理が記述しにくかったりするのです。


FORTRAN を作り出したジョン・バッカスは、言語を作る研究をさらに続けていました。

そして、「より良い言語」を作ろうとしていた国際的なグループに参加します。


この時に作られた言語が ALGOL です。言語仕様は 1958年に作られていますが、実際に動作する処理系が出来たのは 1960年でした。


ALGOL の文法記述方法は、「バッカス・ナウア記法」(Backus-Naur form:BNF)と呼ばれます。

ピーター・ナウアは、ALGOL 開発者の一人。



BNF は、非常にすっきりと文法を記述できます。インターネットのプロトコル仕様などは BNF で表現されることが多く、RFC (インターネットで守られるべき取り決めのこと)を読むうえで、BNF を知っていることは非常に重要です。


最初の FORTRAN の記述方法などは「スパゲティプログラム」と呼ばれて忌み嫌われ、ALGOL の記述方法は良いものとされるのですが、作者は両方同じなのですね。


#FORTRAN の反省に立って ALGOL を設計した、とも言えます。




さて、FORTRAN が無ければその後の言語はありませんし、ALGOL が無ければ現在の C言語や、Java / PHP / Perl などの多くの言語もありません。


これらすべての元…FORTRAN の仕様がが世に示されたのが、1956年の今日なのですね。

そういうわけで「計算機言語が生まれた日」と書いたのです。


…発行日って恣意的な部分もあるから、本当に今日が生まれた日かわからないのですけど (^^;



▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

コンピュータ

今日は何の日

関連ページ

ジョン・バッカスの命日(2007)【日記 15/03/17】

ジョン・バッカスの命日(2007)【日記 15/03/17】

ハーマン・ホレリス 命日(1929)【日記 15/11/17】

プラスとピリオドの取り違え【日記 17/04/07】

ジョン・バッカスの誕生日(1924)【日記 14/12/03】

別年同日の日記

04年 大きく育て

04年 最終確認

13年 富一成さんの誕生日(1960)

15年 プレイステーションを生み出した新聞記事

15年 グレゴリオ暦の制定日(1582)

18年 UPS切り替え

18年 オーシャンハンター


申し訳ありませんが、現在意見投稿をできない状態にしています

変数名の話  2014-10-15 17:10:05  コンピュータ

▲目次へ ⇒この記事のURL

FORTRAN の誕生日ついでにもう一つ。


時々 FAQ のように「なんでループ変数に I とか J とか使うの?」という話を聞きます。

これ、知っている人は知ってますね。FORTRAN がそうだったから、というのが答えです。


でも、こないだ Twitter で見た疑問は「なんで FORTRAN は I から N が整数なの?」でした。

…そうきたか。そこを疑問に思ったことはなかった。


一応、疑問の主は「Integer とか Number なのだろうけど」と言う部分まで理解しています。




先に書いた FORTRAN の誕生日は、実はこの疑問が面白いと思ったために調べていて気付いたのでした。

最初のマニュアルを調べていたら、日付が近かったので「あ、これ記念日ネタだ」と。


で、答えを先に書けば、マニュアルには「I~N が整数」となっているだけで、理由は書かれていませんでした。

策定に2年かけているから、当初は何か理由があったのだろうけど、マニュアルに書く必要は感じられなかったのでしょうね。



FORTRAN が完成した 1957年には、PRIMER …つまり、FORTRAN プログラミング初心者向けの教則本が作られています。

こちらも理由は無しで「I~N が整数」というだけ。


IBM 650 にも FORTRAN があって…というか、IBM は作ってないのにカーネギー工科大学(現在のカーネギーメロン大学)が勝手に移植したようで、IBM が再配布しています。


勝手に作ったものなので一部互換性が無いようで FOR TRANSIT という名前です。

でも、再配布に際して IBM が作ったマニュアルは、704 の物とほぼ同じ。

つまり、ここでも理由は書かれていません。




FORTRAN のマニュアルなどには記述が無いので、以降は推測にすぎません。


まず、FORTRAN は科学計算用であったことに留意が必要です。

科学者が使う「変数名規則」をそのまま使う場合、特に説明はいらないのです。


適当な変数を使って式を立てる際、整数を I とするのはよくあることです。

Integer (整数、という意味の英語)の先頭の文字ね。


#通常、式を立てる際は変数は小文字筆記体で書かれるが、IBM 704 は 6bit で文字を表現するため、大文字しか使えなかった。


整数が複数必要なら、 I J K …とアルファベットを後ろにずらして順番に使います。


アルファベットの成立の歴史の中で、元々 J は存在せず、I から派生したものでした。

この点でも、I と J を同じように使うのに、それほど違和感はありません。



また、科学者は「自然数」の意味で、N を使います。

自然数っていうのは「1以上の整数」の意味ね。


こちらは、Nature number(自然数の意味の英語)の N です。

複数必要な場合、N M L …とアルファベットを前にずらして順番に使います。


なぜ前にずらすのかと言えば、おそらく理由は2つ。

1つ目は、後ろにずらした O よりも、 M の方が N に似ている感じがするから。


「同じ意味である」ことを示すのは重要なので、似ている気がするというのは大事です。

それに、NuMber (数値) という単語のイメージともあいます。


2つ目は、後ろにずらした O (オー) には、「原点」という別の意味があるのです。


O (オー)は数字の 0 (ゼロ) とよく似ています。

複数の数値をまとめて扱う場合、それらの数値すべてが 0(ゼロ) の点を O(オー)で示して特別視することがあります。


以上の理由で、科学者は整数に I J K ... を、自然数に N M L ... を使うのです。




ところで、FORTRAN の変数は、実数型と整数型しかありません。

自然数を表現したいなら、整数型を使うことになります。


FORTRAN のプログラムに於いて、自然数と整数は区別されないのです。


そこで、変数名の最初の1文字が I J K L M N で始まる変数は整数型、それ以外は実数型、と決め打ちになります。

これが、科学者にとって使いやすい言語仕様なのです。


型が変数名によって決まるので、変数の宣言などは不要で、いつでも使いたいときに変数を使えばよい、という形式でした。


#最初の FORTRAN では、変数名は6文字までの長さが許されていました。




…これ、思わぬバグの原因でした。

非常に有名な例を挙げましょう。


FORTRAN では、ループに「DO」と言う命令を使います。次みたいな感じ。


DO 100 I=1,10

WRITE (*,*) I

100 CONTINUE


行番号 100 に書かれた CONTINUE までの間を、I が 1 から始め 10 になるまで(増分1で)繰り返せ、という命令です。

(WRITE …は、変数 I を印字する命令ですが、ここでは気にする必要はありません)


当時、プログラマー(アルゴリズムを考案する人)と、コーダー(FORTRAN でアルゴリズムを記述する人)、パンチャー(コーダーの記述をパンチカードに打ち込む人)は別でした。


そして、上のプログラムをパンチャーがこう打ち込むのです。


DO100I=1.10

WRITE(*,*)I

100 CONTINUE


空白が無くなったことは問題ではありません。

FORTRAN の仕様で、空白は全く無視されました。パンチカードを無駄にしないように、詰め込んで書けるのです。


でも、空白以外に変わった場所があります。最初の行で、カンマ (,) がピリオド (.) に打ち間違えているのです。


すると、DO100I という、6文字以内の規定に正しく従った変数名に、1.10 という、変数の型に正しく沿った実数を代入してしまいます。

規定どおりなので、動作としては全くおかしくありません。


100 行目には CONTINUE という命令が書かれています。ループの終わりです。

「ループが始まってないのに終わりを書いてあればエラーになってくれるのでは」…と、今のプログラマーなら期待してしまいますが、そうはなりません。


実は、CONTINUE という命令は「明示的に行番号を作り出す」ためだけに存在する命令で、「何もしない」と決まっているのです。

だから、DO 命令が存在しないのに CONTINUE がある、という点でもエラーは出ません。



結果として、プログラマーが考えたアルゴリズムは、 カンマ (,) とピリオド (.) を間違えるというミスにより、全く違う動作に変換されてしまい、エラーとして検出されません。


この話、昔は「NASA がこれで金星探査機を失った」とされていたのですが、今は否定されていますね。

(NASA でこのバグが出たのは事実らしい。…NASA に限らず、このバグは良くあったみたいだけど)




上のバグがなぜ出るかと言えば、2つあって


1) 宣言もせずに変数が使えるのが良くない。

2) ループの「はじめ」と「おわり」をセットにしていないので、おかしくなったことに気付けない。


の2つです。


この反省から、ALGOL 以降の言語では、「はじめ」から「おわり」までのブロックを示すことと、変数を宣言することが重視されています。


ブロックは、まぁいいです。実際便利なので。

でも、変数をわざわざ宣言しないと使えないって、面倒くさいようにも思います。


で、今の言語では、変数の宣言が不要、というのも流行しています。面倒がなくていいね!

…そしてまたバグが出る。




変数の宣言が不要、というのは大抵は軽量言語 (Lightweight Language : 略称 LL) と呼ばれるものの特徴で、変数に「型」がありません。


整数型なんて知らない。全部実数でいいじゃん。

文字列型はあるけど、必要に応じて文字と数値は自動変換するよ。変数には気にせず突っ込んじゃえ。

特に型が無いんだから変数宣言なんていらないじゃん。好きな時に使えばいいよ。


…これ、非常に楽なんですよね。実際僕も現在は主に PHP / Javascript プログラマです。


#昔は Perl が好きだったし、そもそもゲームプログラマ時代はCもアセンブラも使ってましたよ。

 今でも使えると思うけど、易きに流れて楽している感じ。


さて、LL の始祖ともいえる awk は、フィルタを「言語的に拡張したもの」だったので、バグが出るほど大きなプログラムを作るのも苦手でした。


でも、awk を拡張した perl では、かなり大きなプログラムを作れる。

にもかかわらず、変数を宣言しないでも良いので、うっかり変数名を間違えた時に気付かない。




ところで、C言語では、変数は「大域変数」と「局所変数」に別れていました。

大域と言うのは、大きなプログラムの全体、どこからでも参照できるもの。


プログラムと言うのは、内部では小さなプログラムの寄せ集めになっているのだけど、「局所変数」は、この小さなプログラムの中でしか参照できないもの。

小さなプログラムの中で変数を宣言すると、局所変数になるようになっていました。


そして、perl も同じ方法です。

小さなプログラムの中で宣言すれば、局所変数になります。


逆に言えば、うっかり間違えた変数名は、宣言されていないので「大域変数」になります。

うっかりミスがプログラム全体に影響を及ぼしてしまう、ということ。



…やっぱ問題があると思ったようで、Perl 5 以降では、変数を宣言しないとエラーになる、というモードが追加され、そのモードを使うことが推奨されています。


あぁ、やっぱ変数の宣言って、面倒でもした方がよかったね、という流れ。




ところが、perl 以降に現れた Javascript でまた、変数の宣言が不要になります。

局所変数の定義方法など、perl と同じ構造。問題の再発です。


こちらも、同じ問題は同じ対処で…と、変数を宣言しないとエラーになるモードが追加されます。

なんと、このモード切替方法まで perl とほぼ同じ。




さらに後に作られた PHP 。


同じ轍は踏まないけど、面倒な変数宣言はやっぱ使いたくない、と思ったのか、「宣言しない限り局所変数」となりました。

小さなプログラムの中で「これは大域変数だよ」と宣言したものだけが、大域変数として使えます。


なるほど、これなら、うっかりミスしても影響は局所的です。

根本的な解決方法にはなっていませんが、perl や Javascript よりは良さそう。



でも、変数宣言したくないものだから、「URL で変数を渡したら、自動的に大域変数になる」なんて機能もあったのですね。

これが大問題で、PHP の最大のセキュリティホールとして、大きな仕様変更を伴いながら、現在では基本的に機能が無くなりました。


…過去との互換性を考えて、まだこの機能を「使おうと思ったら使える」のですけどね。

セキュリティ的には良くないのだけど、過去にやっちゃったので、今更やめにくい。

(近い将来廃止する、とずっとアナウンスしていますが)


今では、やはり「変数の宣言必須モード」にするのが推奨です。

でも、あまり使われているように思いません。


#デフォルトでそのモードなのだけど、「解除方法」が書かれた BLOG が山ほどある。

 みんなこのモード嫌がっているみたい。



ところで、PHP は WEB サーバー用として、Javascript は WEB ブラウザ用として、それぞれ人気のある言語です。

セットで勉強中、という人も多いようなのだけど、この二つで変数の「宣言しなかった時の挙動」が正反対。


言語を学ぼうとする人に、思わぬ障害になっているようです。




最後の方、FORTRAN の話からどんどん離れていきました。

まぁ、FORTRAN から始まる「変数の話」ということで。


▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

コンピュータ

関連ページ

ジョン・バッカスの命日(2007)【日記 15/03/17】

ジョン・バッカスの命日(2007)【日記 15/03/17】

ハーマン・ホレリス 命日(1929)【日記 15/11/17】

プラスとピリオドの取り違え【日記 17/04/07】

ジョン・バッカスの誕生日(1924)【日記 14/12/03】

別年同日の日記

04年 大きく育て

04年 最終確認

13年 富一成さんの誕生日(1960)

15年 プレイステーションを生み出した新聞記事

15年 グレゴリオ暦の制定日(1582)

18年 UPS切り替え

18年 オーシャンハンター


申し訳ありませんが、現在意見投稿をできない状態にしています


戻る
トップページへ

-- share --

23000

-- follow --




- Reverse Link -