ALGOL 60

ALGOL 60（源自ALGOrithmic Language 1960的缩写），是在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定义了运算符：
和:
在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（U+23E8），用codice_13表示codice_14，并且用codice_15表示codice_16，用空格codice_17表示在字符串中的空白字符codice_18（U+2423）。
关键字.
ALGOL 60有24个关键字：
还包括标准函数名字作为限制标识符：
关键字写法依赖于实现，常见的是一种叫做（stropping）的方法，即将关键字大写并包围在两个codice_19之间，例如将codice_20写为codice_21。在ISO 1672标准中关键字还包括对特定符号的某种文字转写：
语义.
块与作用域.
在ALGOL 60中，“复合语句”被定义为：包围在语句括号codice_22和codice_23之间的成序列的语句，形成一个复合语句。块被定义为：成序列的声明，跟随着成序列的语句，并被包围在codice_22和codice_23之间，形成一个块；所有声明以这种方式出现在一个块中，并只在这个块中有效。
一个程序是特定的一个块或复合语句，它不包含在另一个语句之中，并且不使用不包含在它之中的其他语句。在1976年的修改版语言报告中，程序只能包含在叫做“环境块”的假定总是存在的一个虚构块之中，除了可以使用在环境块中声明的过程标识符和函数指定符之外，不使用不包含在它之中的其他语句。
量（quantity）被区分出如下种类：简单变量、数组、标签、codice_26（codice_26列表由标签组成
“25.4.3.
Here, by virtue of switch codice_28, the computation follows one of four possible branches of the program depending on the current value of codice_29. Afterwards the common course of the calculation (i.e. the statements which would follow «codice_23») is taken up again.”</ref>）和过程。声明负担定义在程序中用到的量的特定属性，并给它们关联上标识符。声明包括：类型声明、数组声明、codice_26声明和过程声明。量的作用域是语句和表达式的集合，在其中关联于这个量的标识符的声明是有效的。所有的块，自动地介入（nomenclature）的一个新的层级：
这动态的蕴涵了：在通过codice_22进入一个块的时候，所有为这个块声明的标识符，假定了这个给定声明的所蕴涵的（significance）；如果这些标识符已经被外面的其他声明所定义，这时它们被给予新的意义；在另一方面，并非为这个块声明的标识符，保持它们旧有的含义。在通过codice_23或codice_20语句退出一个块的时候，为这个块声明的标识符失去它们的局部意义。声明可以标记上额外的声明符codice_38，其效果为：在重新进入一个块的时候，自有的这些量的值将不变更而仍是上次退出时的值，然而声明的没有标记上codice_38的变量的值是未定义的。
表达式和语句.
在描述算法处理的程序中，主要构成者是算术表达式、布尔表达式，和得到语句标签的指定（designational）表达式。除了特定的分界符之外，表达式的构成者包括：逻辑值、数值、变量、函数指定式，和基本的算术、关系、逻辑运算符（operator）及顺序运算符。用以形成语句的关键字，在ALGOL 60中被归入顺序运算符和分隔符之中。
变量是对一个单一值的指名。下标（subscripted）变量指定（designate）多维数组的元素的值，这里将数组元素称为“组成元件”（component）。函数指定式（designator）定义单一的数量值或逻辑值，它们是将给定的由过程声明定义的规则集合，应用于固定的实际参数集合的结果。
现在通常将变量定义为抽象的存储位置，它含有了被称为一个值的某种已知或未知的信息量，并且配对了关联的名字。在ALGOL 60中，某些语法单位，比如表达式及其构成者和数组标识符，被称为拥有值。各种“类型”即codice_40、codice_41和codice_42，指称（denote）值的基本的属性。
在左圆括号和匹配的右圆括号之间的表达式（parenthesized expression）自行求值，而这个值被用于后续的计算之中；因此通过适当的圆括号放置，总是可以在表达式之内安排出想要的运算次序。
ALGOL 60将语句分为三类：无条件语句、条件语句和codice_43语句。赋值语句担负将表达式的值，指派（assign）到一个或多个变量，或者在定义函数指定式的值的过程主体中指派到过程标识符；在作为指派目标的下标变量中出现的任何下标表达式，先于得出所指派之值的表达式，而按从左至右顺序求值。空无的虚设（dummy）语句不执行任何运算。过程语句负担实施调用一个过程主体的执行。
控制流程语句包括：codice_20跳转语句、条件语句、codice_43循环语句。codice_20语句结合了无条件codice_20和计算codice_20二者，codice_49语句不能从块外跳转到块内的标签，但可以跳转进入复合语句。条件语句包括codice_50语句（即codice_51），和codice_50语句经由关键字codice_53与随后的语句联合在一起的形式（即codice_54）。ALGOL 60在codice_50语句和codice_43语句中介入了子句概念，算术表达式、布尔表达式和指定表达式，可以是（即codice_57）19.7.1. «<syntaxhighlight lang="pascal" inline>x + (if t > t1 then 1 else -1) / x</syntaxhighlight>».We recall that a conditional arithmetic expression cannot be used directly as a primary in a larger expression, but must for this purpose be enclosed in parentheses (the sequence «codice_58» is always illegal).
19.7.2. Selection of a component of an array with safeguards against exceeding the array bounds:     «<syntaxhighlight lang="pascal" inline>ak > n then n else if k < 1 then 1 else k</syntaxhighlight>».
19.7.3. Where conditional expressions are intended as comparands of a relation or as alternatives of a conditional expression, they must again be enclosed in parentheses:     «<syntaxhighlight lang="pascal" inline>if (if u then x else y) > 0 then (if z = 0 then x + y else x - y) else x × y</syntaxhighlight>».”</ref>。
由于变量和函数指定式二者的语法定义都包含表达式，表达式及其构成者的定义必须是递归的。由于成序列的语句，可以被组织成复合语句和块，语句的定义必需是递归的。ALGOL 60采用了左递归的巴科斯范式（BNF）。
过程.
在ALGOL 60中，过程声明担负定义过程标识符所关联的过程，其主要构成者是过程主体，它是一个语句或一段代码。过程主体总是表现得如同一个块，不管它是否有着块的形式；故而标记了在过程主体内语句或者主体自身的标签的作用域，永远不能延伸超出这个过程主体。
过程主体关联着一个头部，它规定了出现在过程主体内的代表形式参数的特定标识符。过程的参数传递有两种求值策略：传名调用和传值调用。在过程声明中，通过对形式参数名字前导codice_59来指定传值调用，缺省为传名调用。在过程主体是用ALGOL语言写的语句的情况下，过程语句执行它的效果，等价于在程序上进行下列操作的效果：
44.3.1. A global parameter - that is, the identifier of a global operand - represents the same quantity inside the procedure body as outside in the environment of the procedure declaration. A global operand is therefore simply the extension of a quantity which exists outside the procedure. As a consequence we have
44.3.2. "The environment rule for global parameters":If the identifier codice_60 is global parameter of a procedure, then a (true or formal) quantity codice_61 with that identifier must exist in the environment of the procedure declaration, and it is this codice_61 which in a call of the procedure is meant by the identifier codice_60.
According to this rule, a global parameter acts like a thread which links the procedure declaration permanently to its environment; indeed, a procedure which has global parameters is only fully defined if it is embedded into an ALGOL program in which the global operands are properly declared.”</ref>的作用域的外面，在通过这个过程主体替代处理而插入的标识符，和在这个过程语句或函数指定式所在位置上其声明有效的标识符，二者之间的可能冲突，将通过（在发起调用的这个层级上）对后者标识符的适合的系统性变更来避免。
对于定义函数指定式的值的过程声明，在其过程主体中，必须出现具有过程标识符在其左侧部份中的一个或多个赋值语句，其中至少有一个必须被执行；并且这个过程标识符所关联的类型，必须通过以类型声明符作为其过程声明的最先符号的样貌来声明。最后那个这样指派的值，被用来继续此函数指定式在其中出现的表达式的求值。在这个过程主体中，这个过程标识符的不在赋值语句左侧部份中的任何出现，指示了这个过程的激活（activation）。
两个传名调用形式参数，其对应的实际参数之间可能存在依赖关系，比如第一个是整数变量codice_64，而第二个是下标变量codice_32，从而导致后者形式参数也依赖于前者形式参数，利用传名调用和这种副作用可以实现；它典型的用于定义对应于formula_1的级数过程codice_66，它有两个传名调用的形式参数：索引变量codice_29和通项（general）表达式codice_68。
对于交换两个参数的值的codice_69过程，其过程主体定义为：codice_70，这种依赖性副作用会导致可能出现异常行为，由于名字替代机制相当于宏展开（expansion），过程语句codice_71。1964年制定了《SUBSET ALGOL 60报告》，在这个子集语言中对“完全的名字概念”（full name-concept）增加了一项限制：在名字替代（传名调用）中，实际参数只能是一个标识符或字符串。
在过程的参数列表codice_72中，有可选的“codice_73”样式的参数。众所周知的传名调用实现采用了。Donald Knuth设计了“男人抑或男孩测试”，来区分编译器是否正确的实现了“递归和非局部引用”，这个测试用到了传名调用。
例子.
下面是语言报告中过程声明的一个例子：
<syntaxhighlight lang="pascal">
procedure Absmax(a) Size:(n, m) Re​sult:(y) Subscripts:(i, k);
begin
end Absmax
</syntaxhighlight>
在1976年修改版语言报告的环境块中，定义了输入输出过程：codice_74、codice_75、codice_76、codice_77、codice_78、codice_79、codice_80、codice_81和codice_82，下面以其中的codice_80作为演示例子：
<syntaxhighlight lang="ada">
procedure outinteger(channel, int);
begin
end outinteger
</syntaxhighlight>
这里调用到的codice_84，将在字符串codice_85中对应整数codice_86的值的那个字符，传递到通道codice_87；codice_88，用于输出在数值之后的终结符（即空格、换行或分号）。此外，在1964年曾制定《ALGOL 60输入输出过程报告》，其中定义了codice_89、codice_90、codice_76、codice_81、codice_82、codice_94和codice_95，这里的多维数组采用了（Row major）次序。