オブジェクト指向 Fortran 90/95 プログラミングについて

概要

森川が 参考図書 を読んで面白そうと思ったオブジェクト指向的 Fortran90/95 プログラミングについて紹介し, それに関する議論を行った.

以下はその際の紹介に関する記録である. なお, 言葉に関してはオブジェクト指向的 用語や Fortran 用語, 中にはオブジェクト指向スクリプト言語 Ruby の用語まで 混ざったりしていて読みづらい部分も多いかと思うがご了承いただきたい. (修正していただけるとよりありがたい…).

日時・場所・参加者

参考図書

Ed Akin, 2003:
「Object-Oriented Programming Via Fortran 90/95」
Cambridge University Press. ISBN 0-521-52408-3

オブジェクト指向とは

オブジェクト指向の 3 要素について簡単に解説. 詳しいことはオブジェクト指向に関する書籍を参照のこと.

クラスと情報隠蔽

3 章 Object Oriented Programming Concepts では, 主に Fortran90 で クラスの作り方, 情報隠蔽の手法 について述べている.

具体例としては 3.2.1 Example Date, Person, and Student Classes のサンプルプログラムを参照のこと.

クラスの作り方

情報隠蔽の手法

まず, 上記のクラスの作り方を参考にクラスを作る. その上で情報隠蔽するための手法を記す.

gtool4 での実装例

実は gtool4 でも上記のクラスが実装されている. gt4_history モジュールや gtdata_generic + gtdata_types モジュール an_generic + an_types モジュールがそれである.

例えば gt4_history では GT_HISTORY という構造体が用意されており, HistoryCreate が初期化メソッドにあたる. (ただし, デフォルトは gt4_history 内部に用意されている save 変数が利用されるため, 出力ファイルを 1 つにしている場合はあまりなじみが無いかも しれない).

継承と多態性

6 章 Inheritance and Polymorphism において継承の実装方法多態性の実装方法について述べている.

継承の実装方法

継承の定義

まず, ここで森川の考える継承の定義を述べる. (Ruby で勉強した部分が多く, 継承としての一般的定義から外れている可能性も あるので注意).

継承の F90 での実装

残念ながら, Fortran90/95 ではこれらをお手軽に実装するための仕組みは 存在していないようである. Akin (2003) の中でも, use の利用を継承と 称する部分はあるが, (もちろんまともに継承を実装する場合に use は不可欠 ではあるが), ただ use するだけでは, あくまでもベースのクラスをそのまま利用 するだけで, 新たなクラスへの継承ということにはならない.

では, 上記の継承を Fortran90/95 で実装するにはどうしたらいいかを 考察し, 以下にまとめた.

なお, これはあくまで単純継承の話であり, 多重継承の場合は 複数のベースクラスの構造体を含んだり, 複数のクラスのメソッドを インポートするなども考えられる. (多重継承を是とするか否とするかは かなり悩ましい問題なのでここでは触れない).

例えば, 上記に比較的近いのは Figure 6.9 だが, この場合も正しく継承される には, class_Employee の全てのメソッド (サブルーチン及び関数) が type Manager に対して全てインポートされなければならない.

ベースのクラスを解析して雛形を作るぐらいは可能かもしれないが, やっぱり Ruby ほど簡単ではない.

結論としては, やっぱり F90 での継承の実装はなかなか困難であると いえるだろう.

多態性の実装方法

総称名称を用いた多態性の実装

クラスの作り方でメソッドを作成してきた場合, メソッドは 属するモジュールが持つ構造体を引数にとるので, interface を利用して 1つの総称名にまとめることが可能なので, そういった意味での 多態性の実装は Fortran90/95 では容易である.

また interface 文は同じ総称名称の定義を行う場合であっても, 複数箇所で 記述することが許されているので, 各個の クラスにて interface で一般的な名称を与え, それらのクラスを 一箇所のライブラリにしてまとめておけば, 使う側はある一般的な 名称のメソッドさえ知っておけば, 後はそのメソッドは与えられた 構造体に応じて振る舞い変化させる.

異なる型の変数に大して同様な挙動をするサブルーチン・関数の開発

Fortran は Perl や Ruby といったスクリプト言語と異なり, 変数には 必ず型が存在する. そのため, 例えばほとんど挙動が同じに場合で あっても, 単精度実数と倍精度実数とで別々のサブルーチン・関数を 整備しなければならない.

他にも, 配列データを入出力するサブルーチン・関数の場合でも, 1, 2, 3, ... 次元と引数の型が異なるものをとろうとする場合, やはり 個々に手続きを用意しなければならない.

Akin (2003) では, こういったものをテンプレート (雛形) ファイルから 生成することでその開発・整備のコストを減らすことを提案している. (この方法が elegant でないことは Akin 自身も述べている).

gtool4 での試み

gtool4 では m4 というマクロプロセッサ (C プリプロセッサでもそれなりに 似たようなことはできるはずだが) を使っている. これにより, 上記のような単精度実数と倍精度実数をとる サブルーチンの作成を 1 つの雛形から可能にしたり, 1つの雛形から 1 次元 〜 30 次元までのサブルーチンを自動生成したり している.

もちろん Fortran 的に異物が入るので少々コードは見づらくなるが, かなりコストは削減される.