【Simula】
Simula，一种编译式的程式语言，由奥利-约翰·达尔与克利斯登·奈加特，在1960年代于奥斯陆的Norwegian Computing Center，开发出来了Simula I与Simula 67两代。它承继了ALGOL 60作为基础，被认为是第一个物件导向程式设计的程式语言。
Simula 67介入了对象、类、子类（后来惯称为子类继承超类）、虚过程，还有协程、离散事件模拟和特征性的垃圾收集。Simula的影响经常被低估，在C++、Object Pascal、Modula-3、Java和后来的很多编程语言中，都实现了受Simula启发的对象。BETA是Simula的现代后继者。
== 历史 ==
最初Simula设计的离散事件网络示意图
克利斯登·奈加特在1957年开始在自己的电脑上写模拟器。为了发展他的模拟器，他需要更强大的程式语言。1962年1月，奥利-约翰·达尔开始跟他合作。他们受到ALGOL 60的启发，在同年5月，发展出第一个模拟器程式语言，取名为Simula I。此时，克利斯登·奈加特受到Sperry Rand公司邀请，去协助他们开发UNIVAC 1107电脑。UNIVAC软体部门的主管Bob Bemer，力邀克利斯登·奈加特前往International Federation for Information Processing（IFIP）举行的第二次国际会议上，发表了论文「SIMULA－扩展ALGOL到离散事件网路的描述」。
1963年8月，Norwegian Computing Center（NCC）购买到UNIVAC 1107，在UNIVAC的合约同意下，奥利-约翰·达尔在这台电脑上安装以ALGOL 60的编译器来实作的Simula I。1965年1月，Simula I终于可以在UNIVAC 1107上完全的运作。接下来几年，克利斯登·奈加特与奥利-约翰·达尔致力于教授Simula I。Simula I也被移植到Burroughs B5500电脑，以及苏联的URAL-16电脑上。
1965年，东尼·霍尔首次提出“记录类别”（record class）构造的概念，1966年，克利斯登·奈加特与奥利-约翰·达尔通过将Simula I的进程当作由前缀层和主要层二者构成，把它扩展成了具有了记录类别属性的通用进程，他们当时所称“进程”随即被称为“物件”。1967年5月，奈加特和达尔在奥斯陆举办的IFIP工作小组论坛中，发表了关于类别与子类别声明的论文，形成Simula 67的第一份定义文件。
1968年召开的会议，组成了SIMULA标准小组，并发表了第一份官方Simula标准文件「SIMULA 67通用基础语言」。在1960年代后期和1970年代早期，Simula 67主要实现于四个系统之上：Norwegian Computing Center的UNIVAC 1100系列，挪威计算中心的IBM System/360和System/370，奥斯陆大学在Kjeller联合安装的CDC 3000系列，和Swedish National Defence Research Institute（FOA）的DEC TOPS-10。
当前的Simula 67业界标准，是在1986年修订的“标准SIMULA”SIMULA includes most of the ALGOL 60 language. Wherever ALGOL is used in this Standard it relates to the STANDARD ALGOL 60 definition (ISO 1538).|access-date=2022-03-23|archive-date=2022-04-07|archive-url=https://web.archive.org/web/20220407173033/https://portablesimula.github.io/github.io/doc/SimulaStandard.pdf，它在1987年被接受为瑞典国家标准。它有四个主要实现：Simula AS、Lund Simula、GNU Cim和Portable Simula Revisited。
Simula影响了Smalltalk，和后来的面向对象编程语言。Simula经由Smalltalk启发了并发计算的演员模型。C++语言和Java语言的创始人，都认可自己受到了Simula的重要影响cite paper|url=https://www.win.tue.nl/~evink/education/avp/pdf/feel-of-java.pdf|title=The Feel of Java|authors=James Gosling|year=1997|quote=Java is a blue collar language. It’s not PhD thesis material but a language for a job. Java feels very familiar to many different programmers because I had a very strong tendency to prefer things that had been used a lot over things that just sounded like a good idea. …… It has an object-oriented flavor that derives from a number of languages—Simula, C/C++, Objective C, Cedar/Mesa, Modula, and Smalltalk.|journal=|access-date=2022-04-27|archive-date=2022-02-28|archive-url=https://web.archive.org/web/20220228102847/https://www.win.tue.nl/~evink/education/avp/pdf/feel-of-java.pdf。
==特征概念==
Simula 67包含通用算法语言ALGOL 60的多数特征作为自己的子集。它是大小写不敏感的。
===块与过程===
ALGOL 60中最强力的编程构造机制之一，就是块和过程的概念。
====语法====
块是一种语句⑷ Language element. A block is itself a statement, which is a syntactic category of the language. Furthermore, through the procedure mechanism, reference to a block may be dissociated from its defining text.，在Simula 67中，它包括子块和有前缀（prefixed）块。子块就是未加前缀的常规意义上的块，下面分别用字母D表示任意声明，S表示任意语句，L表示可选的任意标签，子块的语法单元采用的形式为：
L: L: ... begin D; D; ... D; S; S; ... S; S end
声明担当定义在程序中用到的量的特定属性，并给它们关联上标识符，这里的量（quantity）包括：简单变量、数组、switch、过程、类和外来声明。块中的每个语句，都可以是完全的复合语句或块。复合语句与块相比没有声明。所有的块，自动地介入一层新的Nomenclature（nomenclature）Identifiers (except those representing labels) occurring within a block and not being declared to this block will be non-local to it, i.e. will represent the same entity inside the block and in the level immediately outside it. A label separated by a colon from a statement, i.e. labelling that statement, behaves as though declared in the head of the smallest embracing block, i.e. the smallest block whose brackets begin and end enclose that statement. In this context a procedure body must be considered as if it were enclosed by begin and end and treated as a block. Since a statement of a block may again itself be a block the concepts local and non-local to a block must be understood recursively. Thus an identifier, which is non-local to a block A, may or may not be non-local to the block B in which A is one statement.|access-date=2022-04-14|archive-date=2007-06-25|archive-url=https://web.archive.org/web/20070625171638/http://www.masswerk.at/algol60/report.htm：
*在这个块内出现的标识符，可以通过合适的声明，而被指定为局部于所论及的这个块。在这个块内侧的这个标识符所表示的实体，不存在于它的外侧。在这个块外侧的这个标识符所表示的任何实体，在这个块内侧是不可见的；在Simula 67中，可通过连接或远程访问使它成为可见的。
*除了表示标签的标识符之外，一个标识符，如果出现在一个块中，而且并非声明于这个块中，则它非局部于这个块，就是说它所表示的这个块内侧实体，与在紧接它外侧的层级中出现的同名实体是同一个实体。因为块中的语句自身可以是一个块，局部和非局部于一个块的概念，必须递归地去理解，就是说非局部于一个块A的一个标识符，可是亦可否地，非局部于A是其中语句的块B。
====语义====
块是一种形式描述或模式，关乎聚集的数据结构和关联的算法以及行动⑴ Duality. A block head and block tail together define an entity which has properties and performs actions. Furthermore the properties may include a data structure as well as associated operators (local procedures). 。一个块实例，可以被认为是它的形式描述的文字复本。一个块的任何内部块，仍然是一个模式，但是在其中出现的非局部标识符，确认了局部于字面上包围的块实例的项目。
*当一个块执行的时候，生成这个块的一个动态实例。在计算机中，一个块实例可以采用一种形式的内存区域，它包含需要的动态块信息，并包括空间来持有局部于这个块的变量的内容⑶ Class of instances. In ALGOL 60 a sharp distinction is made between a block, which is a piece of program text, and a dynamic block instance, which is (a component of) a computing process. An immediate and useful consequence is that a block may be identified with the class of its potential activations. (Strictly speaking a "block" in this context means either the outermost block or a block immediately enclosed by a dynamic block instance.) Through the recursion mechanism of ALGOL 60 different instances of the same block may co-exist in a computing process at the same time.。
*块实例中的局部变量，标识了分配给块实例的内存片段。非局部于内部块的标识符绑定，对这个内部块的任何随后的动态实例，保持有效。
任何声明的变量，在进入这个变量所局部于的那个块之中的时候，都会被初始化。局部于一个块的一个变量，是一个内存设备，其内容依据这个变量的类型，要么是一个值，要么是一个引用。值类型可特征化为直接关联着一个可能值的集合（这个类型的“值范围”）。引用概念，对应于一个名字或一个“指针”的直观想法。它提供了引用值的机制，还反映了机器的寻址可能性。在特定简单情况下，一个引用可以被实现为一个存储的值的内存地址。对于值类型不关联着引用概念。
过程与块相比，它有一个名字，可以在程序的多个不同地方提及，并且在调用时可以给出参数；过程的参数传送模态，除了有传值调用和传名调用，在Simula 67中，又增加了传引用调用。过程和块都不可能建立到它或它内部的引用；对于一个给定块，有可能生成它的一些可以共存和交互的实例，例如递归过程的实例。
*定义函数指示符的值的过程，以类型声明符作为其过程声明的最先符号。此外的真正（proper）过程，在Simula 67中，被称为具有普遍（universal）类型，任何类型都从属（subordinate）于普遍类型。在Simula 67中，过程的参数列表( …  … )，舍弃了其中对ALGOL 60是可选的“) : (”样式的参数Delimiter。
*过程的缺省的传送模态，在Simula 67中，对于值类型的参数是传值调用，对于所有其他类型的参数是传引用调用；故而在过程声明的参数规定中，增加了以name为前导的名字部份，用来指定所述及的参数采用传名调用。在过程主体内传名调用的形式参数的每次出现，都引起对实际参数的一次求值。在Simula 67中，这个求值发生在过程语句的上下文中，就是说不会出现标识符冲突，因为过程主体和它的变量此时是不可见的。
*过程调用的执行，在有参数的情况下要经历如下步骤：建立形式参数块实例；求值对应于传值调用或传引用调用的实际参数，并将其结果赋值给形式参数块实例的对应变量；过程主体被初始化并开始执行。
块实例的想法，在Simula 67中还进一步产生出，一个块作为“对象”的“类”的概念，这些对象每个都是这个块的动态实例，因此符合相同的模式。介入扩展的块概念，要通过类声明和关联的交互机制，比对象引用、远程访问、准并行运算和块串接。
===对象与类===
Simula 67的中心概念是对象，一个对象是一段自备式（self-contained）程序（块实例），它拥有由一个类声明定义的自己的局部数据和行动（action）。操纵对象和相互关联对象的需要，致使语言必须介入列表处理设施。
类是一种过程，它有能力引起在它被调用后仍存活的一个块实例，而这些实例就叫做这个类的对象。类声明定义一个程序（数据和行动）模式，而符合（conforming）这个模式的对象被称为“属于相同的类”。
*对于一个给定对象，形式参数，在由virtual:前导的虚拟部份中规定的量，和声明为局部于类主体（body）的量，叫做这个对象的特性（attribute）。一个特性的声明或规定叫做特性定义。在1986年修订的语言标准中，通过由hidden亦或protected前导的保护规定，可以限制类特性标识符的可见性。
*类声明的形式参数，不适用传名调用。在规定部份中需要对每个形式参数进行规定，这些参数被当作局部于类主体的变量，可以接受如下规定符（specifier）：、array和 array。
*类主体通常是一个块，即使它如语法形式所允许的那样是块以外的一个语句，也表现得如同一个块。一个分裂（split）主体，担当其中符号inner表示一个虚设（dummy）语句的块。
不同于后来的将对象作为记录或结构的扩展的面向对象编程语言，Simula 67的类主体中除了有定义特性的声明，还可以有定义行动的语句。如果有行动定义在一个类声明中，则符合这个模式的行动，可以由属于这个类的所有对象执行。如果在类声明中没有指定行动，则定义了一类纯数据结构。例如：
class Order (number); integer number;
begin integer numberOfUnits, arrivalDate;
real processingTime;
end;
属于特定类的对象，通过对象表达式，用对象生成语句new来生成。例如，想要多少就能生成多少属于这个Order类的一个新对象：
new Order (103);
属于一个对象的行动，可以都在就一个过程而言的一个序列中执行。这些行动，还可以作为一系列的独立子序列或“活动阶段”（active phase）来执行。在一个给定对象的两个活动阶段之间，可以出现任何数目的其他对象的活动阶段。
Simula 67为了将整个程序执行组织为属于对象的活动阶段的一个序列，而包含了其所必需的基本特征。在模拟器类Simulation的声明中，定义了叫做“定序集合”（sequencing set）的一个“时间轴”，它也是充当队列的一个双向列表，还有进程类Process，它给与对象将其活动阶段通过时间轴来组织的一种属性。
===子类===
一个类可以被用作到另一个类声明的“前缀”，从而将前缀所定义的属性，建造入这个新的类声明定义的对象之中。具有前缀C和类标识符D的一个类声明，定义了类C的一个子类D。不同于后来的面向对象编程语言所称谓的派生类扩展基础类，或子类继承超类（父类），在Simula 67中，类D被称为内部（inner）于类C，而类C被称为外部（outer）于类D。
设Cn是具有前缀序列C1, C2, ...... Cn-1的一个类，这里Ck（k = 1,2,...,n）的下标k叫做前缀层级，则属于Cn的对象是一个复合对象，它可以用串接的类声明来正式的描述，串接的过程被认为先于程序执行而发生。
设X是属于Cn的的一个对象。非正式的说，串接机制有如下结果：
*X拥有的特性集合，是在C1, C2, ... , Cn中所定义集合的并集。在Ck（1 ）中定义的特性，被称为定义在前缀层级k。
*X拥有的“运算规则”，构成自来自在这些类的主体的语句，并且它们依据了预先规定的次序。来自Ck的语句，被称为属于X的前缀层级k。
*在X的前缀层级k的语句，能访问在X的等于或外部于k的前缀层级上定义的它的所有特性，但是不能直接访问由于在外部于k层级的冲突定义而导致不可见的特性。这些不可见特性仍然可以访问，例如通过使用过程或this。
*在X的前缀层级k的语句，不能立即访问在X的内部于k的前缀层级上定义的它的那些特性，除非通过虚拟量。
*在前缀层级k的分裂主体中，符号inner，表示X的属于内部于k的前缀层级的运算规则的那些语句，或者在k = n时表示虚设语句。如果C1, ... , Cn-1都没有分裂主体，则在X的运算规则中的那些语句，依据升序前缀层级来排序。
下面是一个简单例子：
Order class BatchOrder;
begin integer batchSize;
real setupTime;
end;
Order class SingleOrder;
begin real setupTime, finishingTime, weight; end;
SingleOrder class Plate;
begin real length, width; end;
属于这些子类如BatchOrder、SingleOrder和Plate的新对象，都有为Order定义的数据，再加上在各种类声明中定义的补充数据。例如，属于类Plate的对象，构成自如下信息片段：Order定义的number、numberOfUnits、arrivalDate和processingTime，SingleOrder定义的setupTime和finishingTime，Plate定义的weight、length和width。
有前缀（prefixed）块的一个实例，是由块前缀生成的对象，与这个主体块的实例，串接而成一个复合对象，其串接定义类似于类的串接规则。块前缀的类的形式参数，按块前缀的实际参数所示初始化。对有前缀块有两个限制：在其中通过使用this来引用到类自身的类，是非法的块前缀。一个块前缀的类标识符所提及的类，必须局部于最小的包围这个有前缀块的块。
===引用===
当属于各种类的很多对象，作为同一个程序的各部份而共存的时候，需要能够对个体对象指定名字，为此介入了叫做“引用”的新的基本类型；还要能相互关联对象，比如通过二叉树和各种其他类型的列表结构，为此将叫做“集合”的循环双向链表，作为一个系统类Simset介入为语言的一部份。
在Simula 67中有两种引用类型，对象引用类型和文本引用。对于一个类对象（类实例），有一个关联的唯一的“对象引用”确认这个对象，并且对于任何类C，都有一个关联的对象引用类型ref (C)。这种类型的量，被称为由类C限定；它的值，要么是一个对象，要么是表示“没有对象”特殊值none。
限定（qualification）将值的范围，限制至包括在限定类中的这些类的对象。不管何种限定，值的范围都包括值none。一个对象引用的限定，是一个类标识符，它因此服从声明的作用域和可见性规则。限定关联于所提及的类声明局部于的那个块的一个实例。这蕴涵着特定的关于限定有效性的检查，不能单独在程序正文的基础上进行，因此这种测试必须在程序执行期间完成。
引用是有限定的，蕴涵着一个给定引用所提及的对象，只能属于这个限定中提到的类，或属于这个限定类的子类。如果一个对象引用类型的限定，是另一个对象引用类型的限定类的子类，则前者被称为从属于后者。例如：
ref(Order) next, previous;
对象表达式是获得对一个对象的引用的一种规则。对象表达式的值，是被引用的对象或none。制作一个引用来提及一个特定对象的运算符，写为:-并读作“指称”（denote），它指示将一个引用，赋值给在引用赋值左侧的、引用类型变量或引用类型过程标识符。例如：
next :- new Oreder(101);
previous :- next;
next :- new Plate(50);
而运算符:=读作“成为”（become），指示将一个值，赋值给在值赋值左侧的、值类型变量或值类型过程标识符，或者将一个文本值，赋值给在左侧者所引用的文本帧（frame）。
===对象表达式===
对象表达式，具有类型ref(限定)。对象表达式的限定规则包括：对象生成式、局部对象或限定对象，分别由跟随符号new、this或qua的标识符的类来限定。
对象生成式（generator），涉及到属于所确认的类的对象的生成和执行。这个对象是相应的（串接成的）类的一个新实例。对象生成式的求值构成自如下行动：
#生成这个对象，并且这个对象生成式如果有实际参数，则求值它们，将得到的这些值And/or引用传送给形式参数。
#控制经过这个对象最初的begin进入其中，借此它变成在“系附”状态下运行。在生成的对象执行了detach基本过程，或者经过这个对象最终的end退出的两种情况之一时，对象生成式的求值完成。
求值之后的对象的状态，要么是“脱离”要么是“终止”，详见后面的块实例章节。
"java"，如果用在类C或C的任何子类的类主体中，或用在其块限定为类C或C的一个子类的连接块中，则这个对象表达式是有效的。在一个给定的上下文中，一个局部对象的值，是一个对象或连接到一个对象，它是这个对象表达式在其中有效的、最小的字面上包围的块实例；如果没有这样的块，则这个对象表达式在这个上下文中是非法的。对于一个过程或类主体的实例（上下文），“字面上包围”意为包含它的声明。如此定义的内涵参见示例章节中的二叉树实例。
设X表示一个简单的引用表达式，而C和D是类标识符，使得类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的值的否定。
===远程访问===
一个对象的一个特定特性，由下列三项信息来完全确认（identify）：
#这个对象。
#外部于或等于这个对象的类的一个类。
#在这个类中或在属于它的前缀序列的任何类中定义的一个特性标识符。
对于任何特性确认，第2项类信息都是在字面上定义的，从而形成静态绑定。属于其他对象的特性，可以要么通过“远程标识符”（“点表示法”），要么通过“连接”（connection）机制，从其外侧“远程访问”来引用和使用。远程标识符的形式为：简单对象表示式.特性标识符，它可用作简单变量、数组变量、函数指示符（designator）和过程语句中的标识符，这种点表示法给出对信息的单独片段的访问，例如：
if next.number >= previous.number then ......;
它将名为next的类Order的对象的特性number，比较于名为previous的类Order的对象的特性number。
“组访问”可通过“连接语句”来完成，连接机制的用途，是为在连接块中的特定识别，提供上述第1项对象信息和第2项类信息的隐式定义。例如：
inspect next when Plate do begin ...... end;
inspect new Plate(50) do begin ...... end;
在检视（inspection）块的begin和end之间的语句中，可以直接提及next所引用的在Plate中包含的所有信息片段。do后面的语句，如果是块以外的一个语句，它表现得也如同一个块。连接语句进而表现得如同被叫做“连接块”的第二个虚构（fictitious）的块所包围。
设对象表达式求值为X，在连接块执行期间，称对象X为“被连接上”了。连接块有一个关联的“块限定”，它是连接块的前导类标识符，而对于没有when子句的情况，它是连接块的前导对象表达式的限定。
===虚过程===
虚拟（virtual）量，有双重用途：
*允许在一个对象的一个前缀层级上，访问在内部前缀层级上声明的特性。
*允许在一个前缀层级上的特性重新定义，在外部前缀层级上有效。
在类声明的虚拟部份中，可以接受如下规定符：label、switch、procedure和 procedure。不同于一般的特性确认，虚过程形成半动态绑定，在某种意义上类似于ALGOL 60的传名调用机制。
一个对象的一个虚拟量，要么是“无匹配的”的，要么被确认为具有一个“匹配”特性，它是在这个虚拟量的前缀层级上或在内部前缀层级上声明的，其标识符Coincidence（coincide）于虚拟量的标识符的一个特性。匹配特性必须与虚拟特性有相同的种类。在一个给定前缀层级上的匹配量的类型，必须重合或从属于这个虚拟规定的类型，和在任何外部前缀层级上声明的任何匹配量的类型。
在1986年修订的语言标准中，虚过程量可选的可使用procedure  方式来指定，即凭借它的类型，并且如果它有形式参数，则还凭借它们的类型、种类和传送模态。含有过程规定is 的虚过程量，只能由有相同类型的过程来匹配，并它与这个过程规定具有相同的过程头部。
例如，下面实现散列表的Hashing类，声明了虚过程hash并随即实现了它，又定义了要用到散列过程hash的查找过程lookup:
class Hashing (n); integer n;
virtual: integer procedure hash;
begin
integer procedure hash(t); text t;
begin ...... end hash;
text array table (0:n-1); integer entries;
integer procedure lookup (t,old);
name old; Boolean old; text t;
begin ...... end lookup;
end Hashing;
Hashing class ALGOL_hash;
begin
integer procedure hash(T); text T;
begin ...... end hash;
end ALGOL_hash;
Hashing(64) begin
integer procedure hash(T); text T;
begin ...... end hash;
......
end
子类ALGOL_hash和有前缀块，用自己的hash过程实现替代了其前缀中的实现。在子类的类主体和有前缀块的主要块中，能获得到过程lookup，而它用到的过程hash是这里提供的替代实现。
===作用域和可见性===
一个标识符定义及其关联的标识符，在其作用域与可见性之间需要做出区别。
*一个标识符定义的作用域，是它在其中可能有作用的那一部份程序正文。相同的标识符，可以定义在程序的很多地方，因此可以关联于不同的量。这种相同的标识符的作用域，因而可能重叠，例如当一个标识符在内部块中被重新声明的情况下。
*一个标识符定义，这个标识符在程序的一个给定点上，如果能够涉及到所论及声明的量，则这个定义被称为在这个点上是可见的。在给定标识符于此可见的程序正文的一个特定点上，最多只能有一个定义关联于这个标识符，例如在上述重新声明的情况下，在它们作用域的并集内任何给定点上，只有一个定义是可见的。
一个标识符定义的局部块，是在字面上最近的包围块，即子块、前缀块、过程主体或类主体，还包括围绕for语句的受控语句、过程声明或类声明的虚构的块、连接块等等。这个标识符和它的定义，被称为局部于这个块。
标识符定义，只在它们的作用域内是可见的。一个特定定义的可见性，在它的作用域内可以受到下列限制：
*具有相同标识符的一个标识符定义，即这个标识符的重新定义，出现在以前的定义的局部块所包围的某个构造内。在它们共同的作用域内，只有最内部的重新定义是可见的。
*一个重新定义，出现在类的某个内部前缀层级。
*远程访问，可以导致某些标识符定义在检视块或点表示法内变成不可见的。
*使用this或qua，可以导致一个或多个重新定义被临时停止。
*这个定义所局部于的类声明的保护部份。
一个标识符的重新定义，不允许出现在它的局部块的头部，这禁止了在同一个块中出现相同标识符的两个定义。
具有形式参数的过程，在特定意义上表现得如同有一个虚构的块包围着过程主体。形式参数因而对应于声明为局部于这个虚构的块的变量。因此，一个过程的形式参数，可以在属于这个过程声明的过程主体的头部内被重新定义。这种重新定义，将这个形式参数的可见性，有效的限制至与它有关的value部份、name部份和规定部份。因此这种参数的唯一作用，是来自其求值可能有的副作用。
除非在它的定义之内，一个标识符的所有出现，都具有动态方面。这样的一个标识符，不仅涉及它的静态定义，还涉及到从这个定义所局域于的那个声明生成的某个对象。例如，在一个过程或类声明之内出现的一个形式参数标识符，参照这个过程或类的某个实例化的对象。
===块实例===
一个程序执行的组成部份，都是块即子块、有前缀块、连接块和类主体的动态实例。一个块实例，被称为“局部于”直接包含它的描述文本的那个块实例。例如一个给定类的实例，局部于包含这个类声明的块实例。最外层块的实例不局部于块实例。
在任何时间，“程序顺序控制”（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）构成。组件是块实例组成的嵌套结构，其中标识这个组件的一个块实例，叫做“组件头领”。
在每个系统中，组件中有一个被称为“主干组件”，在Simula 67最初标准中叫做“主程序”，其他组件叫做“对象组件”。一个系统的主干组件的头领（head），Coincidence（coincide）于系统头领，它总是处在系附状态。一个系统的对象组件的头领，确切的就是局部于系统头领的那些脱离状态的或恢复状态的对象。
*在任何时间，在一个系统的组件之中，有确切的一个组件被称为“生效”（operative）的。不生效的组件，有关联的“重新激活点”，它标识在这个组件被激活（activate）时，要在它那里继续执行的程序点。一个对象组件是生效的，当且仅当这个组件的头领处在恢复状态。
*除了系统组件，程序执行还可以包含不属于特定系统的“独立对象组件”。任何这种组件的头领，都是一个脱离状态的对象，它局部于一个类对象或过程主体的一个实例，也就是说不局部于系统头领（子块或有前缀块的实例）。根据定义，独立组件总是不生效的。
称谓一个块实例X被一个块实例Y“动态包围”，当且仅当存在一个块实例序列：(X = Z0) → Z1 → .... → Zn-1 → (Zn = Y) (n>=0)，使得对于i= 1,2,...,n有着：Zi-1系附到Zi；或者Zi-1是一个恢复状态的对象，它关联的系统头领系附到Zi（而这个系统头领自身不在这个序列中）。终止状态和脱离状态的对象，不被除了自身之外的块实例动态包围。
*将当前包含PSC的块实例动态包围起来的块实例链，叫做“运行链”。在运行链上的块实例，被称为“运行”（operating）的，最外层的块实例总是运行的。一个系统如果有一个组件是运行的，它就是运行的；在任何时间，一个系统最多有一个组件是运行的；运行的系统的头领，可以是不运行的（不在运行链上）。一个运行的组件 ，总是生效的；如果一个系统的生效组件是不运行的，则这个系统也是不运行的。在不运行的系统中的生效的组件，是当这个系统成为不运行的时候在运行的组件，当这个系统再次成为运行的时候它将仍是运行的。
*对于一个不生效的组件C，如果一个块实例P包含了它的重新激活点（而C的重新激活点关联于C的头领），则P被C的头领动态包围，并且P除了自身之外不动态包围块实例。由P与C的头领X“动态合围”的块实例序列(P = Z0) → Z1 → .... → Zn-1 → (Zn = X) (n>=0)，被称谓为C的“重新激活链”。除了C的头领X（脱离状态的对象）之外，这个链上的所有组件头领（恢复状态的对象），标识了生效而不运行的组件。在C成为运行的时候，在它的重新激活链上所有块也成为运行的。
组件的定序（sequencing），由detach、call和resume支配。detach针对隐式指定的一个对象进行操作，而call和resume显式指定所操作的对象。
===定序===
准并行系统的detach/resume机制，是一种协程The basic coroutine call "resume ()" would make control leave the active object, leaving behind a reactivation point at the end of the resume statement, and enter the referenced object at its reactivation point. |access-date=2022-03-14 |archive-date=2022-01-20 |archive-url=https://web.archive.org/web/20220120192521/https://phobos.ramapo.edu/~ldant/datascope/simula%20history.pdf 。在Simula 67最初标准中，没有恢复状态，并且没有规定call，但call通常会出现在当时的语言实现中。detach/call机制，相当于现在称为生成器的“半协程”，而最初标准中的resume可理解为detach与call的组合Thus a main program may establish a coroutine relationship with an object that it has generated, using the call/detach mechanism instead of the more symmetric resume/resume mechanism. In this case, the generated object remains subordinate to the main program, and for this reason is sometimes known as a Semicoroutine. ……Let X and Y be objects, generated by a "master program" M. Assume that M issues a call (X), thereby invoking an "active phase" of X, terminated by a detach operation in X; and then issues a call (Y), and so forth. In this way M may act as a "supervisor" sequencing a pattern of active phases of X, Y, and other objects. Each object is a "slave", which responds with an active phase each time it is called for, whereas M has the responsibility to define the large scale pattern of the entire computation. Alternatively the decision making may be "decentralised", allowing an object itself to determine its dynamic successor by a resume operation. The operation resume (Y), executed by X, combines an exit out of X (by detach) and a subsequent call (Y), thereby bypassing M. Obligation to return to M is transferred to Y.。1986年修订的语言标准，增补定义了call，新增了恢复状态，并且重新定义了resume，它不可再理解为detach与call的组合。
准并行系统，被创建于进入包含局部的类声明的一个子块或有前缀块的时候，借此生成的实例成为这个新系统的头领。初始时，这个主干组件是生效的，并且是这个系统唯一的组件。
建立一个对象组件，要通过针对一个系附状态的对象，执行detach，借此PSC返回到这个对象系附到的那个块实例。这个对象进入脱离状态，并成为一个新的不生效的组件的头领，这个组件的重新激活点被定位到紧后于这个detach。如果这个对象局部于一个系统头领，则这个新的组件成为这个关联的系统的成员。
通过detach和call，可以形成“半对称定序”，这只涉及到对象组件，而不区分它们是属于系统的组件还是独立组件。
*对于一个不生效的对象组件，通过针对它的脱离状态的头领，执行一个call，可以重新激活这个组件，借此PSC移动到它的重新激活点上。这个头领重新进入系附状态，并变成系附到包含这个call的块实例上。这个组件正式的失去了本身（作为组件）的状态。
通过detach和resume，可以形成“对称组件定序”，这只涉及到属于一个准并行系统的那些组件。对立于半对称定序中的“调用者”与它的“被调用者”，在对称组件定序中的“恢复者”与它的“被恢复者”，具有完全的对称联系。
*对于这个系统的一个不生效的对象组件，通过针对它的脱离状态的头领，执行一个resume，可以重新激活这个组件，借此PSC移动到它的重新激活点上；这个组件的头领进入恢复状态，而这个组件变成生效的。这个系统以前生效的组件变成不生效的，并且它重新激活点被定位到紧后于这个resume；如果这个组件是一个对象组件，则它的头领进入脱离状态。
*对于当前生效的对象组件，通过针它的恢复状态的头领，执行一个detach，这个系统的主干组件重获生效的状态，借此PSC移动回到主干组件的重新激活点上。以前生效的组件变成不生效的，并且它重新激活点被定位到紧后于这个detach。这个组件的头领进入脱离状态。
PSC经过一个类对象的最终end的效果，除了使这个对象成为终止状态，而非脱离状态之外，相同于针对这个对象执行detach的效果。其结果是它不会得到重新激活点，并且在它已经拥有作为组件头领的状态时，失去这种状态。
== 程式范例 ==
=== 最小程序 ===
按源代码大小来衡量的话，空计算机文件是Simula 67中最小的程序，它只包含一个东西，就是虚设语句。但是，最小的程序更经常表示为空块：
Begin
End;
它开始执行并立即终止。语言缺乏来自程序的任何返回值。
=== Hello, World! ===
Simula 67的经典Hello, World!范例：
Begin
OutText ("Hello, World!");
OutImage;
End;
OutText过程将字符串输出到缓冲区，而OutImage过程将缓冲区内容输出到标准文件，二者都定义在输出文件类OutFile中，而它是文件类File的子类。
===传名调用===
使用传名调用可以轻易实现Jensen's Device，一个简单的例子是合计函数，它可以实现如下：
Real Procedure Sigma (k, m, n, u);
Name k, u;
Integer k, m, n; Real u;
Begin
Real s;
k:= m;
While k
这个例子对受控变量k和表达式u使用了传名调用。这允许将受控变量k用于表达式u之中。由于Simula 67的for循环中受控变量，不能是传名调用的形式参数或过程标识符，故而上述代码使用了while循环。
公式可以实现为如下：
Z:= Sigma (i, 1, 100, 1 / (i + a) ** 2);
===协程===
Simula 67标准通过如下实例来诠释叫做“准并行系统”的协程机制：
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 system 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的系统头领，到达第23行的系统S1主干组件的第一个可执行语句，开始生成对象X1，进入类C1，PSC到达第5行的类主体的第一个可执行语句，调用了类C1的特性过程P1，进入第4行的过程体的第一个可执行语句，这时的状况是：
S1 ← (X1) ← (P1) ← PSC
这里方括号表示系统头领，圆括号表示其他块实例，左向箭头表示系附。执行第4行的detach语句后，保存对象X1的重新激活点为第4行过程结束，回溯到第23行结束，系统S1的对象X1生成完毕，这时的情况是：
S1 ← PSC
(X1) ← (P1) ← X1重新激活点
这里的竖杠连接一个系统的组件头领。PSC到达系统S1主干组件第24行，开始生成对象X2，进入类C2，PSC到达第13行的类主体的第一个可执行语句，进入这个子块产生系统S2的系统头领，PSC到达第19行的系统S2主干组件的第一个可执行语句，开始生成对象X3，进入类C3，PSC到达第16行类主体的第一个可执行语句，这时的情况是：
S1 ← (X2) ← S2 ← (X3) ← PSC
(X1) ← (P1) ← X1重新激活点
执行第16行类主体内的detach语句后，保存对象X3的重新激活点为第17行，回溯到第19行结束，系统S2的对象X3生成完毕，这时的情况是：
S1 ← (X2) ← S2 ← PSC
(X3) ← X3重新激活点
(X1) ← (P1) ← X1重新激活点
PSC到达系统S2主干组件的第20行，执行resume(X3)语句后，保存系统S2主干组件的重新激活点为第21行，PSC恢复到第17行的对象X3的类主体之中，这时的情况是：
S1 ← (X2) ← S2 ← S2重新激活点
(X3) ← PSC
(X1) ← (P1) ← X1重新激活点
执行第17行的类C2的特性过程P2，到达在第10行的过程体的第一个可执行语句，这时的情况如下，并标记为“状况A”：
状况A
S1 ← (X2) ← S2 ← S2重新激活点
(X3) ← (P2) ← PSC
(X1) ← (P1) ← X1重新激活点
执行在第10行P2过程体的detach语句后，保存对象X2的重新激活点为第11行，回溯到第24行结束，系统S1的对象X2生成完毕，这时的情况如下，并标记为“状况B”：
！状况B
S1 ← PSC
(X1) ← (P1) ← X1重新激活点
(X2) ← S2 ← S2重新激活点
(X3) ← (P2) ← X2重新激活点
注意对象X3仍是系统S2的生效组件，它并没有自己的重新激活点。PSC进入系统S1主干组件第25行，执行call(X2)后，PSC恢复为第11行的P2过程体之中，这时的情况重现为前面的“状况A”。如果将第25行改写为一个resume(X2)语句，执行后保存系统S1主干组件的重新激活点为第26行，PSC恢复为第11行的P2过程体之中，会出现如下情况：
S1 ← S1重新激活点
(X1) ← (P1) ← X1重新激活点
(X2) ← S2 ← S2重新激活点
(X3) ← (P2) ← PSC
如果将第11行的注释替换为一个detach语句，执行后保存对象X2的重新激活点是第12行，PSC恢复到第26行的系统S1主干组件之中，这时的情况重现为前面的“状况B”。如果将第11行的注释替换为一个resume(X1)语句，执行后保存对象X2的重新激活点为第12行，PSC恢复到第4行的P1过程体的过程结束，会出现如下情况：
S1 ← S1重新激活点
(X1) ← (P1) ← PSC
(X2) ← S2 ← S2重新激活点
(X3) ← (P2) ← X2重新激活点
===二叉树===
下面例子中的Tree类，是二叉树数据结构实现：
class Tree (val); integer val;
begin
ref (Tree) left, right;
procedure insert (x); integer x;
begin
if x
在find的过程体中出现了表达式"java"，它意图产生的值是到当前节点的引用，就是说这个节点拥有find特性的“这个”特定实例。例如，如果通过函数指示符X.find (x)，来调用X的find过程，并且X.val = x，则这个函数的结果是X自身的引用值。
=== 抽象类 ===
下面例子中，定义了一个抽象基础类：字形类Glyph，它有二个实现子类：字符类Char和行类Line：
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);
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分钟，每个活动都服从正态分布，他们的试衣间经历被模拟如下：
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的有前缀块。模拟器类可在任何块上使用，而且模拟器甚至可以嵌套，比如在模拟某人做模拟的时候。激活语句Activate，只在包括在Simulation中的类的对象之中，或在其前缀部份是这种对象的有前缀块之中，才是有效的。激活语句的作用，被定义为调用ACTIVAT过程所得到效果。ACTIVAT过程和等待过程Wait，定义在进程类Process中，而Process类是Simulation类的内部类。
表示集合整体的Head类，和表示集合元素的Link类，都是集合类Simset的内部类；而Simset类，是Simulation类声明中的前缀。首位过程First，定义在Head类中；退出过程Out和在Wait过程中用到的进入过程Into，定义在Link类中。
对象fittingRoom1是试衣间类FittingRoom的实例，为了让人们排队等待访问试衣间，它使用了一个队列实例即门对象door。当某人要求用试衣间的时候，如果它正在由他人使用，则必须等待于它的门队列之中，即Wait (door)，当经过排队后得以使用试衣间的时候，相应的从它的门队列中移除自己，即door.First.Out。当某人离开试衣间的时候，在它的门队列中有人的情况下释放出第一个人，即Activate door.First。
个人类Person是Process类的子类，而它的活动，即用来浏览商店的时间，和在试衣间度过的时间，使用Process类的保持过程Hold来描述，并调用在试衣间对象中的过程，来要求和离开试衣间。正态分布的随机抽签过程Normal，定义在ENVIRONMENT类中，它的最后的参数，必须是指定一个伪随机数串流的一个整数。主程序建立所有对象，并激活所有Person对象，从而将他们放置入事件队列之中。主程序在程序终止前，保持100分钟的模拟时间。