FORMAT 芸 リフレクション?


FORTRAN の FORMAT はインタープリタ方式

Fortran の I/O の FORMAT は、実行時に解釈されるインタープリタ方式になっています。このため書式付き I/O が遅くなっていて、昔から難癖付けられています。人間が開いて見るのでなければバイナリで読み書きするのが無難でしょう。

ある時 FORTRAN の開発者である J. Backus が、 FORMAT の書式の解釈はコンパイル時に静的に確定されてもいいはずなのに、インタープリタ方式なったのは何故かと聞かれて、分かっていたが FORTRAN I の時にスケジュールが遅れて時間が足りなかったからだと答えています。1

ところで FORTRAN77 以降 FORMAT は、FORMAT 文や文番号抜きに、READ/WRITE 文に直接文字列や文字変数として与えることが出来ます。 (FORTRAN66 でも、変数や定数に文字型はありませんが、変則的に可能でした。)

例:

write(6, '(f10.2)') x 

したがって、静的な言語である classical な FORTRAN でも FORMAT の所だけは、実行時に動的に自己書き換えを行うことが出来、いわゆる reflection(リフレクション=内省?)が出来ます。微妙ですがw

以下に簡単な実例を示します。

実例  

modern fortran 版ですが・・・

format を文字変数 fmt に入れています。内部ファイルへの write で文字列 fmt 自身を書き換えます。DO LOOP で fmt 中に1回目は十進数で、二回目以降は二進数のビット表示で書き出しています。

実は fmt 自身を書き換えるタイミングがよく分かっていませんが、一応動いていますw

source program

    program Console1
        implicit none
        character(len=80) :: fmt = '(a, i1, a)'
        integer :: i
        print *, fmt
        do i = 2, 4
            write(fmt, fmt) '(a, b', i, ', a)' 
            print *, fmt
        end do    
    end program Console1

intel fortran 出力

(a, i1, a)

(a, b2, a)

(a, b11, a)

(a, b        100, a)

gfortran 出力

 (a, i1, a)
 (a, b2, a)
 (a, b11, a)
 (a, b        100, a)

  1. R. Wexelblat, editor. History of Programming Languages, ACM Monograph Series, Academic Press, 1981. p.70 ; http://www.softwarepreservation.org/projects/FORTRAN/paper/p68-lee.pdf (少し記憶違いがあって、Backus の指名で担当者が方便上のもので本当はコンパイルする意図だったが時間が無かったと答えています。)