Simula
| Simula | |
|---|---|
| パラダイム | オブジェクト指向 |
| 登場時期 | 1967年 |
| 設計者 | Ole-Johan Dahl, Kristen Nygaard |
| 主な処理系 | GNU Cim |
| 影響を受けた言語 | ALGOL 60 |
| 影響を与えた言語 | C++をはじめとするオブジェクト指向言語 |
Simula(シミュラ)は最初期のオブジェクト指向言語の一つである。
目次 |
[編集] 概要
オスロのノルウェー計算センターのクリステン・ニガードとオルヨハン・ダールが1962年から1967年にかけて、Simulaの元となるSimula IとSimula67をALGOL60の拡張として設計/実装した。Simulaは当初シミュレーションに用いられたが、のちに汎用言語となった。名前「Simula」は「シミュレーション言語」を意味する英語「simulation language」と「簡潔な汎用言語」を意味する英語「simple universal language」の二つに由来する。
主に北欧圏で使用されたこと、言語的な未成熟さもあって広く普及することはなかったが、後続言語に与えた影響は大きい。特にSmalltalkはSimulaのオブジェクト概念を一般化したものだと言うことができる。C++もまた、当初はC言語にSimulaのクラスなどの仕組みを追加したものであった。
開発の動機は、ある制限下におかれたモデル群の全体の挙動をどう記述するか、というものである。気体の分子運動を例にとると、システム全体を考えてその中の項として分子を扱うよりも、一つの一つの気体分子をモデル化し、それぞれの相互作用の結果をシステムとして捉える方が自然で取り扱いやすい。その為には小さなモデル、関連する法則、それらを一度に複数取り扱う能力が必要となる。こうして属性を備えたオブジェクト概念と、それに従属するメソッド概念が生まれたのである。
Simula 67ではオブジェクト、 クラス、サブクラス、継承、動的束縛(仮想関数)、コルーチン、 ディスクリートイベントシミュレーション、ガベージコレクションの機能をもち、オブジェクト指向プログラミングの基本概念はすべてここで発案されているといえる。
Simulaはプログラミングパラダイムとして最初のオブジェクト指向言語であると考えられる。その名前が示すようにSimulaはシミュレーションを行うために設計され、その必要性から今日のオブジェクト指向言語で使われる多くの機能のためのフレームワークを提供した。なお、Simula当時「オブジェクト指向」という言葉はまだない。この用語はアラン・ケイがSmalltalkの概念として70年代ごろに使い出したのが始まりといわれている。従ってその意味ではSmalltalkが世界最初のオブジェクト指向言語であり、Simulaは「オブジェクト指向として再認識が可能な最古の言語」ということができる。
VLSI設計、プロセス、プロトコル、アルゴリズムといったシミュレーションや、組版、CG、教育といったアプリケーションソフトにSimulaは利用された。Simula形式のオブジェクトはC++、Java、C#で再実装されており、Simulaの影響を受けていることが知られている。C++の開発者であるビャーネ・ストロヴストルップはBCPLのような機械語を出力し高速に動作する低レベル言語にSimulaが提供する開発効率を高める機能を導入するため、C++開発時にSimula 67の影響を大きく受けていることを認めている。
[編集] 歴史
クリステン・ニガードは1957年からコンピュータシミュレーションの開発を始めた。ニガードはコンピュータの動作とシミュレーションプログラムに要求されるものの不整合を適切に記述する方法が必要であると考えた。既存のコンピュータ言語で彼のアイデアを実現するにはプログラミングのスキル以外に何かが必要であると思われた。オルヨハン・ダールは1962年1月にニガードの業務に参加した。1962年3月までには シミュレーション用プログラミング言語のメインコンセプトは固まっていた。ディクリートイベントシステムを持つシミュレーション専用のプログラミング言語"SIMULA I"が開発された。
UNIVACはUNIVAC 1107を発売するにあたりニガードを1962年3月下旬に招待した。その際にニガードはUNIVACのボブ・バーマーシステムプログラミング部長にSimulaのアイデアを説明した。バーマーはALGOLの熱烈なファンであり、Simulaプロジェクトに説得力を感じた。IFIPが主催する情報処理の第2回国際会議の議長を務めていたバーマーは論文"SIMULA -- An Extension of ALGOL to the Description of Discrete-Event Networks(ディクリートイベントネットワークを記述するためのALGOLの拡張)"を提出したニガードを会議に招待した。
ノルウェー計算機センターはUNIVACとの契約に基づいてダールがSIMULA Iを実装するためUNIVAC 1107を1963年8月に特別価格で譲り受けた。これは UNIVAC用Algol 60コンパイラを元に実装された。1965年1月にはUNIVAC 1107上で完全なSIMULA Iを利用できた。ダールとニガードはその後の2年間に渡りSimulaを教えることに費やした。Simulaは複数の国に広がり、SIMULA Iは後にバロース B5000やロシアのURAL-16に移植された。
アントニー・ホーアは1966年にレコードクラスのコンストラクタの概念を導入し、ダールとニガードは一般的なプロセス概念という要求を満たすためプリフィックスの概念などを導入してこれを拡張した。ダールとニガードはクラスとサブクラスの宣言についての論文を1967年3月にオスロで開催されたIFIPのシミュレーション用言語についてのワーキングカンファレンスで発表した。この論文はSimula 67の最初の正式な定義となった。1967年6月に言語を規格化して複数の実装を始めるためのカンファレンスが開催された。ダールはデータ型とクラスの概念の統一化を提案した。これは激論を巻き起こし委員会から却下された。SIMULA 67はSIMULA標準化グループ (SSG) の最初の会議で1968年2月に正式に標準化された。
SimulaはSmalltalkやその後のオブジェクト指向言語に影響を及ぼした。Simulaだけがコルーチンをサポートした言語ではないし、真の並列性は持たないが、アクターモデルの概念を呼び起こすのに役立った。
60年代後期から70年代前期にかけてSimulaの4つの主要な実装があった。
- UNIVAC 1100用。NCCが開発。
- System/360用およびSystem/370用。スウェーデン国立防衛研究所 (FOA) が開発。
- CDC 3000用。オスロ市シェラー (Kjeller) にあるオスロ大学のJoint Computer Installationで開発。
- TOPS-10用。ENEA ABが開発。
これらの実装は様々なプラットフォームに移植された。TOPS-10用ではメンバ変数とメソッドのpublic、protected、privateが実装され、後にSimula 87に統合された。Simula 87は最新の標準規格であり、下記の3つの実装があることが知られている。
- Simula AS
- Lund Simula
- GNU Cim - GNUのftpよりダウンロードできる
2001年11月に米国電気電子学会 (IEEE) は、「SIMULA 67の設計と実装によりオブジェクト指向の基礎概念を導きだした」ことを讃えフォン・ノイマンメダルをダールとニガードに授与した。2002年2月には「プログラミング言語Simula I及び Simula 67の実装によりオブジェクト指向を出現させた基礎的アイデア」を表彰して2001年度チューリング賞をACMより受賞した。両名は6月と8月にそれぞれ死去したため、シアトルで開催されるOOPSLAカンファレンス2002で行われる予定であったACMチューリング賞の講演に出席できなかった。
研究所はプログラミング言語Simulaにちなんで名付けられた研究所であり、ニガードはオープン時の2001年から非常勤職員として働いていた。
[編集] サンプルコード
[編集] 最小のプログラム
空のファイルはソースコードのサイズを基準とした場合で最も小さなSimulaのプログラムである。これは1つのダミーのステートメントのみで構成される。
しかしながら合理的に考えれば最小のプログラムは空のブロックとして表現される。
Begin End;
これは起動してすぐに終了するプログラムである。Simulaではプログラム自身が値を返すReturn文を持たない。
[編集] 古典的 Hello world
Simulaで記述されたHello worldの例である。Simulaは大文字と小文字を厳密に区別する。
Begin
OutText ("Hello World!");
Outimage;
End;
[編集] 典型的サブクラスと仮想関数
クラス、サブクラス、仮想関数を用いた現実的な例を以下に示す。
Begin
Class Glyph;
Virtual: Procedure print Is Procedure print;;
Begin
End;
Glyph Class Char (c);
Character c;
Begin
Procedure print;
OutChar(c);
End;
Glyph Class Line (elements);
Ref (Glyph) Array elements;
Begin
Procedure print;
Begin
Integer i;
For i:= 1 Step 1 Until UpperBound (elements, 1) Do
elements (i).print;
OutImage;
End;
End;
Ref (Glyph) rg;
Ref (Glyph) Array rgs (1 : 4);
! Main program;
rgs (1):- New Char ('A');
rgs (2):- New Char ('b');
rgs (3):- New Char ('b');
rgs (4):- New Char ('a');
rg:- New Line (rgs);
rg.print;
End;
上記の例には1つの親クラス (Glyph) と2つのサブクラス (CharとLine) があり、1つの仮想関数と2つの実装がある。メインプログラムから実行を開始する。Simulaは純粋仮想関数を持つクラスをインスタンス化できるため抽象基底クラスの概念が無い。これは上記の例にある全てのクラスがインスタンス化できるということである。しかしながら純粋仮想関数を呼び出すとランタイムライブラリエラーを引き起こす。
[編集] 名前による呼び出し
Simulaは評価戦略(call by name)をサポートしているためJensen's Deviceを容易に実装できる。しかしながら単純なパラメーターのためのデフォルトの送信モードは古いALGOL形式の名前呼び出しであり、新しいSimula形式の値呼び出しではない。従ってJensen's DeviceのソースコードをSimulaでコンパイルする際に評価戦略機能を明示的に有効にする必要がある。
より単純な例として総和関数
の実装例を以下に示す。
Real Procedure Sigma (l, m, n, u); Name l, u; Integer l, m, n; Real u; Begin Real s; l:= m; While l <= n Do Begin s:= s + u; l:= l + 1; End; Sigma:= s; End;
上記のコードは値(l)と式(u)を制御するために評価戦略を用いている。これにより式で使用する値を制御できる。Simulaの標準規格はFor文にある種の制約があるため上記の例ではwhile文を使用している。
以下の式は次のように実装できる。

Z:= Sigma (i, 1, 100, 1 / (i + a) ** 2);
[編集] シミュレーション
Simulaにはディスクリートイベントシミュレーションを行うためのシミュレーションパッケージが含まれている。このシミュレーションパッケージはSimulaのオブジェクト指向とコルーチンのコンセプトに基づいている。
下記の例でSam、Sally、Andyは服を買おうとしている。彼らは1つの試着室を共有しなければならない。3人は正規分布によりランダムに約12分間店内を探索し、同様に試着室を約3分間占有する。以下は彼らが試着室をどのように使うのかをシミュレーションするものである。
Simulation Begin
Class FittingRoom; Begin
Ref (Head) door;
Boolean inUse;
Procedure request; Begin
If inUse Then Begin
Wait (door);
door.First.Out;
End;
inUse:= True;
End;
Procedure leave; Begin
inUse:= False;
Activate door.First;
End;
door:- New Head;
End;
Procedure report (message); Text message; Begin
OutFix (Time, 2, 0); OutText (": " & message); OutImage;
End;
Process Class Person (pname); Text pname; Begin
While True Do Begin
Hold (Normal (12, 4, u));
report (pname & " is requesting the fitting room");
fittingroom1.request;
report (pname & " has entered the fitting room");
Hold (Normal (3, 1, u));
fittingroom1.leave;
report (pname & " has left the fitting room");
End;
End;
Integer u;
Ref (FittingRoom) fittingRoom1;
fittingRoom1:- New FittingRoom;
Activate New Person ("Sam");
Activate New Person ("Sally");
Activate New Person ("Andy");
Hold (100);
End;
メインブロックがSimulationでプレフィックスされることによりシミュレーションを実行できる。シミュレーションパッケージはどこのブロックからでも自由に利用でき、シミュレーションしているものそれ自体をシミュレーションするときにはシミュレーションを再帰的にネストできる。
試着室オブジェクトはキュー(door)により試着室にアクセスできる。誰かが使用中の試着室を使おうとしたときはこのキュー(Wait (door))で待たなければならない。誰かが試着室を出るとき、列の先頭にいる者がキューからリリース(Activate door.first)されてドアキューから削除(door.First.Out)される。
PersonはProcessのサブクラスでありその動作はhold(店内を探索する時間と試着室で過ごす時間)を用いて記述され、試着室に出入りするために試着室オブジェクト内でメソッドを呼び出す。
メインプログラムは全てのオブジェクトを生成し、全てのPersonオブジェクトをイベントキューに投入するためにアクティベートする。メインプログラムはシミュレーション時間で100分間待ってからプログラムを終了する。
[編集] 関連項目
[編集] 外部リンク
- INTRODUCTION TO OOP IN SIMULA
- Cim - GNUによるフリーなSimulaのC言語トランスレータ
- Cim - Simula to C translator. Mother of all OO-languages - Cim の配布ページ
- Cim 3.33 for MS Windows - 上記のWindows版