ALGOL 60

ALGOL 60（源自的缩写），是在1960年创建的称为“算法语言”的一种程式语言。它是以后来称为ALGOL 58的“国际代数语言”为基础，其官方后继者是ALGOL 68，它们一起并称为ALGOL语言家族。Algol 60引进了许多新的概念如：块、词法作用域、递归、巴科斯-诺尔范式（BNF），它在程式语言设计和发展演化中有著巨大的影响力。
历史.
1960年，在巴黎举行的讨论会上，来自欧洲的诺尔、、、、范·韦恩加登、、，与来自美国的佩利、巴科斯、麦卡锡、、和J. Green，共同发表了《算法语言ALGOL 60报告》。戴克斯特拉实现了ALGOL 60语言的第一个编译器。在1962年罗马会议上，ALGOL 60报告得到了修订，并于1963年出版。
ALGOL 60是程序设计语言发展史上的一个里程碑，影响到其后的Simula、CPL、ALGOL W、ISWIM、BCPL、B、Pascal、C、Scheme等。它标志着程序设计语言成为一门独立的科学学科，并为后来软件自动化及软件可靠性的发展奠定了基础。
标准.
ALGOL 60以及COBOL，是最初的企图标准化的程式语言。ALGOL60曾经提出两项ISO标准：
实现时间线.
ALGOL 60在语言报告中没有I/O设施；诸多实现以少有相互兼容的方式定义了自己的设施。迄今ALGOL 60已经有了至少70个扩充、扩展、派生和子语言。
词法.
简单符号.
除了字母和数字之外，ALGOL定义了运算符：
和分界符（delimiter）:
在ISO 1672标准中，用codice_1表示codice_2（U+2254），用codice_3表示codice_4；用codice_5表示codice_6，用codice_7或codice_8表示codice_9；用codice_10表示codice_11，用codice_12表示codice_13，用codice_14表示codice_15；用codice_16表示科学记数法中指数运算的底数codice_17所用符号codice_18（U+23E8），用codice_19表示codice_20，并且用codice_21表示codice_22，用空格codice_23表示在字符串中的空白字符codice_24（U+2423）。
关键字.
ALGOL 60有24个关键字：
ALGOL 60不采用保留字的概念，但包括了标准函数名字作为限制标识符：
关键字写法依赖于实现，常见的是一种叫做（stropping）的方法，即将关键字大写并包围在两个codice_25之间，例如将codice_26写为codice_27。在ISO 1672标准中关键字还包括对特定符号的某种文字转写：
语法和语义.
ALGOL 60的语法定义采用了包容左递归的巴科斯范式（BNF）。用以形成语句的关键字，在ALGOL 60中被归入顺序运算符（operator）和分隔符（separator）之中。
量与变量.
在ALGOL 60中，量（quantity）被区分出如下种类的语法单元（unit）：简单变量、数组、标签、接转（codice_28）和过程。及其构成者和数组标识符，被称为拥有值。各种“类型”即codice_29、codice_30和codice_31，指称（denote）值的基本的属性。
变量是对一个单一值的指名（）。加下标（subscripted）变量指定（designate）多维数组的元素的值，这里将数组元素称为“元件”（component）。函数指定式（designator）定义单一的数量值或逻辑值，它们是将给定的由过程声明定义的规则集合，应用于固定的实际参数集合的结果。现在通常将变量定义为抽象的存储位置，它含有了被称为一个值的某种已知或未知的信息量，并且配对了关联的名字。
表达式.
在描述算法处理的程序中，主要构成者是算术表达式和布尔表达式，以及用在codice_26语句中的得到语句标签的指定（designational）表达式。除了特定的分界符之外，表达式的构成者包括：逻辑值、数值、变量、函数指定式，和基本的算术、关系、逻辑运算符及顺序运算符。
由于算术表达式、布尔表达式和指定表达式的语法定义，都在其构成者中包容了自身形式，并且变量和函数指定式的语法定义都包容表达式，表达式的定义必须是递归的。
在左圆括号和匹配的右圆括号之间的表达式（parenthesized expression）自行求值，而这个值被用于后续的计算之中；因此通过适当的圆括号放置，总是可以在表达式之内安排出想要的运算次序。
块与作用域.
在ALGOL 60中，“复合语句”被定义为：包围在语句括号codice_33和codice_34之间的成序列的语句，形成一个复合语句。块被定义为：成序列的声明，跟随着成序列的语句，并被包围在codice_33和codice_34之间，形成一个块；所有声明以这种方式出现在一个块中，并只在这个块中有效。
一个程序是特定的一个块或复合语句，它不包含在另一个语句之中，并且不使用不包含在它之中的其他语句。在1976年的修改版语言报告中，程序只能包含在叫做“环境块”的假定总是存在的一个虚构块之中，除了可以使用在环境块中声明的过程标识符和函数指定符之外，不使用不包含在它之中的其他语句。
声明负担定义在程序中用到的量的特定属性，并给它们关联上标识符。声明包括：类型声明、数组声明、接转声明（用标签组成codice_28列表）和过程声明。量的作用域是语句和表达式的集合，在其中关联于这个量的标识符的声明是有效的。所有的块，自动地介入名称目录（nomenclature）的一个新的层级：
这动态的蕴涵了：在通过codice_33进入一个块的时候，所有为这个块声明的标识符，假定了这个给定声明的所蕴涵的（significance）；如果这些标识符已经被外面的其他声明所定义，这时它们被给予新的意义；在另一方面，并非为这个块声明的标识符，保持它们旧有的含义。在通过codice_34或codice_26语句退出一个块的时候，为这个块声明的标识符失去它们的局部意义。声明可以标记上额外的声明符codice_44，其效果为：在重新进入一个块的时候，自有的这些量的值将不变更而仍是上次退出时的值，然而声明的没有标记上codice_44的变量的值是未定义的。
语句.
ALGOL 60将语句分为三类：无条件语句、条件语句和codice_46循环语句。由于成序列的语句，可以被组织成复合语句和块，语句的定义必需是递归的。
赋值语句担负将表达式的值，指派（assign）到一个或多个变量，或者在定义函数指定式的值的过程主体中指派到过程标识符；在作为指派目标的加下标变量中出现的任何下标表达式，先于得出所指派之值的表达式，而按从左至右顺序求值。
过程语句负担实施调用一个过程主体的执行。codice_26语句结合了无条件跳转和计算跳转二者，codice_26语句不能从块外跳转到块内的标签，但可以跳转进入复合语句。空无的虚设（dummy）语句不执行任何运算。
ALGOL 60介入了子句概念：codice_49子句和codice_46子句，即codice_51和codice_52；并且算术表达式、布尔表达式和指定表达式中，可以有括号包围着的条件表达式，即codice_53或codice_54。
条件语句包括三种形式：codice_49语句，即codice_56；codice_57形式；和codice_56形式。ALGOL 60在语法上避免了codice_59形式的歧义，它等价于codice_60，但仍然介入了codice_61形式的悬摆else歧义。
过程.
在ALGOL 60中，过程声明担负定义过程标识符所关联的过程，其主要构成者是过程主体，它是一个语句或一段代码。过程主体总是表现得如同一个块，不管它是否有着块的形式；故而标记了在过程主体内语句或者主体自身的标签的作用域，永远不能延伸超出这个过程主体。
过程主体关联着一个头部，它规定了出现在过程主体内的代表形式参数的特定标识符。在过程的参数列表codice_62中，有可选的“codice_63”样式的参数。过程的参数传递有两种求值策略：传名调用和传值调用。在过程声明中，通过对形式参数名字前导codice_64来指定传值调用，缺省为传名调用。在过程主体是用ALGOL语言写的语句的情况下，过程语句执行它的效果，等价于在程序上进行下列操作的效果：
对于定义函数指定式的值的过程声明，在其过程主体中，必须出现具有过程标识符在其左侧部份中的一个或多个赋值语句，其中至少有一个必须被执行；并且这个过程标识符所关联的类型，必须通过以类型声明符作为其过程声明的最先符号的样貌来声明。最后那个这样指派的值，被用来继续此函数指定式在其中出现的表达式的求值。在这个过程主体中，这个过程标识符的不在赋值语句左侧部份中的任何出现，指示了这个过程的激活（activation）。
两个传名调用形式参数，其对应的实际参数之间可能存在依赖关系，比如一个是整数变量codice_65，而另一个是加下标变量codice_66，从而导致后者形式参数也依赖于前者形式参数，利用传名调用和这种副作用可以实现；它典型的用于定义对应于formula_1的级数过程codice_67，它有两个传名调用的形式参数：索引变量codice_68和通项（general）表达式codice_69。
对于交换两个参数的值的codice_70过程，其过程主体定义为：codice_71，这种依赖性副作用会导致可能出现异常行为，由于名字替代机制相当于宏展开（expansion），过程语句codice_72中加下标变量codice_66的下标codice_65未经求值，对应的过程主体就转换成为：codice_75。1964年制定了《SUBSET ALGOL 60报告》，在这个子集语言中对“完全的名字概念”（full name-concept）增加了一项限制：在名字替代（传名调用）中，实际参数只能是一个标识符或字符串。
众所周知的传名调用实现采用了机制。Donald Knuth设计了“男人抑或男孩测试”，来区分编译器是否正确的实现了“递归和非局部引用”，在这个测试中局部定义的函数将自身用作其所调用函数的传名调用的实际参数。
例子.
下面是语言报告中过程声明的一个例子：
procedure Absmax(a) Size:(n, m) Re​sult:(y) Subscripts:(i, k);
 value n, m; array a; integer n, m, i, k; real y;
 comment 矩阵a，其大小为n乘m，其绝对值最大的元素
 被传送到y，并且这个元素的下标是i和k。;
begin
 integer p, q;
 y := 0; i := k := 1;
 for p := 1 step 1 until n do
 for q := 1 step 1 until m do
 if abs(a[p, q]) &gt; y then
 begin
 y := abs(a[p, q]);
 i := p; k := q
 end
end Absmax
在1976年修改版语言报告的环境块中，定义了输入输出过程：codice_76、codice_77、codice_78、codice_79、codice_80、codice_81、codice_82、codice_83和codice_84，下面以其中的codice_82作为演示例子：
procedure outinteger(channel, int);
 value channel, int;
 integer channel, int;
 comment 将表示int的值的那些字符，
 加上尾随的终结符传递到channel。;
begin
 procedure digits(int);
 value int; integer int;
 begin
 integer j;
 comment 使用递归从右至左求值数字， 
 但从左至右打印它们。;
 j := int ÷ 10;
 int := int - 10 × j;
 if j ≠ 0 then
 di​gits(j);
 outchar(channel, ‘0123456789’, int + 1)
 end digits;
 if int &lt; 0 then
 begin
 outchar(channel, ‘-’, 1);
 int := -int
 end;
 di​gits(int); outterminator(channel)
end outinteger
这里调用到的codice_86，将在字符串codice_87中对应整数codice_88的值的那个字符，传递到通道codice_89；codice_90，用于输出在数值之后的终结符（即空格、换行或分号）。此外，在1964年曾制定《ALGOL 60输入输出过程报告》，其中定义了codice_91、codice_92、codice_78、codice_83、codice_84、codice_96和codice_97，这里的多维数组采用了（Row major）次序。