ALGOL 60

ALGOL 60（源自ALGOrithmic Language 1960的縮寫），是在1960年創建的稱為“算法語言”的一種程式語言。它是以後來稱為ALGOL 58的“國際代數語言”為基礎，其官方後繼者是ALGOL 68，它們一起並稱為ALGOL語言家族。Algol 60引進了許多新的概念如：塊、詞法作用域、遞歸、巴科斯-諾爾範式（BNF），它在程式語言設計和發展演化中有著巨大的影響力。

**歷史**
1960年，在巴黎舉行的討論會上，來自歐洲的諾爾、Bauer、Rutishauser、Samelson、範·韋恩加登、Vauquois、Woodger，與來自美國的佩利、巴科斯、麥卡錫、Katz、Wegstein和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標準：
*ISO 1538: 1984年，編程語言ALGOL 60，它已穩固化。
*ISO 1672: 1977年，ALGOL基本符號的ISO 7位編碼字符集硬件表示，它已撤消。

**實現時間線**
ALGOL 60在語言報告中沒有I/O設施；諸多實現以少有相互兼容的方式定義了自己的設施。迄今ALGOL 60已經有了至少70個擴充、擴展、派生和子語言。

**詞法**

**簡單符號**
除了字母和數字之外，ALGOL定義了運算符：
和Delimiter:
在ISO 1672標準中，用:=表示≔（U+2254），用*表示×；用%表示÷，用**或^表示↑；用>=表示≥，用表示≤，用表示≠；用@表示科學記數法中指數運算的底數10所用符號⏨（U+23E8），用{表示‘，並且用}表示’，用空格 表示在字符串中的空白字符␣（U+2423）。

**關鍵字**
ALGOL 60有24個關鍵字：
ALGOL 60不採用保留字的概念，但包括了標準函數名字作為限制標識符：
關鍵字寫法依賴於實現，常見的是一種叫做索繞（stropping）的方法，即將關鍵字大寫幷包圍在兩個'之間，例如將go to寫為'GOTO'。在ISO 1672標準中關鍵字還包括對特定符號的某種文字轉寫：

**語義**

**塊與作用域**
在ALGOL 60中，“複合語句”被定義為：包圍在語句括號begin和end之間的成序列的語句，形成一個複合語句。塊被定義為：成序列的聲明，跟隨著成序列的語句，並被包圍在begin和end之間，形成一個塊；所有聲明以這種方式出現在一個塊中，並只在這個塊中有效。A sequence of declarations followed by a sequence of statements and enclosed between begin and end constitutes a block. Every declaration appears in a block in this way and is valid only for that block. |access-date=2023-02-20 |archive-date=2023-02-20 |archive-url=https://web.archive.org/web/20230220054423/https://www.masswerk.at/algol60/report.htm |dead-url=no 
一個程序是特定的一個塊或複合語句，它不包含在另一個語句之中，並且不使用不包含在它之中的其他語句。在1976年的修改版語言報告中，程序只能包含在叫做“環境塊”的假定總是存在的一個虛構塊之中，除了可以使用在環境塊中聲明的過程標識符和函數指定符之外，不使用不包含在它之中的其他語句。
量（quantity）被區分出如下種類：簡單變量、數組、標籤、接轉（switch列表由標籤組成
“25.4.3.
Here, by virtue of switch wernik, the computation follows one of four possible branches of the program depending on the current value of k. Afterwards the common course of the calculation (i.e. the statements which would follow «end») is taken up again.”）和過程。聲明負擔定義在程序中用到的量的特定屬性，並給它們關聯上標識符。聲明包括：類型聲明、數組聲明、接轉（switch）聲明和過程聲明。量的作用域是語句和表達式的集合，在其中關聯於這個量的標識符的聲明是有效的。所有的塊，自動地介入名稱目錄（nomenclature）的一個新的層級：
*在這個塊內出現的標識符，可以通過合適的聲明，而被指定為局部於所論及的這個塊。這個標識符在這個塊裡面的所表示的實體，不存在於它的外面。這個標識符在這個塊外面的所表示的任何實體，在這個塊裡面是不可見的。
*除了表示標籤的標識符之外，一個標識符，如果出現在一個塊中，而且並非聲明於這個塊中，則它非局部於這個塊
42.5.2. Hidden operands. A block may have hidden operands: Indeed, if a procedure P is operand of block B, …… the global parameters of P are also involved in the execution of B, hence operands of B. We call these hidden operands of B because they cannot be found by inspection of block B but only by inspection of the declaration for procedure P, which is given somewhere outside B. ……
42.5.3. The operands of a block B fall into the following four categories:
⒜ Arguments …… ⒝ Results …… ⒞ Transients: …… which have properties of both arguments and results …… ⒟ Exits: Labels referring to destinations located outside B and switches which are declared outside B. ……
52.3.1. Considering a mathematical expression, e.g. an integral    it is seen that the variables x and y serve entirely different purposes: y is a variable upon which the value of I depends; in mathematical logic this is called a free variable (of the expression). This latter term indicates that one is free to substitute a value, e.g. 2.75, for y, where-upon one obtains the result    The variable x, on the other hand, is only an auxiliary object for describing the operation to be performed by the expression. It is called a bound variable since it is not accessible from outside the expression. ……
52.3.2. Comparing these examples with an ALGOL procedure and the terminology used ……, it becomes obvious that the free variables correspond to what are called the operands of a procedure, while the bound variables correspond to the internal quantities.”，就是說它在這個塊裡面和在緊鄰其外的層級中所表示的是同一個實體。
*因為塊中的語句自身可以是一個塊，局部和非局部於一個塊的概念，必須遞歸地去理解，就是說非局部於一個塊A的一個標識符，可是亦可否地，非局部於A是其中語句的塊B。
這動態的蘊涵了：在通過begin進入一個塊的時候，所有為這個塊聲明的標識符，假定了這個給定聲明的本性所蘊涵的意義（significance）；如果這些標識符已經被外面的其他聲明所定義，這時它們被給予新的意義；在另一方面，並非為這個塊聲明的標識符，保持它們舊有的含義。在通過end或go to語句退出一個塊的時候，為這個塊聲明的標識符失去它們的局部意義。聲明可以標記上額外的聲明符own，其效果為：在重新進入一個塊的時候，自有的這些量的值將不變更而仍是上次退出時的值，然而聲明的沒有標記上own的變量的值是未定義的。

**表達式和語句**
在描述算法處理的程序中，主要構成者是算術表達式、布爾表達式，和得到語句標籤的指定（designational）表達式。除了特定的分界符之外，表達式的構成者包括：邏輯值、數值、變量、函數指定式，和基本的算術、關係、邏輯運算符（operator）及順序運算符。用以形成語句的關鍵字，在ALGOL 60中被歸入順序運算符和分隔符之中。
變量是對一個單一值的指名（designation）。加下標（subscripted）變量指定（designate）多維數組的元素的值，這裡將數組元素稱為“組成元件”（component）
    lk ≤ ik ≤ uk  (k = 1, 2, ……, p),
whose boundaries (i.e. the array bounds l1, l2 ……, lp, u1, u2, ……, up) are given in the corresponding array declaration ……. ……
14.3.2. A subscripted variable «IE1, E2, ……, Ep», if encountered in an expression, represents also a single value defined as follows: Evaluate the subscript expressions E1, E2, ……, Ep; if their values are i1, i2, ……, ip, then the subscripted variable represents the value that has most recently been assigned to the i1, i2, ……, ip-component of the array I.”。函數指定式（designator）定義單一的數量值或邏輯值，它們是將給定的由過程聲明定義的規則集合，應用於固定的實際參數集合的結果。
現在通常將變量定義為抽象的存儲位置，它含有了被稱為一個值的某種已知或未知的信息量，並且配對了關聯的符號名字。在ALGOL 60中，某些語法單位，比如表達式及其構成者和數組標識符，被稱為擁有值。各種“類型”即integer、real和Boolean，指稱（denote）值的基本的屬性。
在左圓括號和匹配的右圓括號之間的表達式（parenthesized expression）自行求值，而這個值被用於後續的計算之中；因此通過適當的圓括號放置，總是可以在表達式之內安排出想要的運算次序。
ALGOL 60將語句分為三類：無條件語句、條件語句和for語句。賦值語句擔負將表達式的值，指派（assign）到一個或多個變量，或者在定義函數指定式的值的過程主體中指派到過程標識符；在作為指派目標的下標變量中出現的任何下標表達式，先於得出所指派之值的表達式，而按從左至右順序求值。空無的虛設（dummy）語句不執行任何運算。過程語句負擔實施調用一個過程主體的執行。
控制流程語句包括：go to跳轉語句、條件語句、for循環語句。go to語句結合了無條件go to和計算go to二者，go to語句不能從塊外跳轉到塊內的標籤，但可以跳轉進入複合語句。條件語句包括if語句（即if 布爾表達式> then 無條件語句>），和if語句經由關鍵字else與隨後的語句聯合在一起的形式（即if語句> else 語句>）。ALGOL 60在if語句和for語句中介入了子句概念，算術表達式、布爾表達式和指定表達式，可以是條件表達式（即if ~ then ~ else ~）19.7.1. «x + (if t > t1 then 1 else -1) / x».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 «+ if» is always illegal).
19.7.2. Selection of a component of an array with safeguards against exceeding the array bounds:     «aif k > n then n else if k ».
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:     «if (if u then x else y) > 0 then (if z = 0 then x + y else x - y) else x × y».”。
由於變量和函數指定式二者的語法定義都包含表達式，表達式及其構成者的定義必須是遞歸的。由於成序列的語句，可以被組織成複合語句和塊，語句的定義必需是遞歸的。ALGOL 60採用了左遞歸的巴科斯範式（BNF）。

**過程**
在ALGOL 60中，過程聲明擔負定義過程標識符所關聯的過程，其主要構成者是過程主體，它是一個語句或一段代碼。過程主體總是表現得如同一個塊，不管它是否有著塊的形式；故而標記了在過程主體內語句或者主體自身的標籤的作用域，永遠不能延伸超出這個過程主體    «begin real æ; S end»1, 2.……1 The declaration of the fictitious variable æ serves solely to make this piece of program a block.2 In case S is already an unlabelled block, this artificial construction is unneeded and we could take S instead. ……”。
過程主體關聯著一個頭部，它規定了出現在過程主體內的代表形式參數的特定標識符。過程的參數傳遞有兩種求值策略：傳名調用和傳值調用。在過程聲明中，通過對形式參數名字前導value來指定傳值調用，缺省為傳名調用。在過程主體是用ALGOL語言寫的語句的情況下，過程語句執行它的效果，等價於在程序上進行下列操作的效果：
*聲明為傳值調用的形式參數，都要被賦值即指派上對應的實際參數的值，這些指派被認為是在進入過程主體之前顯式進行的。其效果如同創建了包圍著這個過程主體的一個額外的塊，在其中所做的這些指派針對的是局部於這個虛構（fictitious）塊的變量，它們具有在相應規定中給出的類型。作為結論，傳值調用的變量，被認為非局部於過程主體，但是局部於這個虛構塊。
*聲明為傳名調用的形式參數，在整個過程主體內，要被替代為對應的實際參數，並且只要語法上可能就對這些實際參數包圍上圓括號。在通過這個名字替代處理而插入的標識符，和已經存在於過程主體之內的其他標識符，二者之間的可能衝突，將憑藉對涉及到的（這個過程主體的）形式標識符或局部標識符的適合的系統性變更來避免
  «begin real z; z := 2 × y; z := z / z end»,
which certainly was not the intention of the designer of the procedure. With the above amendment, however, the internal z is changed into zæ, after which we obtain the equivalence block correctly as
  «begin real zæ; zæ := 2 × z; z := z / zæ end».”。
*最終經過上述修改後的過程主體，被插入到過程語句的位置上並被執行。如果調用這個過程的位置，處在這個過程主體的任何非局部量⒜ Those operands of the fictitious block whose identifiers are not quoted in the formal parameter part are called global operands of the procedure. …… ⒝…… formal operands ……⒞…… hidden operands ……
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 I is global parameter of a procedure, then a (true or formal) quantity Q with that identifier must exist in the environment of the procedure declaration, and it is this Q which in a call of the procedure is meant by the identifier I.
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.”的作用域的外面，在通過這個過程主體替代處理而插入的標識符，和在這個過程語句或函數指定式所在位置上其聲明有效的標識符，二者之間的可能衝突，將通過（在發起調用的這個層級上）對後者標識符的適合的系統性變更來避免
  «begin real æ; t := tæ end».
Accordingly, this call accomplishes something which would seem impossible, namely changing the value of a suppressed variable.
45.2.5. ……Consequently no name changes apply where the identifier of a global operand not suppressed at the location of a procedure call coincides with the identifier of an actual operand.”。
對於定義函數指定式的值的過程聲明，在其過程主體中，必須出現具有過程標識符在其左側部份中的一個或多個賦值語句，其中至少有一個必須被執行；並且這個過程標識符所關聯的類型，必須通過以類型聲明符作為其過程聲明的最先符號的樣貌來聲明。最後那個這樣指派的值，被用來繼續此函數指定式在其中出現的表達式的求值。在這個過程主體中，這個過程標識符的不在賦值語句左側部份中的任何出現，指示了這個過程的激活（activation）。
兩個傳名調用形式參數，其對應的實際參數之間可能存在依賴關係，比如第一個是整數變量i，而第二個是下標變量Ai，從而導致後者形式參數也依賴於前者形式參數，利用傳名調用和這種副作用可以實現Jensen's Device；它典型的用於定義對應於的級數過程Sum(k, l, u, ak)，它有兩個傳名調用的形式參數：索引變量k和通項（general）表達式ak。
對於交換兩個參數的值的swap(x, y)過程，其過程主體定義為：t:=x; x:=y; y:=t，這種依賴性副作用會導致可能出現異常行為，由於名字替代機制相當於宏展開（expansion），過程語句swap(i, Ai)中下標變量Ai的下標i未經求值，對應的過程主體就轉換成為：t:=i; i:=Ai; Ai:=t。1964年IFIP制定了《SUBSET ALGOL 60報告》，在這個子集語言中對“完全的名字概念”（full name-concept）增加了一項限制：在名字替代（傳名調用）中，實際參數只能是一個標識符或字符串。
在過程的參數列表( …  … )中，有可選的“) : (”樣式的參數Delimiter。眾所周知的傳名調用實現採用了thunk。Donald Knuth設計了“男人抑或男孩測試”，來區分編譯器是否正確的實現了“遞歸和非局部引用”，在這個測試中局部定義的函數將自身用作其所調用函數的傳名調用的實際參數。

**例子**
下面是語言報告中過程聲明的一個例子這裡採用了1976年修改版語言報告中的代碼，對原版進行的修改是增加了，針對的是數組的全部元素都是0的特殊情況。：
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(ap, q) > y then
begin
y := abs(ap, q);
i := p; k := q
end
end Absmax
在1976年修改版語言報告的環境塊中，定義了輸入輸出過程：inchar、outchar、length、outstring、outterminator、ininteger、outinteger、inreal和outreal，下面以其中的outinteger作為演示例子：
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 
這裡調用到的outchar(channel, str, int)，將在字符串str中對應整數int的值的那個字符，傳遞到通道channel；outterminator(channel)，用於輸出在數值之後的終結符（即空格、換行或分號）。此外，IFIP在1964年曾制定《ALGOL 60輸入輸出過程報告》，其中定義了insymbol、outsymbol、length、inreal、outreal、inarray和outarray，這裡的多維數組採用了橫行為主（Row major）次序
    il = jl for l = 1, 2, ……, h - 1, but ih h.
Moreover, these procedures always transfer all components of the array appearing as the second actual operand.
As a consequence, a call «outarray(15, p)», where p is declared e.g. as «array p-4:5, 1:50, 0:20», is equivalent to
。

**參見**
 ABC ALGOL- ALGOL- ALGOL 58- ALGOL N- ALGOL 68- ALGOL W- ALGOL X- Atlas Autocode- Coral 66- Edinburgh IMP- Jensen's Device- ISWIM- JOVIAL- NELIAC- Simula- S-algol- Scheme

**註釋與引用**

**外部鏈接**
  Revised Report on the Algorithmic Language Algol 60 date=20070625171638  by Peter Naur, et al. ALGOL definition-  Modified Report on the Algorithmic Language Algol 60 date=20230707162118  as modified by R. M. De Morgan, I. D. Hill and B. A. Wichmann under the authority of IFIP Working Group 2.1.- A BNF  syntax summary date=20151208201711  of ALGOL 60-  "The Emperor's Old Clothes" – Hoare's 1980 ACM Turing Award speech, which discusses ALGOL history and his involvement-  MARST date=20200322060922 , a free Algol-to-C translator-  An Implementation of ALGOL 60 for the FP6000 date=20200725025218  Discussion of some implementation issues.- url=http://portal.acm.org/ft_gateway.cfm?id=808370- Edinburgh University wrote compilers for Algol60 (later updated for Algol60M) based on their Atlas Autocode compilers initially bootstrapped from the Atlas to the KDF-9. The Edinburgh compilers generated code for the ICL1900, the ICL4/75 (an IBM360 clone), and the ICL2900. Here is the  BNF for Algol60 date=2020-05-15  and the  ICL2900 compiler source date=2020-05-15 ,  library documentation date=2020-05-15 , and  a considerable test suite date=2020-05-15  including  Brian Wichmann's tests. date=2020-05-15  Also there is a rather superficial  Algol60 to Atlas Autocode source-level translator date=2020-05-15 .- Eric S. Raymond's  Retrocomputing Museum date=20200403000916 , among others a link to the NASE Algol-60 interpreter written in C.-  The NASE interpreter date=20200726231519 - Stories of the B5000 and People Who Were There: a dedicated ALGOL computer  date=20200404183110 ,  date=20161024102839 - archive-url=https://web.archive.org/web/20210424132438/https://digital.library.unt.edu/ark:/67531/metadc871723/-  NUMAL date=20111001070814  A Library of Numerical Procedures in ALGOL 60 developed at The Stichting Centrum Wiskunde & Informatica (legal successor of Stichting Mathematisch Centrum)  legal owner.-  Algol 60 resources: translators, documentation, programs date=20200907205521 -  Algol-60 date=20210506233203  included in Racket.