童子の如くFortran について問います。時に純粋無知な童子は残酷で容赦ないので言い抜けられるように。
(少しづつ拡充してゆくつもりです。)
問その1 なんで大文字でプログラムするんですか?
Fortran 90 以降は、規格上でも小文字利用が任意となっていて処理系が許すなら小文字も使えます。ただし、大文字と小文字を区別しません。(実際の所、80年代には多くの処理系が独自拡張として小文字の使用を許していました。)
文字コードの問題
FORTRAN の開発が始まったのは 1954 年で完成したのは 1957 年ごろです。この頃はコンピュータの黎明期でコンピュータ用の確たる文字コードはありませんでした。ASCII コードや EBCDIC コードの制定は 1963 年で、FORTRAN IV(1962 年)よりも遅い登場です。
初代の FORTRAN の採用した文字コードには英字は大文字しかありませんでしたので、必然的にプログラムは大文字での記述になります。初期のコンピュータでは現今の 8bit とは違って 6bit を単位としており、FORTRAN 処理系では 1 文字あたり 6bit の割り当てとしたので大文字と数字、いくつかの記号で文字コード表がおおむね埋まって小文字を入れる余裕がありませんでした。
視認性の問題
今でもプログラミング用の専用フォントが毎年のように開発されています。数字の 1 と小文字の l など見分けのつきにくい文字の区別がつきやすいように工夫が重ねられています。
しかし、昔の処理系はコンソールであればフォントが 8*8 程度、ラインプリンタであればタイプの型は摩滅気味でインクリボンも使いまわしてかすれ気味という塩梅で、視認性が良くないのが普通でした。その場合、英大文字を用いる方が合理的でした。
比較的最近まで TURBO PASCAL/Delphi 界隈では小文字の l の使用を嫌って大文字の L をつかっていた事も思い出されます。
問その2 ラベル欄 6 カラム空白強制、1 行 72 文字までが嫌です。
それは固定形式の話で、Fortran 90 以降の自由形式なら 1~132 桁まで自由に使えます。
行指向
Fortran は、行指向のソースコード形式をとっています。元々の入力デバイスがパンチカードだったためです。最近の行指向の言語としては Python や Haskell 等が挙げられます。これらの言語でも空白が文法的意味を持っています。
Python のコーディング規約 PEP8 を見ますと、空白 4 つのインデント下げや、一行の文字数 79 文字などが強制されます。またコメントは一行 72 文字までにしろとのことで Fortran の固定形式と同じ数字が表れています。このくらいが人間にとって読みやすい桁数なんだろうと思います。(ちなみにパンチカードは 80 桁、ラインプリンタは 136 桁でした。)
一方で、Go 言語の開発者の一人 Rob Pike は「空白は意味を持つべきではない」と主張してヤンヤの喝采を受けているので、空白やインデントが意味を持つのを嫌う人も多かろうかと思われます。
(典拠:・・・)
問その3 空白が無視されるのは何故?危険では?
これも固定形式の話です。自由形式では空白は区切り文字の意味を持ちます。
まず空白を削る
Fortran の固定形式では、文字列以外の空白を除去してから字句解析が行われます。空白は(行番号のラベル欄を除けば)区切り文字としても意味をもちません。また命令や変数名の単語の途中に空白を入れても問題ありません。
したがって
DO 10 I = 1. 5
のように、コンマをピリオドに打ち間違えると、
DO10I=1.5
という変数 DO10I への代入文になります。
Backus の記述によれば、FORTRAN でこの様な仕様にした理由は、昔は紙に書いたコードをキーパンチャーに頼んで打ち込んでもらっていたが、空白(スペース)を間違えて入れることが多かったので、空白を無視することにしたそうです。
(典拠:・・・)
人間や機械の読み取りエラーが多かった時代には合理的だったのでしょう。
問4 END の前に STOP, RETURN を書くのは何故?
FORTRAN 77 以降では、書かなくても良くなっています。
END 文は非実行文だった
FORTRAN 66 までは END 文は非実行文で、宣言文のようなものでした。したがって実行時にはそこには実行すべき END 文は存在しないことになるので、STOP 文や RETURN 文が必要でした。FORTRAN 77 以降 END 文が実行文となって、文脈に応じて STOP や RETURN と同等の働きをするようになりました。
そもそも FORTRAN I には SUBROUTINE や FUNCTION のような副プログラムは無く、主プログラムしかなかったためプログラムの終了は STOP 文で行われました。FORTRAN II で副プログラムが導入されたとき、各プログラム単位ごとの区切りをコンパイラなどに明示する必要が出来て END 文が導入されました。したがって END 文は実行文というより、一種の宣言文の様な位置づけでした。FORTRAN 66 までは PROGRAM 文もなく、FORTRAN I 以来の主プログラムがいきなり始まる構造を保っていました。
また FORTRAN 77 の時代になってこれらが省略可能になっても STOP や RETURN を省略するのは『言葉の乱れ』的な風潮が残っていました。そして今にいたります。
STOP 文は
stop 666
stop '! in the name of LOVE'
のように整数定数や文字列定数を引数に取れるのでメッセージを残せます。また Fortran 2018 では、変数も書けるようになります。
問5 どうして SUBROUTINE と FUNCTION の二通りがあるのはなぜ?
最近の言語では、副プログラムの形式を function に統一して subroutine にあたるものは返り値を持たない function にしているものが多いようです。
subroutine と function の暗黙裡に使い分け
基本的な使い方の違いは subroutine は call する文で、function は代入文の右辺に現れることが許される値を持つというものです。
しかし Fortran では、subroutine と function に暗黙裡の使い分けがあります。function は導入当初から数学関数を念頭に依存性を持たない(いわば pure 属性がある)ものとして、subroutine はその他全部という使い分けがなされていました。Fortran では乱数や時間を返す機能は、すべて組み込み subroutine として定義されており、関数にはなっていません。
(参考:http://fortran66.hatenablog.com/entry/2013/11/16/182831)
ただし文法的には、大域変数への依存や引数の書き換えは禁じられていません。ただ「下品な言葉遣いはしない」的なレベルで使用されていませんでした。また FORTRAN 77 以前では副プログラムの変数は静的に確保されるのが普通だったので(つまり save 属性がついている)、正確には pure 属性に対応するものでもないのですが。
C 言語はシステム開発用言語なので、返り値はエラーコードを返す前提になっており、引数の方で値を返すようなことが標準的に行われているため、FORTRAN での使い分けを理解してもらえない時代が長く続きました。しかし21世紀に入って関数型言語ブームが起きて『参照透明性』などの概念が普及することで、思想が分かりやすくなったのではないかと思います。
Fortran では並列実行を念頭に置いてきたので、依存性には敏感で Fortran 95 からは、明示的にいわゆる『参照透明性』を pure 指定子で記述できるようになっています。
とはいえ、最近は C 言語の API 呼び出しなどで、エラーコードを返す依存性を持つ関数なども普通に書くようになっているし、coarray 文法周りで依存性を持つ組み込み関数が定義されていたりするので、subroutine/function の区切りではなく、pure/impure の明示的な区切りで依存性の有無を使い分ければいい気がします。
つづく