ALGOL 68

ALGOL 68（源自ALGOrithmic Language 1968的縮寫），是一種指令式程式語言，作為ALGOL家族的成員，它是官方上的ALGOL 60後繼者。ALGOL 68的設計目標，是提供更廣泛的應用，以及更嚴格的語法定義。

ALGOL 68的特徵包括面向表達式程式語言的語法，使用者聲明的類型和結構與標籤聯合類型，變量與引用參數的引用模型，可變長數組和字串、陣列與矩陣的陣列分片，使用者定義的運算符和運算符重載，高階函數與匿名函數，以及並發。

## 概論

IFIP工作組2.1在1964年3月達成一致，要制定ALGOL 60的兩個後續語言標準：ALGOL X，它是具有增補的強類型和Euler語言中的樹或列表的ALGOL語言重新定義；和ALGOL Y，它具有LISP的同像性風格修改自身程序能力。經過多次會議研討針對ALGOL X的提案之後，1968年12月20日，IFIP工作組2.1正式通過了ALGOL 68最終報告，並在1969年1月將其提交給了資訊處理國際聯盟大會，在1969年3月，IFIP大會經過郵件投票授權出版此報告。

ALGOL 68的定義使用了阿德里安·范·韋恩加登發明的一種數學形式主義的兩級形式文法。范韋恩加登文法使用分別稱為「元產生式規則」和「超規則」的兩組上下文無關文法規則，生成形成一個可能無限的產生式集合，而這些常規的產生式將識別特定的ALGOL 68程序；值得注意的是，它們能夠表達在很多其他程式語言的技術標準中被標記為「語義」的那種要求，其他語言的語義必須用易致歧義的自然語言敘述來表達，並接著在編譯器中實現為附加到形式語言解析器的「特設」代碼。

ALGOL 68設計的主要目標和原則為：

- 描述的完備性和清晰性。
- 設計的正交性。
- 安全性。
- 靜態的模態（即類型）檢查。
- 模態無關的解析。
- 分立編譯。
- 循環優化。
- 表示於極小化和更大的字符集。

在1970年，ALGOL 68-R成為了第一個投入工作的ALGOL 68編譯器。在1973年9月確定並於1975年出版的修訂報告中，省略了特定特徵比如過程化、gomma和形式邊界。Stephen R. Bourne是ALGOL 68修訂委員會成員，他選取了它的一些想法到他的Bourne shell之中。

ALGOL 68曾受到激烈的批評，最突出的是來自其設計委員會的一些成員比如C. A. R. Hoare，還有ALGOL 60編譯器作者比如Edsger Dijkstra，它獲評為拋棄了ALGOL 60的簡單性，成為了複雜或過於籠統的想法的載體。ALGOL 68與刻意保持簡單的同時代（競爭）者如C、S-algol和Pascal形成了鮮明對比。

ALGOL 68的語言定義出版後的文本長達兩百多頁並充斥著非既有標準的術語，這種複雜性使得編譯器實現任務變得困難，故而它曾被稱為「沒有實現也沒有使用者」。這麼說只是部份真實的，ALGOL 68曾應用於一些小眾市場，特別是流行於英國的國際電腦有限公司（ICL）的機器之上，還有在教學角色之上。在這些領域之外，其使用相對有限。

儘管如此，ALGOL 68對電腦科學領域的貢獻是深刻、廣泛而持久的，雖然這些貢獻大多只是在它們於後來開發的程式語言中重現之時才被公開認可。很多語言是為了應對設計這門語言時所採用的形式化方法導致的複雜性而專門開發的，其中最著名的是Niklaus Wirth的採用附綴文法的ALGOL W和作為其後繼者的採用擴展巴科斯-瑙爾範式（EBNF）的Pascal；或者是針對特定角色而重新實現的，比如有些人認為Ada可以看作ALGOL 68的後繼者。

1970年代的很多語言可以追溯其設計至ALGOL 68，選取一些特徵，並放棄被認為太複雜或超出給定角色範圍的其他特徵。其中就有C語言，它受到ALGOL 68的直接影響，特別是它的強類型和結構。多數現代語言都至少可以追溯其部份語法至要麼C語言要麼Pascal，因而很多語言可直接或間接的經由C語言而追溯至ALGOL 68。

ALGOL 68項目的完整歷史可參見Charles H. Lindsey的《A History of ALGOL 68》。ALGOL 68語言的長篇闡述可參見Dr. Sian Mountbatten的《Programming ALGOL 68 Made Easy》，或者Marcel van der Veer的《Learning ALGOL 68 Genie》。

## 規定和實現時間線

名稱｜年｜國家｜描述｜目標CPU/平台｜屬主/許可證｜實現語言

Generalized ALGOL｜1962｜荷蘭｜廣義ALGOL｜荷蘭數學中心

ALGOL XDP｜1966｜ALGOL X草擬提案｜IFIP工作組2.1

ALGOL 68DR｜1968｜ALGOL 68草案報告｜IFIP工作組2.1

ALGOL 68r0｜1968｜ALGOL 68最終報告｜IFIP工作組2.1

ALGOL 68-R｜1970｜英國｜GEORGE作業系統之下的ALGOL 68｜ICT 1900系列｜皇家雷達研究所｜ALGOL 60

DTSS ALGOL 68｜1970｜美國｜Dartmouth分時系統的ALGOL 68｜GE-600系列｜達特茅斯學院

Mini ALGOL 68｜1973｜荷蘭｜針對簡單ALGOL 68程序的解釋器｜可移植解釋器｜荷蘭數學中心｜ALGOL 60

OREGANO｜1973｜美國｜實踐「實現模型的重要性。」｜加州大學洛杉磯分校

M-220 ALGOL 68｜1974｜蘇聯｜使用EPSILON語言在M系列電腦上實現ALGOL 68｜M系列電腦｜EPSILON語言

ALGOL 68C｜1975｜英國｜劍橋大學ALGOL 68實現｜國際電腦有限公司，IBM System/360，PDP-10和Unix，Telefunken TR440/TR445，Tesla a.s. 200和Z80（1980年）｜劍橋大學｜ALGOL 68C

ALGOL 68r1｜1975｜ALGOL 68修訂報告｜IFIP工作組2.1

ALGOL 68 H｜1975｜加拿大 荷蘭｜ALGOL 68編譯器｜阿爾伯塔大學，荷蘭數學中心｜ALGOL W

CDC ALGOL 68｜1975｜美國｜完全實現的ALGOL 68｜CDC 6000系列，CDC Cyber｜控制數據公司

Odra ALGOL 68｜1976｜蘇聯 波蘭｜Odra電腦 1204/IL｜ALGOL 60

Oklahoma ALGOL 68｜1976｜美國｜俄克拉何馬州立大學ALGOL 68實現｜IBM 1130和IBM System/370｜俄克拉何馬州立大學｜ANSI Fortran 66

Berlin ALGOL 68｜1977｜德國｜柏林工業大學ALGOL 68實現｜基於抽象ALGOL 68機器的機器無關編譯器｜柏林工業大學｜編譯器描述語言

FLACC｜1977｜加拿大｜具有調試特徵的修訂報告完整實現｜System/370｜租用，Chion公司｜彙編

ALGOL 68RS｜1977｜英國｜可移植編譯器｜ICL 2900系列，Multics，VMS和C生成器（1993年）｜皇家信號與雷達研究所｜ALGOL 68RS

ALGOL 68 MR｜1978｜ALGOL 68的模塊和分立編譯規定｜IFIP工作組2.1

ALGOL 68-RT｜1979｜英國｜並行ALGOL 68-R

Leningrad ALGOL 68｜1980｜蘇聯｜列寧格勒國立大學開發的完全語言加上模塊系統｜IBM，DEC，CAMCOH，PS 1001和PC

交互式ALGOL 68｜1983｜英國｜增量編譯，1992年再版MK2｜PC｜非商業共享軟體

ALGOL 68S｜1985｜英國 美國｜ALGOL 68的子集語言｜Sun-3，Sun SPARC（在SunOS 4.1和Solaris 2下），Atari ST（在GEMDOS下），Acorn Archimedes（在RISC OS下），VAX-11（在Ultrix下）｜利物浦大學，卡內基·梅隆大學，曼徹斯特大學｜BLISS，Pascal

Rutgers ALGOL 68｜1990｜美國 匈牙利｜Mini ALGOL 68解釋器後續版本｜可移植解釋器｜寫於羅格斯大學的非商業開源軟體｜C

Algol68toC｜1993｜英國｜基於源自1985年ELLA語言ALGOL 68RS的ctrans｜可移植C生成器｜國防研究局的皇冠版權開源軟體｜ALGOL 68RS

ALGOL 68 Genie｜2001｜荷蘭｜完全語言包括標準的並立子句｜可移植解釋器；2010年版本2之後，具有可選的選定單元的編譯｜GNU GPL｜C

Algol68FrontEnd in GCC｜2025｜西班牙｜GCC中的ALGOL 68前端｜跨平台｜GNU GPL｜C/C++

## 樣例代碼

下面的樣例代碼實現了埃拉托斯特尼篩法來找到小於等於100的所有素數。ALGOL 68中`'''NIL'''`類似於其他語言中的空指針，`x '''OF''' y`表示訪問`'''STRUCT''' y`的成員`x`。

```bash
BEGIN # ALGOL68的素数筛法，基于链表实现 #
    MODE
        NODE = STRUCT (INT h, REF NODE t),
        LIST = REF NODE;
    OP CONS = (INT n, LIST l) LIST: HEAP NODE := NODE (n, l);
    PRIO CONS = 9;
    PROC one to = (INT n) LIST:
        (PROC fn = (INT m) LIST: (m > n | NIL | m CONS fn(m + 1));
         fn(1));
    PROC error = (STRING s) VOID:
        (print((newline, " error: ", s, newline)); stop);
    PROC hd = (LIST l) INT:
        (l IS NIL | error("hd NIL"); SKIP | h OF l);
    PROC tl = (LIST l) LIST:
        (l IS NIL | error("tl NIL"); SKIP | t OF l);
    PROC show = (LIST l) VOID:
        (l ISNT NIL | print((" ", whole(hd(l), 0))); show(tl(l)) 
         | print(newline));
    PROC filter = (PROC (INT) BOOL p, LIST l) LIST:
    BEGIN
        PROC fn = (LIST m) LIST:
            IF m IS NIL THEN NIL
            ELIF p(hd(m)) THEN hd(m) CONS fn(tl(m))
            ELSE fn(tl(m))
            FI;
        fn(l)
    END;
    PROC sieve = (LIST l) LIST:
        IF l IS NIL THEN NIL
        ELSE hd(l) CONS sieve(filter(
                (INT n) BOOL: n MOD hd(l) NE 0, tl(l)))
        FI;
    PROC primes = (INT n) LIST: sieve(tl(one to(n)));
    show(primes(100))
END
```

將上述代碼保存入文本文件`primes.a68`中，然後使用ALGOL 68 Genie解釋器執行它：

```console
$ a68g primes.a68
 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
```

下面是採用了ALGOL 68RS的程序結構的Hello World樣例代碼，嚴格的說只有在`'''BEGIN'''`與`'''END'''`之間的諸行是ALGOL 68程序，第一行、第二行和最後一行都特定於`a68toc`編譯器。

```bash
PROGRAM helloworld CONTEXT VOID
USE standard
BEGIN
    print(("hello, world!", newline))
END
FINISH
```

第一行給出這個程序的標識為`helloworld`而且這個名字的文件包含了這個程序；`CONTEXT VOID`短語指定這個程序獨立而非嵌入到其他部份之中。第二行的`USE`加載了標準預置（prelude），`print()`就在其中。將上述代碼保存入文本文件`helloworld.a68`中，然後使用ALGOL 68RS編譯器`a68toc`編譯並接著執行它：

```console
$ ca -u ASDFGHJ helloworld.a68
$ ./helloworld
hello, world!
```

下面是採用GCC的ALGOL 68前端`ga68`程序結構的Hello World樣例代碼：

```bash
hello:
begin
    puts ("Hello, world!'n")
end
```

這裡的`puts()`包含在POSIX標準預置之中。將上述代碼保存入文本文件`helloworld.a68`中，然後使用`ga68`編譯器來編譯並接著執行它：

```console
$ ga68 -o helloworld helloworld.a68
$ ./helloworld
Hello, world!
```

## 顯著的語言元素

### 保留字及其等價符號

標準語言包含六十一個保留字，典型的用粗體字列印，並且其中一些還具有「簡短」符號等價者：

`'''MODE'''`，`'''OP'''`，`'''PRIO'''`，`'''PROC'''`，`'''FLEX'''`，`'''HEAP'''`，`'''LOC'''`，`'''LONG'''`，`'''REF'''`，`'''SHORT'''`，`'''STRUCT'''`，`'''UNION'''`，`'''VOID'''`。

`'''BITS'''`，`'''BOOL'''`，`'''BYTES'''`，`'''CHAR'''`，`'''COMPL'''`，`'''INT'''`，`'''REAL'''`，`'''SEMA'''`，`'''STRING'''`，`'''CHANNEL'''`，`'''FILE'''`，`'''FORMAT'''`。

`'''AT'''` `@`，`'''IS'''` `:=:`， `'''ISNT'''` `:/=:`，`'''OF'''`，`'''TRUE'''`，`'''FALSE'''`，`'''EMPTY'''`，`'''NIL'''` `○`，`'''SKIP'''` `~`。

`'''COMMENT'''` `'''CO'''` `#` `¢`，`'''PRAGMAT'''` `'''PR'''`，`'''BEGIN''' ~ '''END'''` `( ~ )`。

`'''IF''' ~ '''THEN''' ~ '''ELIF''' ~ '''THEN''' ~ '''ELSE''' ~ '''FI'''` `( ~ | ~ |: ~ | ~ | ~ )`。

`'''CASE''' ~ '''IN''' ~ '''OUSE''' ~ '''IN''' ~ '''OUT''' ~ '''ESAC'''` `( ~ | ~ |: ~ | ~ | ~ )`。

`'''FOR''' ~ '''FROM''' ~ '''TO''' ~ '''BY''' ~ '''WHILE''' ~ '''DO''' ~ '''OD'''`，`'''PAR'''`，`'''GO TO'''` `'''GOTO'''`，`'''EXIT'''`。

`'''GO TO'''`被當作兩個保留字。在未修訂報告的語言中，`'''OF'''`有等價符號 `→`，`'''EXIT'''`有等價符號`□`，還有保留字`'''EITHER'''`和`'''IS NOT'''`結合。

### 字符表示

<image>

「值當字符」（worthy character）是1977年出版的ALGOL 68標準硬體表示報告出於可移植性而推薦的字符集中的字符:

- A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 `&nbsp;` " # $ % '

這反映了當年一些硬體不支持在ANSI的ASCII或IBM的EBCDIC之外其他字符的事實。

傳輸表示採用「值當字符」時，「加上$i$乘以」符號`⊥`替代為`'''I'''`，「乘以$10$的冪」符號`⏨`和`\`替代為`'''E'''`。

<image>

ALGOL的「特殊」字符：

× ÷ ≤ ≥ ≠ ≡ ¬ ∧ ∨ ⊃ ↑ ⏨ ␣ ↓ → ⊥ ○ □ ⌊ ⌈ ⎩ ⎧ ¢

多數都可以在1965年出現的配備APL打字球與鍵帽後的IBM 2741終端的鍵盤上找到。這些字符也是Unicode標準的一部份，並且在一些流行的字體中可獲得到。

### 單元

基本語言構造是「單元」（unit）。單元可以是「公式」、「封閉子句」、「例程正文」這樣的構造，也可以是某個技術上需要的構造諸如賦值、跳轉、越過和空無。

技術術語「封閉子句」（enclosed clause）統一了某些固有的加括號的構造，它們在其他當代語言中被稱為「塊」、「do語句」、「switch語句」等等。在使用關鍵字的時候，通常使用介入關鍵字的反轉字符序列來終結這個包圍，比如：`'''IF''' ~ '''THEN''' ~ '''ELSE''' ~ '''FI'''`、`'''CASE''' ~ '''IN''' ~ '''OUT''' ~ '''ESAC'''`和`'''FOR''' ~ '''WHILE''' ~ '''DO''' ~ '''OD'''`。這種守衛命令語法被Stephen Bourne重新使用在常用的Unix Bourne shell之中。

一個表達式還可以產生多元值（multiple value）即有多個元素的一個值，它是通過「並立子句」（collateral clause）從其他一些值構造出來的。這種構造看起來就像過程調用的參數包（pack）。

### 模態

數據類型在ALGOL 68用語中叫做「模態」（mode），其原始模態的聲明符為：`'''INT'''`、`'''REAL'''`、`'''COMPL'''`（複數）、`'''BOOL'''`、`'''CHAR'''`、`'''BITS'''`、`'''BYTES'''`和`'''STRING'''`。ALGOL 68不再定義`long`、`short`和`double`這樣的類型，而是提供了修飾符（modifier）`'''LONG'''`和`'''SHORT'''`。

- `'''BITS'''` – `'''BOOL'''`值的壓縮向量（packed vector）。
- `'''BYTES'''` – `'''CHAR'''`值的固定大小的緊緻多元組（即陣列）。
- `'''STRING'''` – `'''CHAR'''`值的`'''FLEX''' [1 : 0]`（聲明時無元素）的靈活多元組（即陣列）。
- `'''LONG'''` – 聲明`'''INT'''`、`'''REAL'''`或`'''COMPL'''`的大小為`'''LONG'''`。
- `'''SHORT'''` – 聲明`'''INT'''`、`'''REAL'''`或`'''COMPL'''`的大小為`'''SHORT'''`。

ALGOL 68提供了預置常量（prelude constant）如`max real`和`long max real`等來將程序適配到不同實現之中。

複雜模態可以使用模態構造子`'''REF'''`、`'''STRUCT'''`、`'''UNION'''`和`'''PROC'''`來創建自更簡單的模態：

- `'''REF''' mode` – 到模態`mode`的值的引用，類似於C/C++中和Pascal中的指針。
- `'''STRUCT'''` – 用來建造結構，類似於C/C++中的`struct`和Pascal中的`recode`。
- `'''UNION'''` – 用來建造聯合，類似於C/C++和Pascal中的`union`。
- `'''PROC'''` – 用來指定過程，類似於C/C++中的函數和Pascal中的過程/函數。

在一個代碼塊中，諸聲明不必須都先於諸語句，但所有名字都必須在使用前聲明。ALGOL 68提供了恆等聲明來將標識符綁定到常量值之上。在聲明給名字的標識符之時，這個名字可以被初始化為立即引用一個值；還可以將名字聲明為等同於以前聲明的名字而使得二者互為別名。例如：

```
'''INT''' n = 2;  # n是新建的常量，它被固定为2 #
'''INT''' m := 3;  # m是新建的局部变量的名字，这个变量的值被初始化为3 #
'''INT''' p = m;  # p是新建的常量，它被固定为同于m当前的值 #
'''INT''' q := m;  # q是新建的局部变量的名字，这个变量的值被初始化为同于m当前的值 #
'''REF INT''' r = m;  # r是新建的变量名字，它与m引用的是同一个变量 #
'''REAL''' avogadro = 6.02214076'''E'''23;  # 阿伏伽德罗常数 #
'''LONG REAL''' long pi = 3.14159 26535 89793 23846 26433 832795;
'''COMPL''' imaginary unit = 0 '''I''' 1;  # 虚数单位i即复数0 + 1i #
```

其他聲明符號包括：`'''FLEX'''`、`'''HEAP'''`和`'''LOC'''`。

- `'''FLEX'''` – 所聲明的名字是靈活的，就是說它可以引用任何數量元素的多元組（即陣列）。
- `'''HEAP'''` – 為變量從全局堆中分配一些空閒空間。
- `'''LOC'''` – 為變量分配這個局部棧的一些空閒空間。

聲明`'''REAL''' x`只是`'''REF''' '''REAL''' x = '''LOC''' '''REAL'''`的語法糖，`'''LOC''' '''REAL'''`是生成`'''REF''' '''REAL'''`模態的名字的單元。在`'''REF''' '''REAL''' x = '''LOC''' '''REAL''' := 0`中，賦值`'''LOC''' '''REAL''' := 0`導致整數`0`在被賦值給這個生成器產生的名字之前就被擴充（widen）為實數`0.0`，聲明的名字`x`與生成器產生的名字二者所引用的是同一個變量。

原始聲明符還包括：`'''FORMAT'''`、`'''FILE'''`、`'''CHANNEL'''`、`'''SEMA'''`、`'''COMPLEX'''`G和`'''PIPE'''`G。

- `'''SEMA'''` – 可以通過運算符`'''LEVEL'''`初始化的信號量。

ALGOL 68使用`'''MODE'''`聲明來給模態聲明名字，它類似於C/C+中的`typedef`和Pascal中的`type`：

```
'''INT''' max = 99;
'''MODE''' NEWMODE = [0:9][0:max]'''STRUCT''' (
    '''LONG''' '''REAL''' a, b, c, '''SHORT''' '''INT''' i, j, k, '''REF''' '''REAL''' r);
```

這類似於如下C99代碼：

```c
const int max = 99;
typedef struct {
    double a, b, c; short i, j, k; float *r;
} newmode[9+1][max+1];
```

對於ALGOL 68，只有模態標示（indicant）`NEWMODE`出現在等號的左側，最值得注意的是，構造的製造和讀取，是從左至右而不顧及優先級的。還有ALGOL 68多元組（陣列）的下界預設的是`1`，但也可以是從`-max int`到`max int`的任何整數。

模態聲明允許遞歸模態，就是說模態可直接或間接的依據自身來進行定義。這要服從一些限制，例如下列聲明是非法的：

```
'''MODE''' A = '''REF''' A;
'''MODE''' A = '''STRUCT''' (A a, B b);
'''MODE''' A = '''PROC''' (A a) A;
```

而下列聲明是有效的：

```
'''MODE''' A = '''STRUCT''' ('''REF''' A a, B b);
'''MODE''' A = '''PROC''' ('''REF''' A a) '''REF''' A;
```

### 注釋和編譯指導

注釋可以按各種方式插入：

```
¢ 最初方式是在程序中增加两个美分符号 ¢
'''COMMENT''' "粗体"注释 '''COMMENT'''
'''CO''' 风格i注释 '''CO'''
# 风格ii注释 #
£ 针对英国键盘的横杠/英镑注释 £
```

一般而言，注釋在ALGOL 68中不能嵌套。這個限制可以使用不同的注釋分界符來繞過。

語用指定（pragmat）是在程序中的編譯指導，典型的提示給編譯器；在新近的語言中叫做「pragma」。例如：

```
'''PRAGMAT''' heap=32 '''PRAGMAT'''
'''PR''' heap=32 '''PR'''
```

### 表達式和複合語句

ALGOL 68成為了面向表達式程式語言，賦值語句所返回的值是到目的地的引用。因此下列代碼在ALGOL 68中是有效的：

```
'''REAL''' half pi, one pi; one pi := 2*(half pi := 2*arc tan(1))
```

這種表示法也出現在C語言和Perl以及其他一些語言之中。注意在早期語言比如ALGOL 60和FORTRAN中，在標識符中的空格是允許的，所以`half pi`是一個單一的標識符，因而無需採用蛇形命名法或駝峰式大小寫。

另一個例子，要表達數學中`f(i)`從`i=1`到`n`的總和，下列ALGOL 68整數表達式就可充任：

```
('''INT''' sum := 0; '''FOR''' i '''TO''' n '''DO''' sum +:= f(i) '''OD'''; sum)
```

注意，作為整數表達式，上述的代碼塊可以用在「整數值可以使用的任何上下」之中。代碼塊在ALGOL 68稱為「系列子句」（serial clause），它返回其中被求值的最後一個表達式的值；這個概念也出現在LISP以及其他一些語言之上。系列子句加上封閉它的一對圓括號或`'''BEGIN'''`與`'''END'''`叫做閉合子句（closed-clause）。

複合語句都終止於獨特的閉括號：

#### IF選擇子句

```
'''IF''' 条件 '''THEN''' 诸语句 [ '''ELSE''' 诸语句 ] '''FI'''
<small>简短形式：</small>( 条件 | 诸语句 | 诸语句 )

'''IF''' 条件1 '''THEN''' 诸语句 '''ELIF''' 条件2 '''THEN''' 诸语句 [ '''ELSE''' 诸语句 ] '''FI'''
<small>简短形式：</small>( 条件1 | 诸语句 |: 条件2 | 诸语句 | 诸语句 )
```

這種方案不僅避免了懸擺else問題，還避免了必須對嵌入的語句序列使用`'''BEGIN'''`和`'''END'''`。

#### CASE選擇子句

```
'''CASE''' 接转 '''IN''' 诸语句, 诸语句, ... [ '''OUT''' 诸语句 ] '''ESAC'''
<small>简短形式：</small>( 接转 | 诸语句, 诸语句, ... | 诸语句 )

'''CASE''' 接转1 '''IN''' 诸语句, 诸语句, ... '''OUSE''' 接转2 '''IN''' 诸语句, 诸语句, ... [ '''OUT''' 诸语句 ] '''ESAC'''
<small>简短形式：</small>( 接转1 | 诸语句, 诸语句, ... |: 接转2 | 诸语句, 诸语句, ... | 诸语句 )
```

採用粗體符號的選擇子句的例子：

```
'''PROC''' days in month = ('''INT''' year, month) '''INT''':
    '''CASE''' month '''IN'''
    #一月# 31,
    #二月# '''IF''' year '''MOD''' 4 '''EQ''' 0 '''AND''' year '''MOD''' 100 '''NE''' 0 '''OR''' year '''MOD''' 400 '''EQ''' 0 '''THEN''' 29 '''ELSE''' 28 '''FI''',
          31, 30, 31, 30, 31, 31, 30, 31, 30, 31 # 直到十二月 #
    '''ESAC''';
```

採用簡短符號的選擇子句的例子：

```
'''PROC''' days in month = ('''INT''' year, month) '''INT''':
    (month|
     31,
     (year%*4 = 0 '''AND''' year%*100 /= 0 '''OR''' year%*400 = 0 | 29 | 28),
     31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
```

粗體和簡短符號的選擇子句可以混合使用。

ALGOL 68允許接轉（switch）具有的類型，要麼是`'''INT'''`要麼是（獨有的）`'''UNION'''`。後者允許在`'''UNION'''`變量上施加強類型，參見後面的聯合例子。

#### DO循環子句

```
[ '''FOR''' 索引 ] [ '''FROM''' 第一个 ] [ '''BY''' 增量 ] [ '''TO''' 最后一个 ] [ '''WHILE''' 条件  ] '''DO''' 诸语句 '''OD'''
```

循環語句的極小化形式是：`'''DO''' 诸语句 '''OD'''`。

下面是這種「通用」循循的完整例子：

```
'''FOR''' i '''FROM''' 1 '''BY''' -22 '''TO''' -333 '''WHILE''' i*i /= 4444 '''DO''' ~ '''OD'''
```

這個構造有一些不尋常的方面：

- 只有`'''DO''' ~ '''OD'''`部份是強制性的，在這種情況下循環將無限迭代。
- 因此子句`'''TO''' 100 '''DO''' ~ '''OD'''`，將只迭代100次。
- `'''WHILE'''`「語法元素」允許編程者更早的從`'''FOR'''`循環中破出，例如：

```
'''INT''' sum sq := 0;
'''FOR''' i
'''WHILE'''
    print(("So far:", i, newline));
    sum sq /= 70**2
'''DO'''
    sum sq +:= i**2
'''OD'''
```

後續的對標準ALGOL 68的擴展，允許`'''TO'''`語法元素被替代為`'''UPTO'''`和`'''DOWNTO'''`來達成小優化。這些編譯器還結合了：

- `'''UNTIL'''`C – 用於更晚的循環終止。
- `'''FOREACH'''`S – 用於並行的運算於多元組（陣列）之上。

### 結構與聯合

ALGOL 68支持多欄位結構`'''STRUCT'''`和標籤聯合`'''UNION'''`。`'''REF'''`可以前導於任何`'''MODE'''`，包括多元組分片和結構欄位。

作為遞歸模態的例子，下面是傳統的鍊表的聲明：

```
'''MODE'''
    VALUE = '''UNION''' ('''VOID''', '''REAL''', '''INT''', '''COMPL''', '''STRING'''),
    NODE = '''STRUCT''' (VALUE val, '''REF''' NODE next),
    LIST = '''REF''' NODE;
```

對上述`VALUE`的`'''UNION'''`使用共形子句（conformity clause）的`'''CASE'''`的例子：

```
VALUE v := "1234";  # 或者 v := '''EMPTY'''; #
'''CASE''' v '''IN'''
    ('''VOID'''):     print(("void:", "EMPTY")),
    ('''REAL''' r):   print(("real:", r)),
    ('''INT''' i):    print(("int:", i)),
    ('''COMPL''' c):  print(("compl:", c)),
    ('''STRING''' s): print(("string:", s))
    '''OUT'''         print("undefined value")
'''ESAC'''
```

在未修訂報告的語言中共形子句的功能通過在`'''CASE'''`子句中採用共形關係`'''CTAB'''`來實現。

### 多元組

在ALGOL 68中，不再採用術語陣列或陣列（array），轉而基於數學中的$n$元組（$n$-tuple）定義了多元值（multiple value）亦簡稱多元組（multiple）。多元組由一定數量的元素組成，每個元素都有相同的模態，有時稱之為基礎模態。多元組的模態由前導著一對方括號的針對每個元素的模態標示組成，它被讀作「行主序和列主序的模態」（row of mode），它不同於函數式程式語言如ML中的對應於代數數據類型里積類型的「元組」（tuple）。

ALGOL 68多元組的屬性之一是它的維度數目。可以聲明任何數目維度的多元組，整數的二維多元組擁有模態`[,]'''INT'''`，它被讀作「行套行的整數」（row-row-of-int），而實數的三維多元組擁有模態`[,,]'''REAL'''`。

```
'''MODE''' VECTOR = [1:3]'''REAL''';  # 向量'''MODE'''声明 #
'''MODE''' MATRIX = [1:3,1:3]'''REAL''';  # 矩阵'''MODE'''声明 #
VECTOR v1 := (1,2,3);  # 向量变量初始化为 (1,2,3) #
[]'''REAL''' v2 = (4,5,6);  # 常量元组，类型等价于VECTOR，边界是隐含的 #
'''OP''' + = (VECTOR a, b) VECTOR:  # 二元'''OP'''即运算符定义 #
    (VECTOR out; '''FOR''' i '''FROM''' '''LWB''' a '''TO''' '''UPB''' a '''DO''' out[i] := a[i]+b[i] '''OD'''; out);
MATRIX m := (v1, v2, v1+v2);
```

這裡的冒號分隔構造：`<small>第一个元素的下标</small> : <small>最后一个元素的下标</small>`，被稱為裁剪器（trimmer）。

ALGOL 68的陣列分片，在概念上涵蓋了向多元組的各個維度加下標與上標（subscript）從而訪問其中特定元素的常規情況，但這個術語更常用的保留給至少一個維度不加下標的情況，比如從矩陣中切分出部份橫行（row）或縱列（column）。例如：

```
'''REF''' VECTOR row = m[2,];  # 定义一个'''REF'''至矩阵的第二个横行 #
'''REF''' VECTOR col = m[,2];  # 定义一个'''REF'''至矩阵的第二个纵列 #
print ((m[,2:]));  # 打印矩阵的从第二个至最后一个的纵列 #
```

省略了裁剪器中第一個下標則假定其為此維度的下界，而省略了第二個下標則將假定其為對應的上界，兩個下標都省略則產生下界為`1`的全部分片。

### 過程

過程（procedure）的`'''PROC'''`聲明對參數和結果值二者要求類型指定，如果沒有參數則省略參數列表，如果沒有結果值則指定結果模態為`'''VOID'''`：

```
'''PROC''' max of real = ('''REAL''' a, b) '''REAL''': (a > b | a | b);
```

過程的返回值是在過程中求值的最後一個的表達式的值。當進行如下過程調用之時：

```
a := max of real(x, y)
```

得到等價於進行了如下變換後的結果：

```
a := '''REAL''' ('''REAL''' a = x, b = y; (a > b | a | b))
```

在這個過程之內對變量`a`和`b`的賦值是非法的。針對需要變更形式參數所提及的值的情況，ALGOL 68提供了傳引用調用參數，用來在形式參數列表中指定引用，比如`'''REF REAL'''`。到過程的引用`'''REF PROC'''`也是允許的。下列例子定義一個過程，它將作為參數而指定的一個函數應用於一個陣列的每個元素：

```
'''PROC''' apply = ('''REF''' []'''REAL''' a, '''PROC''' ('''REAL''') '''REAL''' f) '''VOID''':
    '''FOR''' i '''FROM''' '''LWB''' a '''TO''' '''UPB''' a '''DO''' a[i] := f(a[i]) '''OD''';
```

這種代碼的簡單性是在ALGOL 68的前身ALGOL 60中不能達成的。

### 運算符與關聯名字的單元

過程和運算符（operator）合稱例程（routine），編程者可以定義新的運算符，並且這些自定義的和預定義的運算符二者都可以重載，並且它們的優先級可以由編碼者變更。下列例子定義的運算符`MAX`具有二元和一元形式二者，一元形式在一個陣列的元素之上進行掃描。

```
'''PRIO''' MAX = 9;
'''OP''' MAX = ('''INT''' a, b) '''INT''': (a > b | a | b);
'''OP''' MAX = ('''REAL''' a, b) '''REAL''': (a > b | a | b);
'''OP''' MAX = ('''COMPL''' a, b) '''COMPL''': ('''ABS''' a > '''ABS''' b | a | b);
'''OP''' MAX = ([]'''REAL''' a) '''REAL''':
    ('''REAL''' out := a['''LWB''' a];
     '''FOR''' i '''FROM''' '''LWB''' a + 1 '''TO''' '''UPB''' a '''DO''' (a[i] > out | out := a[i]) '''OD''';
     out);
```

#### 初等和二等單元

初等單元（primary）涵蓋封閉子句，此類屬自身包括：所應用的標識符、調用、鑄型、除了例程指示之外的指示和分片。

所應用的標識符（applied-identifier）意味著標識符在一個上下文之中被使用，並非處在其定義之中。

指示（denotation）是其所產生與任何行動都無關的構造，比如實數指示`3.14`或字串指示`"abc"`，模態`'''VOID'''`只有一個值，其指示是`'''EMPTY'''`。在其他語言中，指示有時叫做「文字 (電腦編程)」（literal）或「常值」（constant）。

鑄型（cast）構成自一個模態標示（indicant）和隨後的通常為閉合子句的封閉子句。鑄型可被用來提供強位置，在強上下文中能獲得所有的強制。例如在`'''REF''' '''REAL''' (xx) := 1`中的`'''REF''' '''REAL''' (xx)`。

調用（call）引起（invoke）一個過程，調用在ALGOL 68 Genie中可以被部份參數化（partial parameterisation）：就是說增加實際參數到一個過程的語境（locale）中，當這個語境完全之時調用這個過程，否則發生柯里化。

優先級｜ALGOL68r1「值當字符」｜ALGOL68G

相當於12｜加下標`[~]`，分片`[~,~]`，裁剪`[~:~]`，`'''AT'''` `@`｜`'''DIAG'''`，`'''TRNSP'''`，`'''ROW'''`，`'''COL'''`

二等單元（secondary）包括生成器（generator）和選取（selection）。

優先級｜ALGOL68r1「值當字符」｜ALGOL68r0−r1｜ALGOL68G

相當於11｜`'''OF'''`，`'''LOC'''`，`'''HEAP'''`｜`→`｜`'''NEW'''`

有關的符號在技術上不是運算符，它們轉而被當作「關聯名字的單元」。

#### 三等單元

三等單元（tertiary）包括公式和`'''NIL'''`（可替代為`○`）。公式構成自運算符和運算元。

在ALGOL 68中對於名字只有一個指示，那就是含義為不引用任何值的`'''NIL'''`。`'''NIL'''`的模態依賴於上下文，例如：`'''REF''' '''INT''' k = '''NIL'''`，這裡的`'''NIL'''`擁有模態`'''REF''' '''INT'''`。儘管`'''NIL'''`是一個名字卻不可以對它賦值。

##### 一元運算符

優先級｜ALGOL68r1「值當字符」｜ALGOL68r1替代符號｜ALGOL68C,G｜ALGOL68r0-r1

相當於10｜`'''NOT'''`，`-`，`'''UP'''`，`'''DOWN'''`，`'''LWB'''`，`'''UPB'''`，`'''ABS'''`，`'''ARG'''`，`'''BIN'''`，`'''ENTIER'''`，`'''LENG'''`，`'''LEVEL'''`，`'''ODD'''`，`'''REPR'''`，`'''ROUND'''`，`'''SHORTEN'''`｜`¬` `~`，`↑`，`↓`，`⌊`，`⌈`｜`'''NORM'''`，`'''TRACE'''`，`'''T'''`，`'''DET'''`，`'''INV'''`｜`'''LWS'''` `⎩`，`'''UPS'''` `⎧`，`'''BTB'''`，`'''CTB'''`

##### 二元運算符及其關聯的優先級

優先級｜ALGOL68r1「值當字符」｜ALGOL68r1替代符號｜ALGOL68r0−r1

9｜`'''I'''` `+*`｜`⊥` `+×`｜`!`

8｜`'''UP'''` `**`，`'''DOWN'''`，`'''LWB'''`，`'''UPB'''`，`'''SHL'''`，`'''SHR'''`｜`↑`，`↓`，`⌊`，`⌈`｜`^` `××`，`'''LWS'''` `⎩`，`'''UPS'''` `⎧`

7｜`*`，`/`，`'''OVER'''` `%`，`'''MOD'''` `%*`，`'''ELEM'''`｜`×`，`÷`，`÷×` `÷*` `%×`，`□`｜`÷:`

6｜`-`，`+`

5｜`'''LT'''` `<`，`'''LE'''` `<=`，`'''GE'''` `>=`，`'''GT'''` `>`｜`≤`，`≥`

4｜`'''EQ'''` `=`，`'''NE'''` `/=`｜`≠` `¬=` `~=`

3｜`'''AND'''`｜`∧` `&`｜`/\`

2｜`'''OR'''`｜`∨`｜`\/`

1｜`'''MINUSAB'''` `-:=`，`'''PLUSAB'''` `+:=`，`'''TIMESAB'''` `*:=`，`'''DIVAB'''` `/:=`，`'''OVERAB'''` `%:=`，`'''MODAB'''` `%*:=`，`'''PLUSTO'''` `+=:`｜`×:=`，`÷:=`，`÷×:=` `÷*:=` `%×:=`｜`'''MINUS'''`，`'''PLUS'''`，`'''TIMES'''`，`'''DIV'''`，`'''OVERB'''`，`'''MODB'''` `÷::=`，`'''PRUS'''`

`'''LWB'''`（可替代為`⌊`）和`'''UPB'''`（可替代為`⌈`），這兩個運算符所運算的多元組運算元的模態是`ROW`，它是指稱任何行主序和列主序的模態。在未修訂報告的語言中，`'''LWS'''`（可替代為`⎩`）和`'''UPS'''`（可替代為`⎧`），分別是在一個多元組（陣列）的這個維度的「下界狀態」和「上界狀態」為固定的（fixed）的情況下返回`'''TRUE'''`。

#### 四等單元

四等單元（quaternary）包括：賦值、同一關係、例程指示（也稱作例程正文）和`'''SKIP'''`（可替代為`~`）。四等單元並非語言報告中的術語，它是給從單元這個類屬中除去封閉子句、初等單元、二等單元和三等單元所餘下的只稱為「單元」的類屬的別名。

`'''SKIP'''`產生任何模態的未定義的值，並且只能出現在強上下文中。

優先級｜ALGOL68r1「值當字符」｜ALGOL68r1替代符號｜ALGOL68C,R｜ALGOL68r0−r1

相當於0｜`:=`，`'''IS'''` `:=:`，`'''ISNT'''` `:/=:`｜`:≠:` `:¬=:` `:~=:`｜`:=:=`C，`=:=`R｜`..=` `.=`，`'''IS NOT'''`，`'''CT'''` `::`，`'''CTAB'''` `::=`

在ALGOL 68中除了恆等聲明之外的所有構造都有一個值，它允許鏈式賦值，例如`a := b := c`，這些賦值是從右至左執行的。

同一關係包括：`'''IS'''`（可替代為`:=:`）測試兩個引用是否相等；`'''ISNT'''`（可替代為`:/=:`）測試兩個引用是否不相等。同一關係的一側是可以在強制時解引用來匹配另一側的強側，而另一側則為軟側，不允許兩側都解引用。

### 強制

強制（coercion）依據三個要件，從被強制者（coercend）產生已強制者（coercee）：在應用任何強制之前作為要被強制者的一個先驗模態，在這些強制之後作為已被強制者的一個後驗模態，已強制者的的語法位置（position）或類屬（sort）。強制是可以級聯的（cascaded）。

有7種可能的強制，其術語為解過程化（deproceduring），解引用（dereferencing）和弱解引用（weakly-dereferencing），聯合化（uniting），擴充（widening）、入行（rowing）和棄置（voiding）。除了聯合化之外，每種強制都在所關聯的值之上，規制（prescribe）一個相應的動態效果。因此，可以使用強制來編程很多原始行動。

允許特定強制的境況（circumstance）叫做上下文（context）。下面列出每種上下文所固有的強度及其允許的強制：

- 軟（soft）– 解過程化。
- 弱（weak) – 軟強制，隨後弱解引用而產生一個名字。
- 柔（meek）– 軟強制，隨後解引用。
- 硬（firm）– 柔強制，隨後聯合化。
- 強（strong）– 硬強制，隨後擴充、入行或棄置。

在任何上下文中，都有擁有或產生某種模態的值的一個單元，並且在這個上下文中亦有所需的一個模態。如果兩個模態不同而現有模態的值能夠強制成所需模態的值，則這種強制是合法的。

平衡是將`'''IF'''`、`'''CASE'''`和共形子句中的交替者（alternative）即可供選擇者，和同一關係的兩側，都強制成共同（common）的模態的手段，這使得所涉及構造的上下文會被提升（promote）從而獲得這種強制。

#### 強制層級及例子

ALGOL 68有著上下文層級，它確定在程序中特定點之上可獲得的強制的種類。這種上下文分為五個層次：

上下文｜上下文位置｜可獲得的強制｜在此上下文中強制例子

軟｜弱｜柔｜硬｜強

強｜、恆等（identity）聲明的右手側，如`~`之於`'''REAL''' …… = ~`、初始化的名字聲明的右手側，如`~`之於`'''REAL''' …… := ~`、賦值的右手側，如`~`之於`…… := ~`、調用的實際參數，如`~`之於`……(~)`、鑄型（cast）的封閉子句，如`~`之於`'''REAL'''(~)`、例程指示的單元、產生`'''VOID'''`的單元、平衡（balanced）子句的除第一部份之外的所有部份、同一關係的一側，它可能需要解引用來適配於另一側，如`xx`之於`xx := x; xx '''IS''' x`｜解過程化｜只在弱上下文時軟強制再弱解引用｜軟強制再解引用｜柔強制再聯合化｜硬強制再擴充或入行或棄置｜擴充出現在沒有精度損失的情況下。例如：、LONG INT$\,\Longleftarrow\,$INT、REAL$\,\Longleftarrow\,$INT、LONG REAL$\,\Longleftarrow\,$REAL、COMPL$\,\Longleftarrow\,$REAL、BOOL$\,\Longleftarrow\,$BITS、STRING$\,\Longleftarrow\,$BYTES 變量可以入行為長度為1的多元組。例如:、1INT$\,\Longleftarrow\,$INT、1REAL$\,\Longleftarrow\,$REAL

硬｜、公式的運算元，如`~`之於`~ + ~`、傳輸調用的實際參數｜例子： UNION(INT, REAL) var := 1

柔｜、剪標（trimscript）：裁剪器、下標和邊界，產生`'''INT'''`、質詢（enquiry）子句，如`~`之於`'''IF''' ~ '''THEN''' …… '''FI'''`和 `'''FROM''' ~ '''BY''' ~ '''TO''' ~ '''WHILE''' ~ '''DO''' …… '''OD'''`、調用的初等單元（被調用者），如`~`之於`~(……)`｜例子：、BOOL$\,\Longleftarrow\,$REF REF BOOL、INT$\,\Longleftarrow\,$REF REF REF INT

弱｜、分片的初等單元（被分片者），如`~`之於`~[……]`、選取的二等單元（被選取者），如`~`之於`…… '''OF''' ~`｜例子：、REF INT$\,\Longleftarrow\,$REF REF INT、REF REAL$\,\Longleftarrow\,$REF REF REF REAL、REF STRUCT$\,\Longleftarrow\,$REF REF REF REF STRUCT

軟｜、賦值的左手側，如`~`之於`~ := ……`、同一關係的另一側，它被其中一側可能需要解引用來匹配，如`x`之於`xx := x; xx '''IS''' x`｜例子：標準預置中的random擁有模態PROC REAL，在調用它之時發生REAL$\,\Longleftarrow\,$PROC REAL。PROC REAL rnd := random所定義的rnd擁有模態REF PROC REAL，單獨使用它即rnd;之時，進行解引用接著解過程化並棄置結果的REAL。

### 正交性

ALGOL 68文法的表達依據了一些原始概念：值、模態、上下文、強制和短語（phrase）。短語是聲明和單元二者之一。共有5種上下文、7種強制、22種不同的單元，和潛在無窮數量的值和模態。在每種上下文中都有可獲得的強制。

正交性所稱謂的是基本概念可以被沒有副作用的組合。原始概念：值、模態、上下文、強制和短語，是相互獨立的，它們的組合給予了ALGOL 68少有程式語言擁有的靈活性。舉個例子，如果需要模態`'''INT'''`的一個值，比如在多元組的聲明的裁剪器或邊界中，那麼在這個上下文中任何會產生一個整數的單元都可充任。其結果是ALGOL 68程序可以用寬廣多樣的風格來書寫。例如列印從鍵盤讀取的兩個數的總和，用常規風格可以寫為：

```
'''INT''' a, b;
read((a, b));
print((a + b, newline))
```

也可以等價的寫為：

```
print((('''INT''' a, b;
    read((a, b));
    a + b), newline))
```

只要所書寫的是合法的ALGOL 68代碼，可以採用編程者喜好的任何方式。這種獨立性的另一個結果是語言的規則極少有例外。

### 傳輸

傳輸（transput）是ALGOL 68用來稱謂輸入和輸出設施的術語。它包括針對非格式化、格式化和二進位傳輸的預定義的過程。文件和其他傳輸設備以機器無關的方式來處理。下面的例子列印出一些非格式化的輸出到「標準輸出」設備：

```
print ((newpage, "Title", newline, "Value of i is ",
    i, "and x[i] is ", x[i], newline))
```

注意預定義的過程`newpage`和`newline`作為實際參數而傳送。

`print`和`read`接受可能具有各種所需模態的實際參數，這些例程的形式參數具有成行的聯合模態：

```
'''PROC''' print = ([]SIMPLOUT items) '''VOID''': …… ;
'''MODE''' SIMPLOUT = '''UNION''' (
    '''INT''', '''REAL''', '''BOOL''', '''CHAR''',
    []'''INT''', []'''REAL''', []'''BOO'''L, []'''CHAR''',
    [,]'''INT''', [,]'''REAL''', [,]'''BOOL''', [,]'''CHAR''',
    …… );
'''PROC''' read = ([]SIMPLIN items) '''VOID''': …… ;
'''MODE''' SIMPLIN = '''UNION''' (
    '''REF''' '''INT''', '''REF''' '''REAL''', '''REF''' '''BOOL''', '''REF''' '''CHAR''',
    '''REF''' []'''INT''', '''REF''' []'''REAL''', '''REF''' []'''BOOL''', '''REF''' []'''CHAR''',
    '''REF''' [,]'''INT''', '''REF''' [,]'''REAL''', '''REF''' [,]'''BOOL''', '''REF''' [,]'''CHAR''',
    …… );
```

`read`使用的模態`SIMPLIN`是來自各種名字的模態的聯合。`print`使用共形子句來從參數行中每個元素提取出實際的值。

在ALGOL 68中「格式化傳輸」擁有自己的語法和模式（函數），具有嵌入在兩個`$`字符之間的`'''FORMAT'''`。例如：

```
printf (($2l"The sum is:"x, g(0)$, m + n)); # 其打印相同于下列： #
print (new line, new line, "The sum is:", space, whole(m + n, 0))
```

### 並行處理

ALGOL 68支持並行處理編程。使用關鍵字`'''PAR'''`，可以將「並立子句」轉換成「並行子句」，這裡的行動的同步使用信號量來控制。並行行動在ALOGL 68 Genie中被映射到線程上，如果它們在宿主作業系統上能獲得到的話。例如：

```
'''PROC'''
    eat = '''VOID''': (muffins -:= 1; print(("Yum!", newline))),
    speak = '''VOID''': (words -:= 1; print(("Yak...", newline)));
'''INT''' muffins := 4, words := 8;
'''SEMA''' mouth = '''LEVEL''' 1;
'''PAR''' '''BEGIN'''
    '''WHILE''' muffins > 0 '''DO'''
        '''DOWN''' mouth;
        eat;
        '''UP''' mouth
    '''OD''',
    '''WHILE''' words > 0 '''DO'''
        '''DOWN''' mouth;
        speak;
        '''UP''' mouth
    '''OD'''
'''END'''
```

### 未修訂報告的語言

原本依據1968年最終報告的語言在模態鑄型的語法上有所不同，並且它擁有過程化（proceduring）這個特徵，就是說，將一個項目的值強制成求值這個項目的一個過程。過程化意圖進行惰性求值。最有用的應用是實現布爾運算符的短路求值：

```
'''OP''' ANDF = ('''BOOL''' a, '''PROC''' '''BOOL''' b) '''BOOL''': (a | b | '''FALSE''');
'''OP''' ORF = ('''BOOL''' a, '''PROC''' '''BOOL''' b) '''BOOL''': (a | '''TRUE''' | b);
```

在`ANDF`中，`b`只在`a`為`'''TRUE'''`的情況下才求值。預期下面例子中的`print`不會被執行：

```
'''IF''' '''FALSE''' ANDF (print("Should not be executed"); '''TRUE''') '''THEN''' …… '''FI'''
```

語言修訂之後，已經不再允許這種從模態`'''BOOL'''`到模態`'''PROC''' '''BOOL'''`的強制和鑄型。ALGOL 68 Genie將`ANDF`和`ORF`作為擴展而實現為偽運算符。

在語言修訂之前，編程者可以通過使用叫做「gomma」的分號替代逗號（comma），從而決定一個過程的參數串行而非並立的求值。例如：

```
'''PROC''' test = ('''REAL''' a; '''REAL''' b): …… ;
test (x +:= 1, x);
```

這裡保證第一個實際參數求值在第二個實際參數之前，但是在平常情況：

```
'''PROC''' test = ('''REAL''' a, b): …… ;
test (x +:= 1, x);
```

這時編譯器可以按它喜好的次序來求值實際參數。

## 外部連結

- Revised Report on the Algorithmic Language ALGOL 68 The official reference for users and implementors of the language (large pdf file, scanned from Algol Bulletin)
- Revised Report on the Algorithmic Language ALGOL 68 Hyperlinked HTML version of the Revised Report
- A Tutorial on Algol 68, by Andrew S. Tanenbaum, in Computing Surveys, Vol. 8, No. 2, June 1976, with Corrigenda (Vol. 9, No. 3, September 1977)
- Algol 68 Genie – a GNU GPL Algol 68 compiler-interpreter
- Open source Algol 68 implementations, on SourceForge
- Algol68 Standard Hardware representation
- Из истории создания компилятора с Алгол 68
- Algol 68 – 25 Years in the USSR
- McJones, Paul, "Algol 68 implementations and dialects", Software Preservation Group, Computer History Museum, 2011-07-05

## 基本資料

- 編程范型：多范型：指令式，過程式，結構化，並發
- 設計者：阿德里安·范·韋恩加登, Barry J. Mailloux, John E. L. Peck, Cornelis H.A. Koster等人
- 發行日期：最終報告: 1968年、修訂報告: 1973年
- 類型系統：靜態、強類型、安全、結構類型系統
- 軟體實現：Algol68toC, ALGOL 68 Genie, ALGOL 68-R, ALGOL 68C, ALGOL 68RS, ALGOL 68S, FLACC
- dialects：ALGOL 68r0 (最終報告：1968年)、ALGOL 68r1 (修訂報告：1973年)
- 受影響於：ALGOL 60, ALGOL X, ALGOL Y
- 施影響於：C、C++、Bourne shell、KornShell、Bash、Steelman語言要求、Ada、Python、Seed7、Mary (程式語言)、S3 (程式語言)