ALGOL 68

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

ALGOL 68 的特徵包括的語法，使用者宣告的型別和結構與標籤聯合型別，變數與引用引數的引用模型，可變長陣列和字串、陣列與矩陣的，使用者定義的運算子和運算子過載，高階函式與匿名函式，以及併發。

概論

ALGOL 68 由負責設計。1968 年 12 月 20 日，IFIP 工作組 2.1 透過了這個語法規範，並提交 IFIP 大會透過且出版。

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

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

描述的完備性和清晰性；
設計的正交性；
安全性；
高效性：
* 靜態的模態（即型別）檢查，
* 模態無關的解析，
* 分立編譯，
* 迴圈最佳化，
* 表示於極小化和更大的字元集。

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

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

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

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

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

規定和實現時間線

樣例程式碼

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

PROGRAM helloworld CONTEXT VOID

USE standard

BEGIN

print (("hello, world!", newline))

END

FINISH

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

$ ca -u ASDFGHJ helloworld.a68

$ ./helloworld

hello, world!

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

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 直譯器執行它：

$ 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

顯著的語言元素

4.1 符號和保留字

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

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 →r0，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 □r0。

GO TO 被當作兩個保留字，未修訂報告的語言還有保留字 EITHER 和 IS NOT 結合。

4.2 符號表示

“臻選字元”（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 " # $ % ' ( ) * + , - . / : ; @ _ |

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

傳輸表示採用 “臻選字元” 時，“加上乘以” 符號⊥替代為 I，“乘以的冪” 符號⏨和 \ 替代為 E。

配備 APL 打字球與鍵帽後的終端的鍵盤，它不再支援小寫字母。

ALGOL 的 “特殊” 字元：

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

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

4.3 單元

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

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

一個表示式還可以產生多元值（multiple value）即有多個元素的一個值，它是透過 “並立子句”（collateral clause）從其他一些值構造出來的。這種構造看起來就像過程呼叫的引數包（pack）。

4.4 模態

資料型別在 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.02214076E23; # 阿伏伽德羅常數 #

LONG REAL long pi = 3.14159 26535 89793 23846 26433 832795;

COMPL imaginary unit = 0 I 1; # 虛數單位 i 即複數 0 + 1i #

4.5 註釋和編譯指導

4.6 表示式和複合語句

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

REAL half pi, one pi; one pi := 2(half pi := 2arc 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）。

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

4.6.1 IF 選擇子句

IF 條件 THEN 諸語句 ELSE 諸語句 FI

簡短形式：(條件 | 諸語句 | 諸語句)

IF 條件 1 THEN 諸語句 ELIF 條件 2 THEN 諸語句 ELSE 諸語句 FI

簡短形式：(條件 1 | 諸語句 |: 條件 2 | 諸語句 | 諸語句)

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

4.6.2 CASE 選擇子句

CASE 開關 IN 諸語句，諸語句，... OUT 諸語句 ESAC

簡短形式：(開關 | 諸語句，諸語句，... | 諸語句)

CASE 開關 1 IN 諸語句，諸語句，... OUSE 開關 2 IN 諸語句，諸語句，... OUT 諸語句 ESAC

簡短形式：(開關 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 變數上施加強型別，參見後面的聯合例子。

4.6.3 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 /= 702

DO

sum sq +:= i2

OD

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

UNTILC – 用於更晚的迴圈終止。
FOREACHS – 用於並行的運算於多元組（陣列）之上。

4.7 結構與聯合

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 來實現。

4.8 多元組

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

ALGOL 68 多元組的屬性之一是它的維度數目。可以宣告任何數目維度的多元組，整數的二維多元組擁有模態，INT，它被讀作 “行套行的整數”（row-row-of-int），而實數的三維多元組擁有模態，REAL。

MODE VECTOR = 1:3REAL; # 向量 MODE 宣告 #

MODE MATRIX = 1:3,1:3REAL; # 矩陣 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 outi := ai+bi OD; out);

MATRIX m := (v1, v2, v1+v2);

這裡的冒號分隔構造：第一個元素的下標：最後一個元素的下標，被稱為裁剪器（trimmer）。

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

REF VECTOR row = m2,; # 定義一個 REF 至矩陣的第二個橫行 #

REF VECTOR col = m,2; # 定義一個 REF 至矩陣的第二個縱列 #

print ((m,2:)); # 列印矩陣的從第二個至最後一個的縱列 #

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

4.9 過程

過程（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 ai := f (ai) OD;

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

4.10 運算子與關聯名字的單元

過程和運算子（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 := aLWB a;

FOR i FROM LWB a + 1 TO UPB a DO (ai> out | out := ai) OD;

out);

4.10.1 初等和二等單元

初等單元（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）中，當這個語境完全之時呼叫這個過程，否則發生柯里化。

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

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

4.10.2 三等單元

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

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

4.10.2.1 一元運算子

4.10.2.2 二元運算子及其關聯的優先順序

特殊細節：

LWS 和 UPS：在 ALGOL 68r0 中，它們分別在一個多元組（陣列）的這個維度的 “下界狀態” 和 “上界狀態” 為固定的（fixed）的情況下返回 TRUE。
LWB 和 UPB：這兩個運算子所運算的多元組運算元的模態是 ROW，它是指稱任何的模態。

4.10.3 四等單元

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

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

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

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

4.11 強制

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

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

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

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

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

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

4.11.1 強制層級及例子

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

4.12 正交性

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 程式碼，可以採用程式設計者喜好的任何方式。這種獨立性的另一個結果是語言的規則極少有例外。

4.13 傳輸

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

print ((newpage, "Title", newline, "Value of i is",

i, "and xi is", xi, newline))

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

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

PROC print = (SIMPLOUT items) VOID: …… ;

MODE SIMPLOUT = UNION (

INT, REAL, BOOL, CHAR,

INT, REAL, BOOL, 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))

4.14 並行處理

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

4.15 未修訂報告的語言

原本依據 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);

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