Simula

Simula，一種編譯式的程式語言，由奧利-約翰·達爾與克利斯登·奈加特，在1960年代於挪威奧斯陸的挪威計算中心，開發出來了Simula I與Simula 67兩代。它承繼了ALGOL 60作為基礎，被認為是第一個物件導向程式設計的程式語言。

Simula 67介入了對象、類、子類（後來慣稱為子類繼承超類）、虛過程，還有協程、離散事件模擬和特徵性的垃圾收集。Simula的影響經常被低估，Smalltalk、CLU、C++、Object Pascal、Modula-3、Java和後來的很多程式語言，受到了Simula 67的啟發。BETA是Simula的現代後繼者。

## 歷史

<image>

1957年，克利斯登·奈加特開始在挪威國防研究機構的Ferranti Mercury電腦上寫模擬器，為此他需要更強大的程式語言。1962年1月，奧利-約翰·達爾開始跟他合作，他們受到ALGOL 60的啟發。1962年5月，發展出第一份模擬器程式語言提議，語言取名為SIMULA，後改稱為Simula I。此時，克利斯登·奈加特受到Sperry公司邀請，去協助他們開發UNIVAC 1100/2200系列電腦。UNIVAC軟體部門的主管鮑伯·貝莫，力邀克利斯登·奈加特前往國際資訊處理聯盟（IFIP）舉行的第二次國際會議上，發表了論文「SIMULA－擴展ALGOL到離散事件網路的描述」。

1963年8月，挪威計算中心（NCC）購買到UNIVAC 1100/2200系列，在UNIVAC的合約同意下，奧利-約翰·達爾在這台電腦上安裝以凱斯西儲 1107 ALGOL 60的編譯器來實作的Simula I。1965年1月，Simula I終於可以在UNIVAC 1107上完全的運作。Simula I在1968年被移植到了Burroughs大型系統 B5500電腦，以及後來蘇聯的Ural (電腦)電腦。

1965年，東尼·霍爾首次提出「記錄類」（record class）構造的概念，1966年，克利斯登·奈加特與奧利-約翰·達爾二人，將Simula I的具有「准並行」性質的「進程」，擴展成了具有了記錄類性質的廣義進程，隨即改稱為「物件」。1967年5月，奈加特和達爾在奧斯陸舉辦的IFIP工作小組論壇中，發表了關於類與子類聲明的論文，形成Simula 67的第一份定義文件。

1968年召開的會議，組成了SIMULA標準小組，並發表了第一份官方Simula標準文件「SIMULA 67通用基礎語言」。在1960年代後期和1970年代早期，Simula 67主要實現於四個系統之上：挪威計算中心的UNIVAC UNIVAC 1100/2200系列，挪威計算中心的IBM System/360和IBM System/370，奧斯陸大學在Kjeller聯合安裝的CDC CDC 3000系列，和瑞典國防研究所（FOA）的DEC TOPS-10。

當前的Simula 67業界標準，是在1986年修訂的「標準SIMULA」，它在1987年被接受為瑞典國家標準。它有四個主要實現：Simula研究實驗室、Lund Simula、GNU Cim和Portable Simula Revisited。

Simula影響了Smalltalk，和後來的面向對象程式語言。C++語言和Java語言的創始人，都認可自己受到了Simula的重要影響。

## 語法和語義

Simula 67包含通用算法語言ALGOL 60的多數特徵作為自己的子集，它是大小寫不敏感的。Simula 67的中心概念是對象，對象是自給自足（self-contained）的一段程序即一個塊實例，它擁有由一個類聲明定義的自己的局部數據和行動（action）。類是一種過程，它有能力引起在它被調用後仍存活的一個塊實例，而這些實例就叫做這個類的對象。為了操縱對象和相互關聯對象，語言介入了鍊表處理設施。

Simula 67為了將整個程序執行組織為：對象所屬的諸「行動階段」的一個序列，而將其所必需的基本功能特徵，包含在作為「系統類」的「環境類」之中。在環境類中有被稱為「標準系統類」的模擬器類`Simulation`，它定義了充當系統時間軸的「定序集合」（sequencing set）對象`SQS`、進程類`Process`和事件通告類`EVENT_NOTICE`，定序集合的成員是事件通告對象，它通過其`PROC`特性提及一個進程對象；事件通告表示了對應這個進程對象的下一個行動階段的一個事件，被調度在系統時間`EVTIME`時發生。

### 塊

塊是成序列的聲明，跟隨著成序列的語句，並被包圍在關鍵字`begin`和`end`之間。塊自身是一種語句，在Simula 67中，它包括子塊和有前綴（prefixed）塊，在語法上，子塊就是無前綴的ALGOL 60的塊，即匿名塊和過程主體。

聲明擔負定義在程序中用到的量（quantity）的特定屬性，並給它們關聯上標識符，這包括：簡單變量、陣列、接轉（`switch`）、過程、類和外來聲明。塊中的每個語句，都可以是塊或複合語句。複合語句與塊相比在語法上沒有聲明。

所有的塊，自動地介入名稱目錄（nomenclature）的一個新的層級：在這個塊內出現的標識符，可以通過合適的聲明，而被指定為局部於所論及的這個塊；這個標識符在這個塊裡面的所表示的實體，不存在於它的外面；這個標識符在這個塊外面的所表示的任何實體，在這個塊裡面是不可見的；在Simula 67中，可通過連接或遠程訪問使它成為可見的。

除了表示標籤的標識符之外，一個標識符，如果出現在一個塊中，而且並非聲明於這個塊中，則它非局部變量於這個塊。因為塊中的語句自身可以是一個塊，局部和非局部於一個塊的概念，必須遞歸地去理解。

塊是一種形式描述或模式，關乎匯聚的數據結構和關聯的演算法以及行動。當一個塊執行的時候，生成這個塊的一個動態實例。一個塊實例，可以被認為是它的形式描述的文字複本。在電腦中，一個塊實例可以採用某一種形式的記憶體區域，它包含需要的動態塊資訊，並包括空間來持有局部於這個塊的變量的內容。

塊的任何一個內部的塊，仍然是一個模式，但是在其中出現的非局部變量標識符，標定了局部於在字面上外在包圍（textually enclosing）的塊實例的項目。非局部變量於內部的塊的標識符綁定，對這個內部的塊的任何隨後的動態實例，保持有效。

塊實例中的局部變量，標識了分配給塊實例的記憶體片段。在進入一個塊之中的時候，任何局部於這個塊即在其中聲明的變量，都會被初始化。局部於一個塊的一個變量，是一個記憶體設備，其內容依據這個變量的類型，要麼是一個值，要麼是一個引用。

值類型可特徵化為直接關聯著一個可能值的集合，即這個類型的「值範圍」。引用概念，對應於一個名字或一個「指針」的直觀想法。在Simula 67中有兩種引用類型，對象引用類型和文本引用。對於值類型不關聯著引用概念。提供了引用值的機制，還反映了機器的尋址可能性；在特定簡單情況下，一個引用可以被實現為一個存儲的值的記憶體地址。

### 過程

過程與塊相比，它有一個名字，可以在程序的一些不同地方提及，並且在調用時可以給出參數。過程和塊都不可能建立到它或它內部的引用；對於一個給定塊，有可能生成它的一些可以共存和交互的實例，例如遞歸過程的實例。

過程的參數傳送模態，除了有傳值調用和傳名調用，在Simula 67中，又增加了傳引用調用。過程的預設的傳送模態，在Simula 67中，對於值類型的參數是傳值調用，對於所有其他類型的參數是傳引用調用；故而在過程聲明的參數規定中，增加了以`name`為前導的名字部份，用來指定所述及的參數採用傳名調用。

在過程主體內傳名調用的形式參數的每次出現，都引起對實際參數的一次求值。在Simula 67中，這個求值發生在過程語句的上下文中，就是說不會出現標識符衝突，因為過程主體和它的變量此時是不可見的。過程調用的執行，在有參數的情況下要經歷如下步驟：建立形式參數塊實例；求值對應於傳值調用或傳引用調用的實際參數，並將其結果賦值給形式參數塊實例的對應變量；過程主體被初始化並開始執行。

真正（proper）過程，不定義特定類型的函數指定式的值，在Simula 67中，它被稱為具有普遍（universal）類型，任何類型都從屬（subordinate）於普遍類型。

### 類與對象

類聲明定義一個程序（數據和行動）模式，而符合（conforming）這個模式的對象被稱為「屬於相同的類」。不同於Smalltalk 80等面向對象程式語言，Simula 67的類和後來的Modula-3的對象類型，不進行實例變量與類變量的區分。

對於一個給定對象，類聲明中形式參數、在虛擬部份中規定的虛擬量，和聲明為局部於類主體（body）的量，叫做這個對象的特性（attribute）。一個特性的聲明或規定叫做特性定義。在1986年修訂的語言標準中，通過保護規定可以限制類特性標識符的可見性。

類聲明中的形式參數，不適用傳名調用，這是為了保證實際參數在類所引起的對象存活期間不能消失。在規定部份中需要對每個形式參數進行規定，這些參數被當作局部於類主體的變量。類主體通常是一個塊，即使它如語法形式所允許的那樣是塊以外的一個語句，也表現得如同一個塊。一個分裂（split）主體表現為一個塊，在其中符號`<span style="color:green;font-weight: bold;">inner</span>`表示一個虛設（dummy）語句。

Simula 67的類主體中除了有定義特性的聲明，還可以有定義行動的語句。如果在一個類聲明中有行動定義，則符合這個模式的行動，可以由屬於這個類的所有對象執行。如果在類聲明中沒有指定行動，則定義了一類純數據結構，很多後來的面向對象程式語言就是這樣，將對象作為記錄或結構的擴展。例如：

```ObjectPascal
class Order(number); integer number;
begin
    integer numberOfUnits, arrivalDate;
    real processingTime;
end;
```

屬於特定類的對象，通過對象表達式中的對象生成式`<span style="color:green;font-weight: bold;">new</span>`來生成，並製作出到它的引用。例如，想要多少就能生成多少屬於這個`Order`類的一個新對象：

```ObjectPascal
new Order(103);
```

屬於一個對象的行動，可以都在就一個過程而言的一個序列中執行。這些行動，還可以作為一系列的獨立子序列或「行動階段」（active phase）來執行。在一個給定對象的兩個行動階段之間，可以出現任何數目的其他對象的行動階段。

### 子類與類串接

一個類可以被用作到另一個類聲明的「前綴」，從而將前綴所定義的性質，建造入這個新的類聲明定義的對象之中。具有前綴類`C`和類標識符`D`的一個類聲明，定義了類`C`的一個子類`D`。屬於子類`D`的對象，由自身是類`C`的對象的「前綴部份」，和類`D`的類聲明主體所描述的「主體部份」組成。這兩部份串接而形成了一個複合對象，它可以用串接成的類聲明來正式的描述，串接的過程被認為先於程序執行而發生。

類只能在定義它的塊層級中用作前綴。前綴類自身也可以有前綴。類不能出現在自己的前綴序列中。子類被稱為內部（inner）於前綴類，而前綴類被稱為外部（outer）於子類，但不可將子類稱為前綴類的內部類。這不同於後來的面向對象程式語言中的稱謂：「派生類」擴展「基礎類」，或「子類」繼承「超類」。例如：

```ObjectPascal
Order class SingleOrder;
begin
    real setupTime, finishingTime, weight;
end;
SingleOrder class Plate;
begin
    real length, width;
end;
```

屬於`Order`類的子類如`SingleOrder`類和`Plate`類的新對象，都含有`Order`類定義的數據，再加上在各種類聲明中定義的補充數據。例如，屬於`Plate`類的對象含有`Order`類、`SingleOrder`類和`Plate`類定義的所有數據。

一個標識符在一個塊中的出現，如果並未處在遠程標識符之中或在有重新定義的內部的塊之中，則被稱為「未託付」（uncommitted）出現。對於子類的聲明及其前綴類串接成的類聲明，在局部於子類的特性標識符，和局部於其前綴類的特性標識符，二者的未託付出現之間的可能衝突，將憑藉對涉及到的局部於子類的特性標識符的適合的系統性變更來避免，但是對應虛擬量的標識符不變更。

對於前綴類和子類聲明串接成的類聲明，它的形式參數列表，由前綴類的形式參數列表，和附加的子類聲明的參數列表二者合併而成。它的值部份、規定部份和虛擬部份，是前綴類和子類聲明相應各部份的併集。結果的虛擬部份不能包含某個標識符的多於一次出現。

對於類主體，最初的`begin`和隨後的聲明被稱為「塊頭部」，從第一個可執行語句直到`inner`之前的語句被稱為「初始運算」，在`inner`之後的語句和最終的`end`被稱為「複合尾部」。如果前綴類主體是分裂主體，用前綴類的塊頭部複本替代子類的塊頭部中的`begin`，將前綴類的初始運算複本插入到子類的塊頭部之後，用前綴類的複合尾部複本替代子類的複合尾部中的`end`。如果前綴類主體不是分裂主體，它被解釋為如同將`;inner`插入到最終的`end`之前。

設`C<sub>n</sub>`是具有前綴序列`C<sub>1</sub>, C<sub>2</sub>, ……, C<sub>n-1</sub>`的一個類，這裡類`C<sub>k</sub>` `(k = 1, 2, ……, n)`的下標`k`叫做前綴層級，`X`是屬於類`C<sub>n</sub>`的一個對象，則`X`是一個複合對象；非正式的說，串接機制有如下結果：

- 對象`X`擁有的特性集合，是在序列`C<sub>1</sub>, C<sub>2</sub>, ……, C<sub>n</sub>`中諸類所定義特性集合的併集。在類`C<sub>k</sub>` `(1 <= k <= n)`中定義的特性，被稱為定義在前綴層級`k`。
- 對象`X`擁有的「運算規則」，由來自這些類主體的諸語句構成，它們所屬的前綴層級遵循規定的次序。來自類`C<sub>k</sub>`的語句，被稱為屬於對象`X`的前綴層級`k`。
- 在對象`X`的前綴層級`k`的語句，能訪問在對象`X`的等於或外部於`k`的前綴層級上定義的它的所有特性，但是如果外部的類`C<sub>i</sub>` `(i < k)`中存在衝突定義，則導致對應特性不可見而不能直接訪問。這些不可見特性仍有訪問方式，例如通過使用過程或`this C<sub>i</sub>`。
- 在對象`X`的前綴層級`k`的語句，不能立即訪問在對象`X`的內部於`k`的前綴層級上定義的它的那些特性，除非通過虛擬量。
- 在前綴層級`k`的分裂主體中，符號`inner`，表示對象`X`的屬於內部於`k`的前綴層級的運算規則的諸語句，或者在`k = n`時表示虛設語句。如果序列`C<sub>1</sub>, ……, C<sub>n-1</sub>`都沒有分裂主體，則在對象`X`的運算規則中諸語句所屬的前綴層級遵循遞增次序。

用作前綴的系統類，與其前綴鏈的所有的類一起，被當作聲明於最小的包圍其字面上出現的塊中。因此重新聲明可以出現在一個程序的內部的塊層級中。

有前綴塊的一個實例，是由塊前綴生成的一個單一的對象，與這個主體塊的實例，串接而成一個複合對象，其串接定義採用類似於類的串接規則。塊前綴的類的形式參數，按塊前綴的實際參數所示初始化。對有前綴塊有兩個限制：一個類如果在其中通過使用`this`來引用類自身，則它作為塊前綴是非法的。塊前綴的類標識符所提及的類，必須局部於最小的包圍這個有前綴塊的塊。

### 對象引用

當屬於各種類的很多對象，作為同一個程序的各個部份而共存的時候，需要能夠對個體對象指定名字，為此介入了叫做「引用」的新的基本類型；還要能相互關聯對象，比如通過二叉樹和各種其他類型的列表結構。Simula 67將循環雙向鍊表叫做「集合」，它將集合類`Simset`作為「標準系統類」介入為環境類的一部份。

對於某個類的一個對象，有一個唯一的關聯的「對象引用」標定這個對象，並且對於任何類`C`，都有一個關聯的對象引用類型`<span style="color:green;font-weight: bold;">ref</span>(C)`。這種類型的量，被稱為由類`C`限定；它的值，要麼是一個對象，要麼是表示「沒有對象」的特殊值`<span style="color:green;font-weight: bold;">none</span>`。

限定（qualification）將值的範圍，限制至包括在限定類中的這些類的對象。不管何種限定，值的範圍都包括值`none`。一個對象引用的限定，是一個類標識符，它因此服從聲明的作用域和可見性 (去歧義)規則。限定關聯於所提及的類聲明所局部於的那個塊的一個實例。這蘊涵著特定的關於限定有效性的檢查，不能單獨在程序正文的基礎上進行，因此這種測試必須在程序執行期間完成。

引用是有限定的，蘊涵著一個給定引用所提及的對象，只能屬於這個限定中提到的類，或屬於這個限定類的子類。如果一個對象引用類型的限定，是另一個對象引用類型的限定類的子類，則前者被稱為從屬於後者。例如：

```
<tt><span style="color:green;font-weight: bold;">ref</span>(Order) next, previous;</tt>
```

對象表達式是獲得對一個對象的引用的一種規則。對象表達式的值，是被引用的對象或`none`。運算符`:-`讀作「指稱」（denote），它指示將一個引用，指派（assign）到處在「引用指派符」左側的引用類型的變量或過程標識符。例如：

```
next :- <span style="color:green;font-weight: bold;">new</span> Plate(50);
previous :- next;
next :- <span style="color:green;font-weight: bold;">none</span>;
```

而運算符`:=`讀作「成為」（become），指示將一個值，指派到處在賦值符左側的值類型的變量或過程標識符，或者將一個文本值，指派到在賦值符左側者所引用的那個文本幀（frame）。

### 遠程訪問

一個對象的一個特定特性，由下列三項資訊來完全標定（identify）：

- 這個對象。
- 外部於或等於這個對象的類的一個類。
- 在這個類中或在屬於它的前綴序列的任何類中定義的一個特性標識符。

對於任何特性標定，第二項類資訊都是在字面上定義的，從而形成靜態綁定。屬於其他對象的特性，可以要麼單個的通過「遠程標識符」（「點表示法」），要麼成組的通過「連接」（connection）機制，從其外面「遠程訪問」來引用和使用。

遠程標識符的形式為：`<small>简单对象表示式</small>.<small>特性标识符</small>`，它可用作簡單變量、陣列變量、函數指定式（designator）和過程語句中的標識符，這種點表示法給出對資訊的單獨片段的訪問，例如：

```ObjectPascal
if next.number >= previous.number then ……;
```

它將名為`next`的類`Order`的對象的特性`number`，比較於名為`previous`的類`Order`的對象的特性`number`。

「成組訪問」可通過連接語句`inspect`來完成，例如：

```
<tt><span style="color:green;font-weight: bold;">inspect</span> next <span style="color:green;font-weight: bold;">when</span> Plate <span style="color:green;font-weight: bold;">do begin</span> …… <span style="color:green;font-weight: bold;">end</span>;</tt>
<tt><span style="color:green;font-weight: bold;">inspect new</span> Plate(50) <span style="color:green;font-weight: bold;">do begin</span> …… <span style="color:green;font-weight: bold;">end</span>;</tt>
```

在這裡的`begin`和`end`之間的語句中，`next`引用的對象所屬的`Plate`類的所有資訊片段，都可以直接提及。

在`do`後面的語句，如果是塊以外的一個語句，它表現得也如同一個塊。連接語句進而表現得如同被叫做「連接塊」的第二個擬制（fictitious）的塊所包圍。連接機制的用途，是為在連接塊中的特定特性標定，提供對象資訊和在`when`子句中的類資訊的隱式定義。

設對象表達式求值為`X`，在連接塊執行期間，稱對象`X`為「被連接上」了。連接塊有一個關聯的「塊限定」，如果連接塊有`when`子句，它是前面的類標識符，如果沒有`when`子句，它是前面的對象表達式的限定。

### 虛過程

虛擬（virtual）量，是在類聲明中由`<span style="color:green;font-weight: bold;">virtual:</span>`前導的量，它有雙重用途：

- 允許在一個對象的一個前綴層級上，訪問在內部前綴層級上聲明的特性。
- 允許在一個前綴層級上的特性重新定義，在外部前綴層級上有效。

不同於一般的特性標定，虛過程形成「半動態綁定」，在某種意義上是類似傳名調用的機制。這種機制不同於Smalltalk 80等面向對象程式語言中，上溯子類至超類的繼承鏈來找到最近的方法實現的那種動態綁定。

一個對象的一個虛擬量，要麼是「無匹配的」的，要麼被標定為具有一個「匹配」特性，它是在這個虛擬量的前綴層級上或在內部前綴層級上聲明的，其標識符重合（coincide）於虛擬量的標識符的一個特性。匹配特性必須與虛擬特性有相同的種類。在一個給定前綴層級上的匹配量的類型，必須重合或從屬於這個虛擬規定的類型，和在任何外部前綴層級上聲明的任何匹配量的類型。

在1986年修訂的語言標準中，虛過程量可選的可使用`<span style="color:green;font-weight: bold;">procedure</span> <small><过程标识符></small> <small><过程规定></small>`方式來指定，即憑藉它的類型，並且如果它有形式參數，則還憑藉它們的類型、種類和傳送模態。含有過程規定`<span style="color:green;font-weight: bold;">is</span> <small><过程声明></small>`的虛過程量，只能由有相同類型的過程來匹配，並它與這個過程規定具有相同的過程頭部。

例如，下面實現散列表的`HashTable`類，聲明了整數類型的虛過程`hash`並隨即實現了它，又定義了要用到這個散列函數`hash`的查找過程`lookup`:

```ObjectPascal
class HashTable(n); integer n;
    virtual: integer procedure hash;
begin 
    integer procedure hash(t); text t;
    begin 
        ……
    end hash;
    text array table(0 : n-1); ……
    integer procedure lookup(t, old);
        name old; Boolean old; text t;
    begin
        integer i, istart; Boolean entered;
        i := istart := hash(t);
        while not entered do
        begin
            ……
        end;
        lookup := i;
    end lookup;
end HashTable;
HashTable class ALGOL_hashing;
begin
    integer procedure hash(t); text t;
    begin
        ……
    end hash;
end ALGOL_hashing;
```

作為子類的`ALGOL_hashing`類和以`HashTable`類為前綴的有前綴塊，可以用自己的`hash`過程實現，替代在`HashTable`類中的實現。在子類的類主體和有前綴塊的主體塊中，能獲得到過程`lookup`，而它用到的過程`hash`是這裡提供的替代實現。

### 對象表達式

對象表達式 (電腦科學)，具有類型`<span style="color:green;font-weight: bold;">ref</span>(<small>限定</small>)`。對象表達式的限定規則包括：對象生成式（generator）、局部對象或限定對象，分別由跟隨符號`new`、`this`或`qua`的標識符的類來限定（qualification）。

對象生成式new C，這裡標定了類`C`，它涉及到屬於類`C`的對象的生成和執行。這個對象是類`C`的一個新實例。對象生成式的求值構成自如下行動：

- 生成這個對象，並且如果這個對象生成式有實際參數，則求值它們，將得到的這些值及或引用傳送給形式參數。
- 控制經過這個對象最初的`begin`進入其中，它籍此變成在「系附」狀態下運行。當所生成的對象執行了`detach`基本過程變為「脫離」狀態，或者經過這個對象最終的`end`退出而變為「終止」狀態，對象生成式的求值完成。

局部對象this C，這裡的`C`是類標識符。如果用在類`C`或`C`的任何子類的類主體中，或用在其塊限定為類`C`或`C`的一個子類的連接塊中，則這個對象表達式是有效的。在一個給定的上下文中，一個局部對象的值，是一個對象或連接到一個對象，它是這個對象表達式在其中有效的、最小的在字面上外在包圍的塊實例；如果沒有這樣的塊，則這個對象表達式在這個上下文中是非法的。對於一個過程或類主體的實例（上下文），「在字面上外在包圍」（textually enclosing）意為包含它的聲明。

暫瞬限定`X <span style="color:green;font-weight: bold;">qua</span> C`，這裡的`X`表示一個簡單的引用表達式，而`C`是類標識符。設類`D`是對象`X`的限定，對於限定對象`X qua C`，如果類`C`外部於或等於類`D`，或者是`D`的一個子類，則這個對象表達式是合法的，否則是為非法。如果`X`的值是`none`，或者是屬於外部於`C`的類的一個對象，則這個對象表達式求值形成一個運行時間錯誤；在其他情況下，`X qua C`的值，就是`X`的值。對一個串接的類對象的暫瞬限定，限制或擴展它的特性通過檢視或遠程訪問的可見性。

對象關係表達式，使用運算符`is`和`in`，來測試一個對象的類成員關係。關係X is C，在`X`引用的是屬於類`C`的對象之時，值為`true`，否則值為`false`。關係X in C，在`X`引用的是屬於類`C`的對象，或者`X`是內部於類`C`的類之時，值為`true`，否則值為`false`。

不同於算術關係表達式使用比較運算符`=`和`<>`，對象引用關係表達式，使用比較運算符`==`和`=/=`，來比較引用，從而區別於對應的被引用的值。兩個對象引用`X`和`Y`，在它們都引用相同的對象，或者它們都是`none`之時，被稱為是「同一性 (面向對象編程)」的。關係`X == Y`，在這種情況下擁有的值為`true`，否則值為`false`。關係`X =/= Y`的值，是`X == Y`的值的否定。

### 作用域和可見性

不同於ALGOL 60規定了量的作用域與可見性 (去歧義)，在Simula 67中，一個標識符定義及其關聯的標識符，在其作用域與可見性之間需要做出區別。

- 作用域：一個標識符定義的作用域，是它在其中可能有作用的那一部份程序正文。同一個標識符，可以定義在程序的很多地方，因此可以關聯於不同的量。同一個標識符的這些定義的作用域，因而可能有所重疊，例如在一個標識符在內部塊中被重新聲明的情況下。
- 可見性 (去歧義)：一個標識符定義，如果它所關聯的標識符，在程序的給定點上能夠提及到這個定義所聲明的量，則它被稱為在這個點上是可見性 (去歧義)的。在給定標識符於此可見的程序正文的一個特定點上，最多只能有一個定義關聯於這個標識符，例如在重新聲明的情況下，在它們作用域的併集內任何給定點上，只有一個定義是可見的。

一個標識符定義的局部塊，是在字面上最近的包圍塊，即子塊、前綴塊、過程主體或類主體，還包括圍繞`for`語句的受控語句、過程聲明、類聲明和連接塊等的擬制塊。這個標識符和它的定義，被稱為局部於這個塊。

標識符定義，只在它們的作用域內是可見的。一個特定定義的可見性，在它的作用域內可以受到下列限制：

- 在一個標識符定義的局部塊所包圍的某個構造內，出現的具有相同標識符的標識符定義，是這個標識符的重新定義。在它們共同的作用域內，只有最內部的重新定義是可見的。
- 一個重新定義，出現在類的某個內部前綴層級。
- 遠程訪問，可以導致某些標識符定義在檢視塊或點表示法內變成不可見的。
- 使用`this`或`qua`，可以導致一個或多個重新定義被暫時停止。
- 在這個標識符定義所局部於的類聲明中，這個標識符出現在由`hidden`及或`protected`前導的保護部份中。

一個標識符的重新定義，不允許出現在它的局部塊的頭部，這禁止了在同一個塊中出現相同標識符的兩個定義。

### 塊實例

一個程序執行的各個組成部份，都是塊即子塊、有前綴塊、連接塊和類主體的動態實例。一個塊實例，被稱為「局部於」直接包含它的描述正文的那個塊實例。例如一個給定類的實例，局部於包含這個類聲明的塊實例。最外層塊的實例不局部於塊實例。

在任何時間，「程序順序控制」（Program Sequence Control），首字母簡寫為PSC，參照在一個塊實例中當前被執行的程序點；形象的說，PSC「定位」至這個程序點，並被這個塊實例所「包含」。進入任何塊，都涉及到生成這個塊的一個實例，於是PSC進入這個塊實例，到達它的第一個可執行語句上。

一個塊實例在任何時間，都是處在四種執行狀態 (電腦科學)之一：系附（attached）、脫離（detached）、恢復（resumed）或終止（terminated）。沒有在字面上給出前綴的任何類，都被定義為前綴了一個擬制（fictitious）的類，它只有一個特性即`detach`過程，因此所有類對象或有前綴塊的實例，都擁有`detach`過程。在環境類`ENVIRONMENT`中，還定義了用於調度的`call`過程和`resume`過程。

- 一個非類塊實例，總是在系附狀態下，這個實例被稱為系附到了導致它生成的那個塊上。因此一個過程體的實例，系附到包含對應函數指定式或過程語句的塊實例上。非類、非過程塊實例，系附到它所局部的塊實例。在PSC到達非類塊實例的最終的`end`的時候，PSC返回到緊隨導致這個塊實例生成的語句或表達式的程序點。
- 一個對象，最初是在系附狀態下，並被稱為系附到包含對應對象生成語句的那個塊實例上。一個對象，可以通過執行`detach`過程，進入脫離狀態。通過執行`call`過程，可以使一個脫離狀態的對象重新進入系附狀態，它藉此變為系附到包含這個調用語句的那個塊實例上。通過執行`resume`過程，可以使一個脫離狀態的對象進入恢復狀態。不使用`detach`、`call`或`resume`過程的一個程序執行，是一個簡單的系附狀態的塊的嵌套結構。
- 當PSC通過一個對象的最終`end`，或通過`goto`語句離開它的時候，這個對象進入終止狀態。沒有塊實例系附到一個終止狀態的類對象上。終止狀態的對象，仍作為一個數據項而存在，它可以通過針對這個對象的包括過程和函數特性的這些特性的遠程標定來引用。

每當一個塊實例不復存在，局部於或系附於它的所有塊實例也不復存在。一個對象的動態作用域，因而受限於它的類聲明的作用域。在Simula 67最初標準中曾提到過，語言實現可以使用垃圾回收技術，來進一步縮減一個對象的有效壽命的跨度。一個陣列聲明的動態作用域，可以擴展超出包含這個聲明的塊實例的作用域，因為傳引用調用參數傳送模態適用於陣列。

### 准並行系統

一個準並行系統，由「構件」（component）構成。構件是塊實例組成的嵌套結構，其中標定（identify）這個構件的那個塊實例，叫做「構件頭領」。在每個系統中，構件中總是有一個被稱呼為「主構件」，在Simula 67最初標準中它叫做「主程序」，其他構件叫做「對象構件」。

構件的定序（sequencing），由`detach`、`call`和`resume`過程支配。`detach`過程針對隱式指定的一個對象進行操作，而`call`和`resume`過程顯式指定所操作的對象。

一個準並行系統，由包含局部的類聲明的一個子塊或有前綴塊的任何實例所標定。標定了一個系統的塊實例，叫做「系統頭領」。一個系統的主構件的頭領（head），重合（coincide）於系統頭領。最外層的標定了一個系統的塊實例，被稱為「最外層系統」。

一個系統的主構件的頭領，總是處在系附狀態。一個系統的對象構件的頭領，確切的就是局部於系統頭領的那些脫離狀態的或恢復狀態的對象。在任何時間，在一個系統的構件之中，有確切的一個構件被稱為「生效」（operative）的。不生效的構件，有關聯的「重新激活點」，它標定在這個構件被激活（activate）時，要在它那裡繼續執行的程序點。一個對象構件是生效的，若且唯若這個構件的頭領處在恢復狀態。

稱謂一個塊實例`P`被一個塊實例`X`「動態包圍」，若且唯若存在一個塊實例序列：`(P = Z<sub>0</sub>), Z<sub>1</sub>, ……, Z<sub>n-1</sub>, (Z<sub>n</sub> = X)` `(n >= 0)`，使得對於`i = 1, 2, ……, n`有著：`Z<sub>i-1</sub>`系附到`Z<sub>i</sub>`；或者`Z<sub>i-1</sub>`是一個恢復狀態的對象，它關聯的系統頭領系附到`Z<sub>i</sub>`。終止狀態和脫離狀態的對象，不被除了自身之外的塊實例動態包圍。

將當前包含PSC的塊實例動態包圍起來的塊實例鏈，叫做「運行鏈」。在運行鏈上的塊實例，被稱為是「運行」（operating）的，最外層的塊實例總是運行的。一個構件只要其頭領是運行的它就是運行的。

一個系統如果有一個構件是運行的，它就是運行的；在任何時間，一個系統最多有一個構件是運行的；運行的系統的頭領，可以是不運行的。一個運行的構件總是生效的；如果一個系統的生效構件是不運行的，則這個系統也是不運行的。在不運行的系統中的生效的構件，是當這個系統成為不運行的時候在運行的構件，當這個系統再次成為運行的時候它將仍是運行的。

對於一個不生效的構件`C`，設它的頭領是`X`，如果一個塊實例`P`包含了它的重新激活點，則`P`被`X`動態包圍，並且`P`除了自身之外不動態包圍塊實例。由構件頭領`X`動態包圍的這個塊實例序列，被稱為構件`C`的「重新激活鏈」。除了`X`之外，這個鏈上的所有構件頭領，標定了生效而不運行的構件。在構件`C`成為運行的時候，在它的重新激活鏈上所有塊也成為運行的。

除了系統構件，程序執行還可以包含不屬於特定系統的「獨立對象構件」。任何這種構件的頭領，都是一個脫離狀態的對象，它局部於一個類對象或一個過程主體實例，也就是說不局部於某個系統頭領。根據定義，獨立構件總是不生效的，只能對它執行`call`過程。

### 協程和生成器

准並行系統的`detach`/`resume`機制，是一種協程。在Simula 67最初標準中，沒有恢復狀態，並且沒有規定`call`過程，但`call`過程通常會出現在當時的語言實現中。`detach`/`call`機制，相當於現在稱為生成器的「半協程」，而最初標準中的`resume`過程可理解為`detach`過程與`call`過程的組合。1986年修訂的語言標準，增補定義了`call`過程，新增了恢復狀態，並且重新定義了`resume`過程，它不可再理解為`detach`過程與`call`過程的組合。

准並行系統，被創建於進入包含局部的類聲明的一個子塊或有前綴塊的時候，藉此生成的實例成為這個新系統的頭領。初始時，這個主構件是生效的，並且是這個系統唯一的構件。

建立一個對象構件，要通過針對一個系附狀態的對象，執行`detach`過程，藉此PSC返回到這個對象系附到的那個塊實例。這個對象進入脫離狀態，並成為一個新的不生效的構件的頭領，這個構件的重新激活點被定位到緊後於這個`detach`過程調用。如果這個對象局部於一個系統頭領，則這個新的構件成為這個關聯的系統的成員。

通過`detach`和`call`過程，可以形成「半對稱定序」，這隻涉及到對象構件，而不區分它們是屬於系統的構件還是獨立的構件。

- 對於一個不生效的對象構件，通過針對它的脫離狀態的頭領，執行一個`call`過程，可以重新激活這個構件，藉此PSC移動到它的重新激活點上。這個頭領重新進入系附狀態，並變成系附到包含這個`call`過程調用的塊實例上。這個構件正式的失去了本身（作為構件）的狀態。

通過`detach`和`resume`過程，可以形成「對稱構件定序」，這隻涉及到屬於一個準並行系統的那些構件。對立於半對稱定序中的「調用者」與它的「被調用者」，在對稱構件定序中的「恢復者」與它的「被恢復者」，具有完全的對稱聯繫。

- 對於這個系統的一個不生效的對象構件，通過針對它的脫離狀態的頭領，執行一個`resume`過程，可以重新激活這個構件，藉此PSC移動到它的重新激活點上；這個構件的頭領進入恢復狀態，而這個構件變成生效的。這個系統以前生效的構件變成不生效的，並且它重新激活點被定位到緊後於這個`resume`過程調用；如果這個構件是一個對象構件，則它的頭領進入脫離狀態。
- 對於當前生效的對象構件，通過針它的恢復狀態的頭領，執行一個`detach`過程調用，這個系統的主構件重獲生效的狀態，藉此PSC移動回到主構件的重新激活點上。以前生效的構件變成不生效的，並且它重新激活點被定位到緊後於這個`detach`過程調用。這個構件的頭領進入脫離狀態。

PSC經過一個類對象的最終`end`的效果，除了使這個對象成為終止狀態，而非脫離狀態之外，相同於針對這個對象執行`detach`過程的效果。其結果是它不會得到重新激活點，並且在它已經擁有作為構件頭領的狀態時，失去這種狀態。

## 程式範例

### Hello, World!

Simula 67下的經典Hello, World!範例：

```ObjectPascal
begin
    outtext("Hello, World!");
    outimage;
end;
```

`outtext`過程將字串輸出到緩衝區，而`outimage`過程將緩衝區內容輸出到標準文件，二者都定義在輸出文件類`OutFile`中，而它是文件類`File`的子類。

### 二叉樹

下面例子中的`Tree`類，是二叉樹數據結構實現：

```ObjectPascal
class Tree(val); integer val;
begin
    ref(Tree) left, right;
    procedure insert(x); integer x;
    begin
        if x < val then
        begin
            if left == none then
                left :- new Tree(x)
            else 
                left.insert(x)
        end
        else if right == none then
            right :- new Tree(x)
        else
            right.insert(x);
    end insert;  
    ref(Tree) procedure find(x); integer x;
    begin
        if x = val then
            this Tree
        else if x < val then
            (if left == none then
                none
             else 
                left.find(x))
        else if right == none then
            none
        else
            right.find(x);
    end find;
end Tree;
```

在`find`過程的主體中出現了表達式this Tree，它產生的值所引用的是當前節點。這裡通過函數指定式`X.find(x)`，來調用對象`X`的`find`過程，如果`X.val = x`，則這個函數的結果是到`X`自身的引用值。

### 協程

Simula 67標準通過如下實例來詮釋叫做「准並行系統」的協程機制：

```ObjectPascal
begin comment 系统S1;
    ref(C1) X1;
    class C1;
    begin
        procedure P1;
            detach;
        P1
    end C1;
    ref(C2) X2;
    class C2;
    begin
        procedure P2;
        begin
            detach; 
            ! 可尝试detach或resume(X1);
        end P2;
        begin comment 系统S2;
            ref(C3) X3;
            class C3;
            begin 
                detach;
                P2
            end C3;
            X3 :- new C3;
            resume(X3)
        end S2
    end C2;
    X1 :- new C1;
    X2 :- new C2;
    call(X2); ! 可尝试resume(X2);
end S1;
```

這個例子程序中，有兩個准並行系統`S1`和`S2`。系統`S1`是對應最外層子塊的最外層系統，它包含了兩個類聲明`C1`和`C2`。系統`S2`對應於類`C2`的類主體中的匿名塊，它包含了一個類聲明`C3`。

在PSC進入最外層子塊開始處，產生系統`S1`的系統頭領，到達第28行的系統`S1`主構件的第一個可執行語句，開始生成對象`X1`，進入類`C1`，PSC到達第7行的類主體的第一個可執行語句，調用了類`C1`的特性過程`P1`，進入第6行的過程體的第一個可執行語句，這時的狀況是：

```
['''S1'''] ← (X1) ← (P1) ← <span style="color:FireBrick;">PSC</span>
```

這裡方括號表示系統頭領，圓括號表示其他種類的塊實例，左向箭頭表示系附，使用粗體表示這個塊實例執行了對象生成式。執行第6行的`detach`語句後，對象構件頭領`X1`進入脫離狀態，保存`X1`的重新激活點為第6行`P1`過程體結束，回溯到第28行對象產生式結束，系統`S1`的對象`X1`生成完畢，這時的情況是：

```
[S1] ← <span style="color:FireBrick;">PSC</span>
 |
(X1) ← (P1) ← <X1重新激活点>
```

這裡的豎槓將對象構件頭領列為一個系統的成員。PSC到達系統`S1`主構件第29行，開始生成對象`X2`，進入類`C2`，PSC到達第17行的類主體中匿名塊開始處，進入這個子塊產生系統`S2`的系統頭領，PSC到達第24行的系統`S2`主構件的第一個可執行語句，開始生成對象`X3`，進入類`C3`，PSC到達第20行類主體開始處，這時的情況是：

```
['''S1'''] ← (X2) ← ['''S2'''] ← (X3) ← <span style="color:FireBrick;">PSC</span>
 |
(X1) ← (P1) ← <X1重新激活点>
```

執行第21行類主體的第一個可執行語句`detach`後，對象構件頭領`X3`進入脫離狀態，保存`X3`的重新激活點為第22行，回溯到第24行對象產生式結束，系統`S2`的對象`X3`生成完畢，這時的情況是：

```
['''S1'''] ← (X2) ← [S2] ← <span style="color:FireBrick;">PSC</span>
 |             |
 |            (X3) ← <X3重新激活点>
 |
(X1) ← (P1) ← <X1重新激活点>
```

PSC到達系統`S2`主構件的第25行，執行`resume(X3)`語句後，保存系統`S2`主構件的重新激活點為第26行，對象構件頭領`X3`進入恢復狀態，PSC恢復到第22行的對象`X3`的類主體之中，這時的情況是：

```
['''S1'''] ← (X2) ← [S2] ← <S2重新激活点>
 |             |
 |            (<u>X3</u>) ← <span style="color:FireBrick;">PSC</span>
 |
(X1) ← (P1) ← <X1重新激活点>
```

這裡的下劃線指示這個塊實例處在恢復狀態。執行第22行的類`C2`的特性過程`P2`，到達在第14行的過程體的第一個可執行語句，這時的情況如下，並標記為「狀況A」：

```
                                  <span style="color:DarkCyan;">! 状况A ;</span>
['''S1'''] ← (X2) ← [S2] ← <S2重新激活点>
 |             |
 |            (<u>X3</u>) ← (P2) ← <span style="color:FireBrick;">PSC</span>
 |
(X1) ← (P1) ← <X1重新激活点>
```

執行在第14行`P2`過程體的`detach`語句後，對象構件頭領`X2`進入脫離狀態，保存`X2`的重新激活點為第15行，回溯到第29行對象產生式結束，系統`S1`的對象`X2`生成完畢，這時的情況如下，並標記為「狀況B」：

```
                                  <span style="color:DarkCyan;">！状况B ;</span>
[S1] ← <span style="color:FireBrick;">PSC</span>
 |
(X1) ← (P1) ← <X1重新激活点>
 |
(X2) ← [S2] ← <S2重新激活点>
        |
       (<u>X3</u>) ← (P2) ← <X2重新激活点>
```

注意對象`X3`仍是系統`S2`的生效構件，它並沒有自己的重新激活點。序列`(P2, X3, X2)`是`X2`的重新激活鏈，這裡的`X3`是恢復狀態，而它的系統頭領`S2`系附到了`X2`。

PSC進入系統`S1`主構件第30行，執行`call(X2)`語句後，對象構件頭領`X2`進入系附狀態，PSC恢復為第15行的`P2`過程體之中，這時的情況重現為前面的「狀況A」（`S1`不加粗體）。

如果將系統`S1`主構件中第30行改寫為一個`resume(X2)`，執行後對象構件頭領`X2`進入恢復狀態，保存系統`S1`主構件的重新激活點為第31行，PSC恢復為第15行的`P2`過程體之中，會出現如下情況：

```
[S1] ← <S1重新激活点>
 |
(X1) ← (P1) ← <X1重新激活点>
 |
(<u>X2</u>) ← [S2] ← <S2重新激活点>
        |
       (<u>X3</u>) ← (P2) ← <span style="color:FireBrick;">PSC</span>
```

序列`(P2, X3, X2)`是`X2`的運行鏈。

如果將`P2`過程體中第15行的注釋替換為一個`detach`語句，執行後對象構件頭領`X2`進入脫離狀態，保存`X2`的重新激活點是第16行，PSC恢復到第31行的系統`S1`主構件之中，這時的情況重現為前面的「狀況B」。

如果將`P2`中第15行的注釋替換為一個`resume(X1)`語句，執行後對象構件頭領`X2`進入脫離狀態，對象構件頭領`X1`進入恢復狀態，保存`X2`的重新激活點為第16行，PSC恢復到第6行的`P1`過程體的過程結束，會出現如下情況：

```
[S1] ← <S1重新激活点>
 |
(<u>X1</u>) ← (P1) ← <span style="color:FireBrick;">PSC</span>
 |
(X2) ← [S2] ← <S2重新激活点>
        |
       (<u>X3</u>) ← (P2) ← <X2重新激活点>
```

### 抽象類

下面例子中，定義了一個字形類`Glyph`，它是抽象基礎類，並且有二個實現子類：字符類`Char`和行 (文本文件)類`Line`：

```ObjectPascal
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(cs);
        ref(Glyph) array cs;
    begin
        procedure print;
        begin
            integer i;
            for i := 1 step 1 until upperbound(cs, 1) do
                cs(i).print;
            outimage;
        end;
    end;
    ref(Glyph) rg;
    ref(Glyph) array rgs(1 : 4);
    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;
```

這裡的虛過程量`print`具有過程規定`is procedure print`，它匹配既沒有形式參數也沒有結果值的`print`過程，如果不加以這種過程規定，則它可以匹配具有任何形式參數和任何結果值的`print`過程。在Simula 67中，沒有不可以實例化帶有純虛過程類的特定限制，因而缺乏真正的抽象類的概念，所有類都可以被實例化，但是調用純虛過程會產生運行時間錯誤。

### 模擬器

在下面的離散事件模擬例子中，Sam、Sally和Andy正在逛商店買衣服，他們必須共享一個試衣間。他們每人只能瀏覽商店大約12分鐘，並接著獨占的使用試衣間大約3分鐘，每個行動都服從正態分布，他們的試衣間經歷被模擬如下：

```ObjectPascal
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 & " 要求用试衣间");
            fittingroom1.request;
            report(pname & " 已进入试衣间");
            hold(Normal(3, 1, u));
            fittingroom1.leave;
            report(pname & " 已离开试衣间");
        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`的有前綴塊。模擬器類可在任何塊上使用，而且模擬器甚至可以嵌套，比如在模擬某人做模擬的時候。時間過程`time`、等待過程`wait`、保持過程`hold`和激活過程`ACTIVAT`，定義在`Simulation`類之中。

進程類`Process`是`Simulation`類的嵌套類。激活語句`activate`，只有處在`Simulation`類所包含的類的對象之中，或處在其前綴部份是這種對象的有前綴塊之中，才是有效的。激活語句的作用，被定義為得到調用激活過程`ACTIVAT`的那種效果。

集合類`Simset`是`Simulation`類的前綴類，其中定義了三個嵌套類：表示集合整體的`Head`類，表示集合元素的`Link`類，和二者的前綴類鍊表類`Linkage`。首位過程`first`，定義在`Head`類中；退出過程`out`和在等待過程`wait`中用到的進入過程`into`，定義在`Link`類中。

在試衣間類`FittingRoom`中，為了讓人們排隊等待訪問試衣間，使用了門對象`door`，它是隊列類即`Head`類的一個對象。試衣間類定義了兩個過程：要求過程`request`：如果試衣間中正有人使用，則他必須等待於門隊列之中，即`wait(door)`；當他可以使用試衣間之時，相應的從門隊列中移除自己，即`door.first.out`。離開過程`leave`：如果門隊列中有人等待的話，放行其中第一個人，即`activate door.first`。

個人類`Person`是`Process`類的子類，它的行動是瀏覽商店和在試衣間試衣，使用保持過程`hold`來描述其所用時間，並調用對應的試衣間對象的過程來要求和離開試衣間。正態分布的隨機抽籤過程`normal`，定義在環境類`ENVIRONMENT`中，它的最後的參數，必須是指定一個偽隨機數串流的一個整數。

主程序是進程類`Process`的子類`MAIN_PROGRAM`類的對象。它建立`FittingRoom`類的實例`fittingRoom1`對象，接著建立並激活`Person`類的三個對象，從而將他們三人放置入事件隊列之中，主程序在終止前保持100分鐘的模擬時間。

## 基本資料

- 編程范型：多范型: 指令式, 過程式, 結構化, 物件導向, 並發
- 發行時間：1962年（Simula I）、1967年（Simula 67）
- 設計者：奧利-約翰·達爾
- 開發者：克利斯登·奈加特
- 軟體版本週期：Standard SIMULA
- 軟體版本週期：1986年8月25日
- 類型系統：靜態、名稱式類型系統
- 作用域：詞法
- 實作語言：主要為ALGOL 60（有一些Simscript成份）
- 軟體實現：Portable Simula Revisited, GNU Cim
- 受影響於：ALGOL 60, Simscript
- 施影響於：Smalltalk、CLU、C++、BETA、Object Pascal、Modula-3、Java
- 作業系統：類Unix系統、Windows、z/OS、TOPS-10、MVS