Simula

プログラミング言語 >>他のプログラミング言語 ■カテゴリ / ■テンプレート SIMULA（シミュラ; SIMUlation LAnguage）は、オルヨハン・ダールとクリステン・ニガードによってALGOL60を拡張する形で1960年代に開発が始められたシミュレーション用途のプログラミング言語である。 ALGOLのbegin ... endで囲まれた部分であるブロック（block）の概念を実体的な実例（instance）として扱うことを目的として、クラス（class）の構文と対象（object、オブジェクト）の概念を初めて導入した言語である。初期のオブジェクト指向プログラミング言語の一つである。 オスロのノルウェー計算センターのクリステン・ニガードとオルヨハン・ダールが1962年から1967年にかけて、Simula の元となる Simula I と Simula67 を ALGOL 60 の拡張として設計/実装した。Simula は当初シミュレーションに用いられたが、のちに汎用言語となった。名前「Simula」は「シミュレーション言語」を意味する英語「simulation language」と「簡潔な汎用言語」を意味する英語「simple universal language」の二つに由来する。 主に北欧圏で使用されたこと、言語的な未成熟さもあって広く普及することはなかったが、後続言語に与えた影響は大きい。特にSmalltalk は Simula のオブジェクト概念を一般化したものだと言うことができる。C++ もまた、当初はC言語に Simula のクラスなどの仕組みを追加したものであった。 開発の動機は、ある制限下におかれたモデル群の全体の挙動をどう記述するか、というものである。気体の分子運動を例にとると、システム全体を考えてその中の項として分子を扱うよりも、一つの一つの気体分子をモデル化し、それぞれの相互作用の結果をシステムとして捉える方が自然で取り扱いやすい。その為には小さなモデル、関連する法則、それらを一度に複数取り扱う能力が必要となる。こうして属性を備えたオブジェクト概念と、それに従属するメソッド概念が生まれたのである。 Simula 67 ではオブジェクト、 クラス、サブクラス、継承、動的束縛（仮想関数）、コルーチン、 ディスクリートイベントシミュレーション、ガベージコレクションの機能をもち、オブジェクト指向プログラミングの基本概念はすべてここで発案されているといえる。 Simula はプログラミングパラダイムとして最初のオブジェクト指向言語であると考えられる。その名前が示すように Simula はシミュレーションを行うために設計され、その必要性から今日のオブジェクト指向言語で使われる多くの機能のためのフレームワークを提供した。なお、Simula 当時「オブジェクト指向」という言葉はまだない。この用語はアラン・ケイが Simula の概念として70年代ごろに使い出したのが始まりといわれている。従ってその意味では Simula が世界最初のオブジェクト指向言語であり、Simula は「オブジェクト指向として再認識が可能な最古の言語」ということができる。 VLSI設計、プロセス、プロトコル、アルゴリズムといったシミュレーションや、組版、コンピュータグラフィックス、教育といったアプリケーションソフトに 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」を提出したニガードを会議に招待した。 ノルウェー計算機センターは 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 用。Norwegian Computing Center (NCC) が開発。 Sysmtem/360 用および System/370 用。スウェーデン国立防衛研究所 (FOA) が開発。 CDC 3000 用。オスロ市シェラーにあるオスロ大学の Joint Computer Installation で開発。 TOPS-10 用。ENEA AB が開発。 これらの実装は様々なプラットフォームに移植された。TOPS-10 用ではメンバ変数とメソッドの public、protected、private が実装され、後に Simula 87 に統合された。Simula 87 は最新の標準規格であり、下記の3つの実装があることが知られている。 Simula AS Lund Simula GNU Cim 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文 を持たない。 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（en:Jensen's Device）を容易に実装できる。デフォルトはALGOLと異なり値呼び（call by value）であるため、Jensen's Deviceを実装する際には、名前呼びであることを明示する必要がある。 単純な例として総和関数 ∑ {\displaystyle \sum } の実装例を以下に示す。 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 = ∑ i = 1 100 1 ( i + a ) 2 {\displaystyle Z=\sum _{i=1}^{100}{1 \over (i+a)^{2}}} 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分間待ってからプログラムを終了する。