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

ALGOL 68
編程範型多范型指令式過程式結構化並發
設計者阿德里安·范·韋恩加登, B.J. Mailloux英語Barry J. Mailloux, J.E.L. Peck英語John E. L. Peck, C.H.A. Koster英語Cornelis H.A. Koster等人
面市時間最終報告: 1968年,​56年前​(1968
型態系統靜態強類型安全結構式英語Structural type system
網站Revised Report on the Algorithmic Language ALGOL 68
主要實作產品
ALGOL 68C英語ALGOL 68C, ALGOL 68 Genie(新近[1]), ALGOL 68-R英語ALGOL 68-R, ALGOL 68RS英語ALGOL 68RS, ALGOL 68S英語ALGOL 68S, FLACC英語FLACC, 列寧格勒ALGOL 68, Odra英語Odra (computer) ALGOL 68
衍生副語言
ALGOL 68r0 (最終報告:1968年),
ALGOL 68r1 (修訂報告:1973年)
啟發語言
ALGOL 60, ALGOL Y英語ALGOL Y
影響語言
C[2]C++[3]Bourne shellKornShellBashSteelman英語Steelman language requirementsAdaPython[4]Seed7英語Seed7Mary英語Mary (programming language)S3英語S3 (programming language)

ALGOL 68的特徵包括基於表達式英語Expression-oriented programming language的語法,用戶聲明的類型和結構/加標記的聯合,變量和引用參數的引用模型,字符串、數組和矩陣的分片,以及並發

概論

編輯

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

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

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

  1. 描述的完備性和清晰性[5]
  2. 設計的正交性[6]
  3. 安全性[5]
  4. 高效性[5]

ALGOL 68曾受到批評,最突出的是來自其設計委員會的一些成員比如C. A. R. Hoare[7],還有ALGOL 60編譯器作者比如Edsger Dijkstra[8],它拋棄了ALGOL 60的簡單性,成為了複雜或過於籠統的想法的載體,不能使編譯器作者的任務變得更輕易些,與刻意保持簡單的同時代(競爭)者如CS-algol英語S-algolPascal形成了鮮明對比。

在1970年,ALGOL 68-R英語ALGOL 68-R成為了第一個投入工作的ALGOL 68編譯器。

在1973年9月確定的修訂版本中,省略了特定特徵比如過程化、gomma和形式邊界[5]

Stephen R. Bourne是ALGOL 68修訂委員會成員,他選取了它的一些想法到他的Bourne shell之中。

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

儘管如此,ALGOL 68對計算機科學領域的貢獻是深刻、廣泛而持久的,雖然這些貢獻大多只是在它們於後來開發的程式語言中重現之時才被公開認可。很多語言是為了應對這門語言的複雜性而專門開發的,其中最著名的是Niklaus WirthALGOL WPascal[9],或者是針對特定角色而重新實現的,比如有些人認為Ada可以看作ALGOL 68的後繼者[10]

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

規定和實現時間線

編輯
名稱 用途 國家 描述 目標CPU 屬主/許可證 實現語言
廣義ALGOL 1962 科學   荷蘭 廣義文法的ALGOL[11]
ALGOL 68DR 1968 草案 Does not appear IFIP WG 2.1草案報告[12] Does not appear
ALGOL 68r0 1968 標準 Does not appear IFIP WG 2.1最終報告[13] Does not appear
ALGOL 68-R英語ALGOL 68-R 1970 軍用   英國 GEORGE 3英語GEORGE (operating system)之下的ALGOL 68 ICL 1900英語ICT 1900 series 皇家雷達研究所英語Royal Radar Establishment ALGOL 60
DTSS ALGOL 68 1970   美國 Dartmouth分時系統英語Dartmouth Time Sharing System的ALGOL 68[14] GE-635英語GE-600 series 達特茅斯學院
Mini ALGOL 68 1973 研究   荷蘭 針對簡單ALGOL 68程序的解釋器[15] 可移植解釋器 荷蘭數學中心 ALGOL 60
OREGANO 1973 研究   美國 實踐「實現模型的重要性。」[16] 加州大學洛杉磯分校
ALGOL 68C英語ALGOL 68C 1975 科學   英國 劍橋ALGOL 68 ICL英語International Computers Limited, IBM System/360, PDP-10Unix, Telefunken, Tesla & Z80 (1980)[17] 劍橋大學 ALGOL 68C
ALGOL 68r1 1975 標準 Does not appear IFIP WG 2.1修訂報告[18] Does not appear
Algol H 1975 實驗等   英國 對ALGOL 68的模態系統提議了擴展[19] ALGOL W
CDC ALGOL 68 1975 科學   美國 完全實現的ALGOL 68[20] CDC 6000系列英語CDC 6000 series, CDC Cyber 控制數據公司
Odra英語Odra (computer) ALGOL 68 1976 實用   蘇聯/  波蘭 Odra 1204/IL ALGOL 60
俄克拉何馬ALGOL 68 1976 編程指導   美國 俄克拉何馬州立大學實現[21] IBM 1130System/370 Model 158英語IBM System/370 俄克拉何馬州立大學 ANSI Fortran 66
柏林ALGOL 68 1977 研究   德國 柏林ALGOL 68實現[22] 抽象ALGOL 68機器 – 機器無關編譯器 柏林工業大學 CDL 2英語Compiler Description Language
FLACC英語FLACC 1977 多用途   加拿大 具有調試特徵的修訂報告完整實現 System/370 租用, Chion公司 彙編
ALGOL 68RS英語ALGOL 68RS 1977 軍用   英國 可移植編譯器 ICL 2900系列英語ICL 2900 Series, Multics, VMSC生成器 (1993) 皇家信號與雷達研究所英語Royal Signals and Radar Establishment ALGOL 68RS
ALGOL 68-RT英語ALGOL 68-RT 1979 科學   英國 並行ALGOL 68-R
ALGOL 68+ 1980 科學   荷蘭 提議的ALGOL 68的超語言[23]
M-220英語M-220 ALGOL 68   蘇聯 M-220 EPSILON英語EPSILON (programming language)
列寧格勒ALGOL 68 1980 電信   蘇聯 完全語言 + 模塊 IBM, DEC, CAMCOH, PS 1001 和 PC
交互式ALGOL 68英語Interactive ALGOL 68 1983   英國 增量編譯 PC 非商業共享軟體
ALGOL 68S英語ALGOL 68S 1985 科學   英國 ALGOL 68的子集語言[24] Sun-3英語Sun-3, Sun SPARC (在SunOS 4.1和Solaris 2之下), Atari ST (在GEMDOS之下), Acorn Archimedes英語Acorn Archimedes (在RISC OS之下), VAX-11英語VAX-11Ultrix-32英語Ultrix之下 曼徹斯特維多利亞大學 BLISS英語BLISS
A68toC[25] 1985 電子   英國 基於源自ELLA英語ELLA (programming language) ALGOL 68RS英語ALGOL 68RS的ctrans 可移植C生成器 國防研究局英語Defence Research Agency皇家版權開源軟體 ALGOL 68RS
MK2 交互式ALGOL 68英語Interactive ALGOL 68 1992   英國 增量編譯 PC 非商業共享軟體[26]
ALGOL 68 Genie 2001 完全語言   荷蘭 包括標準的並立子句 可移植解釋器 GNU GPL C
ALGOL 68 Genie版本2 2010 完全語言   荷蘭 可移植解釋器;可選的選定單元的編譯 GNU GPL C

樣例代碼

編輯

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

BEGIN # ALGOL68的素数筛法,基于链表实现 #
    MODE
        LIST = REF NODE,
        NODE = STRUCT (INT h, LIST t);
    OP  CONS = (INT n, LIST l) LIST: HEAP NODE := (n, LIST: l);
    PRIO CONS = 9;
    PROC one to = (INT n) LIST:
        (PROC f = (INT m) LIST: (m > n | NIL | m CONS f(m+1));
         f(1));
    PROC error = (STRING s) VOID:
        (print((newline, " error: ", s, newline)); GOTO 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:
        IF l IS NIL THEN NIL
        ELIF p(hd(l)) THEN hd(l) CONS filter(p, tl(l))
        ELSE filter(p, tl(l))
        FI;
    PROC sieve = (LIST l) LIST:
        IF l IS NIL THEN NIL
        ELSE
            PROC not multiple = (INT n) BOOL: n MOD hd(l) NE 0;
            hd(l) CONS sieve(filter(not multiple, 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

顯著的語言元素

編輯

粗體符號和保留字

編輯

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

MODEOPPRIOPROCFLEXHEAPLOCLONGREFSHORTBITSBOOLBYTESCHARCOMPLINTREALSEMASTRINGVOIDCHANNELFILEFORMATSTRUCTUNIONAT @,EITHERr0IS :=:,IS NOTr0  ISNT :/=: :~=:,OFr0TRUEFALSEEMPTYNIL ○,SKIP ~,
COMMENT  CO # ¢,PRAGMAT  PRCASE ~ IN ~ OUSE ~ IN ~ OUT ~ ESAC ( ~ | ~ |: ~ | ~ | ~ ),
FOR ~ FROM ~ TO ~ BY ~ WHILE ~ DO ~ ODIF ~ THEN ~ ELIF ~ THEN ~ ELSE ~ FI ( ~ | ~ |: ~ | ~ | ~ ),
PARBEGIN ~ END ( ~ ),GO TO  GOTOEXITr0

單元:表達式

編輯

基本語言構造是「單元」(unit)。單元可以是「公式」、「閉合子句」、「例程正文」和某個技術上需要的那些構造(賦值、跳轉、越過、空無)。技術術語「閉合子句」(enclosed clause)統一了某些固有的加括號的構造,在其他當代語言種被稱為「塊」、「do語句」、「switch語句」。在使用關鍵字的時候,通常使用介入關鍵字的反轉字符序列來終結這個包圍,比如:IF ~ THEN ~ ELSE ~ FICASE ~ IN ~ OUT ~ ESACFOR ~ WHILE ~ DO ~ OD。這種守衛命令語法被Stephen Bourne重新使用在常用的Unix Bourne shell之中。一個表達式還可以產生「多個值」,它是通過「並立子句」(collateral clause)從其他一些值構造出來的。這種構造看起來就像過程調用的參數包(pack)。

模態:聲明

編輯

基本數據類型在ALGOL 68用語中叫做「模態」(mode),其原始聲明符為:INTREALCOMPL複數)、BOOLCHARBITSBYTES。ALGOL 68不再定義longshortdouble這樣的類型,而是提供了修飾符(modifier)LONGSHORT

  • BITSBOOL值的包裝向量(packed vector)。
  • BYTESCHAR值的包裝向量。
  • LONG – 聲明INTREALCOMPL的大小為LONG
  • SHORT – 聲明INTREALCOMPL的大小為SHORT

ALGOL 68提供了預置常量(prelude constant)如max reallong max real等來將程序適配到不同實現之中。

原始聲明符還包括:COMPLEXGSTRINGFORMATFILEPIPEGCHANNELSEMA

  • STRINGCHAR值的FLEX(靈活)數組。
  • SEMA – 可以通過OP LEVEL初始化的信號量

所有變量都必須被聲明,但是聲明不必須先於第一次使用。例如:

INT n = 2;  # n被固定为常量2 #
INT m := 3; # m是新建的局部变量,它的值被初始化为3 #
# 这是REF INT m = LOC INT := 3;的简写 #
REAL avogadro = 6.02214076E23; # 阿伏伽德罗常数 #
LONG LONG REAL long long pi = 3.14159 26535 89793 23846 26433 83279 50288 41971 69399 37510;
COMPL square root of minus one = 0 I 1; # 复数0 + 1i #

複雜類型可以使用類型構造子REFSTRUCTUNIONPROC來創建自更簡單的類型:

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

具體例子可參見ALGOL 68與C++的比較英語Comparison of ALGOL 68 and C++

其他聲明符號包括:FLEXHEAPLOCEVENTS

  • FLEX – 聲明這個數組是靈活的,就是說它的長度可以按需要增長。
  • HEAP – 為變量從全局堆中分配一些空閒空間。
  • LOC – 為變量分配這個局部棧的一些空閒空間。

聲明REAL x;只是REF REAL x = LOC REAL;語法糖。就是說,x實際上是「常量標識符」,它「引用到」一個新創建的局部REAL變量。

聲明模態(類型)的名字可以使用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代碼:

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

對於ALGOL 68,只有模態指示符NEWMODE出現在等號的左側,最值得注意的是,構造的製造和讀取,是從左至右而不顧及優先級的。還有ALGOL 68數組的下界(lower bound)預設的是1,但也可以是從-max intmax 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

強制:鑄型

編輯

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

有六種可能的強制,其術語為解過程化(deproceduring),解引用(dereferencing),聯合化(uniting),擴大(widening)、成行(rowing)和棄置(voiding)。除了單位化之外,每種強制都在所關聯的值之上規制一個相應的動態效果。因此,很多原始行動可以使用強制來編程。

上下文強度 – 允許的強制:

  • 軟(soft)– 解過程化。
  • 弱(weak) – 解引用或解過程化,產生一個名字。
  • 柔(meek)– 解引用或解過程化。
  • 硬(firm)– 柔強制,隨後聯合化。
  • 強(strong)– 硬強制,隨後擴大、成行或棄置。

強制層級及例子

編輯

ALGOL 68有著上下文層級,它確定在程序中特定點之上可獲得的強制的種類。這種上下文是為:

上下文 上下文位置 可獲得的強制 在此上下文中強制例子
如下情況中的右手側:
  • 標識符聲明,如~之於REAL x = ~
  • 初始化,如~之於REAL x := ~

還有:

  • 調用的實際參數,如~之於PROC: sin(~)
  • 鑄型(cast)的閉合子句,如~之於REAL(~)
  • 例程正文的單元
  • 產生VOID的語句
  • 平衡(balanced)子句的(除第一部份之外)的所有部份
  • 恆等關係的一側,如~之於 ~ IS ~
解過程化 都軟強制再解引用或解過程化產生一個名字 都弱強制再解引用或解過程化 都柔強制再聯合化 都硬強制再擴大或成行或棄置

擴大出現在沒有精度損失的情況下。例如:

  • LONG INTINT
  • REALINT
  • LONG REALREAL
  • COMPLREAL
  • 得 []BOOLBITS
  • STRINGBYTES

變量可以成行為長度為1的數組。例如:

  • 得 [1]INTINT
  • 得 [1]REALREAL
  • 公式的運算元,如~之於~ OP ~
  • 傳輸調用的參數
例子:

UNION(INT, REAL) var := 1

  • 剪標(trimscript),產生INT
  • 質詢(enquiry),如~之於
    IF ~ THEN …… FIFROM ~ BY ~ TO ~ WHILE ~ DO …… OD
  • 調用的一級符號,如sin之於sin(x)
例子:
  • BOOLREF REF BOOL
  • INTREF REF REF INT
  • 分片的一級符號,如~之於~[1:99]
  • 選取的二級符號,如~之於value OF ~
例子:
  • REF INTREF REF INT
  • REF REALREF REF REF REAL
  • REF STRUCTREF REF REF REF STRUCT
賦值的左手側,如~之於~ := …… 例子:
  • PROC REAL random的解過程化:random

關於一級符號(primary)、二級符號(secondary)、三級符號(tertiary)和四級符號(quaternary)可參見運算符優先級

PR和CO:指示和注釋

編輯

指示(pragmat)在程序中的編譯指導,典型的提示給編譯器;在新近的語言中叫做「pragma」。例如:

PRAGMAT heap=32 PRAGMAT
PR heap=32 PR

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

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

一般而言,注釋在ALGOL 68中不能嵌套。這個限制可以使用不同的注釋分界符來繞過,比如只對臨時代碼刪除使用井號。

表達式和複合語句

編輯

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

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

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

另一個例子,要表達數學中f(i)i=1n的總和,下列ALGOL 68整數表達式就可勝任:

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

注意,作為整數表達式,前面的代碼塊可以用在「整數值可以使用的任何上下」之中。代碼塊在ALGOL 68稱為「系列子句」(serial clause),它返回其中被求值的最後一個表達式的值;這個概念也出現在LISP以及其他一些語言之上。

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

  • IF選擇子句:
 IF 条件 THEN 诸语句 [ ELSE 诸语句 ] FI
 “简短”形式:  ( 条件 | 诸语句 | 诸语句 )
 IF 条件1 THEN 诸语句 ELIF 条件2 THEN 诸语句 [ ELSE 诸语句 ] FI
 “简短”形式: ( 条件1 | 诸语句 |: 条件2 | 诸语句 | 诸语句 )

這種方案不僅避免了懸擺else英語dangling else問題,還避免了必須對嵌入的語句序列使用BEGINEND

  • CASE選擇子句:
 CASE 开关 IN 诸语句, 诸语句, ... [ OUT 诸语句 ] ESAC
 “简短”形式:  ( 开关 | 诸语句, 诸语句, ... | 诸语句 )
 CASE 开关1 IN 诸语句, 诸语句, ... OUSE 开关2 IN 诸语句, 诸语句, ... [ OUT 诸语句 ] ESAC
 “简短”形式: ( 开关1 | 诸语句, 诸语句, ... |: 开关2 | 诸语句, 诸语句, ... | 诸语句 )

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

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
    );

採用「粗體」符號的選擇子句的例子:

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:
    CASE month IN
    #一月# 31,
    #二月# (year MOD 4 = 0 AND year MOD 100 ~= 0 OR year MOD 400 = 0 | 29 | 28),
    #三月# 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 # 直到十二月 #
    ESAC;

Algol68允許開關具有類型要麼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

後續的對標準Algol68的擴展允許TO語法元素被替代為UPTODOWNTO來達成小優化。這些編譯器還結合了:

  • UNTIL(C) – 用於更晚的循環終止。
  • FOREACH(S) – 用於並行的運算於數組之上。

進一步的例子可以在下面的代碼例子中找到。

STRUCT、UNION和[:]:結構、聯合和數組

編輯

ALGOL 68支持據於任意數目維度的數組,並且允許整體或部份橫行或縱列的切片。

 MODE VECTOR = [1:3]    REAL;   # vector MODE声明 #
 MODE MATRIX = [1:3,1:3]REAL;   # matrix 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 ⌊a TO ⌈a DO out[i] := a[i]+b[i] OD; out);
 MATRIX m := (v1, v2, v1+v2);
 print ((m[,2:]));              # 第二和第三纵列的切片 #

矩陣可以用任何一種方式定義,例如:

 REF VECTOR row = m[2,];  # 定义一个REF至第二横行 #
 REF VECTOR col = m[,2];  # 定义一个REF至第二纵列 #

ALGOL 68支持多欄位結構STRUCT標籤聯合UNION。引用變量可以指向任何MODE,包括數組切片和結構欄位。

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

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

對上述NODEUNION使用CASE的例子:

ALGOL68r0遵循1968年最終報告 ALGOL68r1遵循1973年修訂報告
 NODE n := "1234";
 REAL r; INT i; COMPL c; STRING s
 CASE r,i,c,s CTAB n IN
     print(("real:", r)),
     print(("int:", i)),
     print(("compl:", c)),
     print(("string:", s))
 OUT print(("?:", n))
 ESAC
 NODE n := "1234";  # 或者 n := EMPTY; #
 CASE n 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(("?:", n))
 ESAC

PROC:過程

編輯

過程的PROC聲明對參數和結果二者要求類型指定,如果沒有則為VOID

 PROC max of real = (REAL a, b) REAL:
     IF a > b THEN a ELSE b FI;

或者使用條件語句的「簡短」形式:

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

過程的返回值是在過程中求值的最後一個的表達式的值 。到過程的引用REF PROC也是允許的。提供了傳引用調用參數來在形式參數列表中指定引用,比如REF REAL。下列例子定義一個過程,它將(作為參數而指定的)一個函數應用於一個數組的每個元素:

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

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

OP:運算符

編輯

編程者可以定義新的運算符,並且這些自定義的和預定義的運算符二者都可以重載,並且它們的優先級可以由編碼者變更。下列例子定義的運算符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)

數組、過程、解引用和強制運算

編輯
PRIO ALGOL68r0&r1運算 +ALGOL68r0 +ALGOL68G
效果上 12
(一級符號)
解引用,解過程化(~,~),加下標[~],成行[~,],分片[~:~],大小指示LONGSHORT 過程化 柯里化(~,,,)DIAGTRNSPROWCOL
效果上 11
(二級符號)
OF(選取),LOCHEAP(生成器) → (選取) NEW(生成器)

這些符號在技術上不是運算符,它們轉而被當作「關聯著名字的單元」[27]

一元運算符

編輯
PRIO
(三級符號)
ALGOL68「傑出字符」r0&r1 +ALGOL68r0&r1 +ALGOL68C,G +ALGOL68r0
10 NOT ~,-,UPDOWNLWBUPBABSARGBINENTIERLENGLEVELODDREPRROUNDSHORTEN ¬,↑,↓,⌊,⌈ NORMTRACETDETINV LWS ⎩,UPS ⎧,BTBCTB

關聯著優先級的二元運算符

編輯
PRIO
(三級符號)
ALGOL68「傑出字符」r0&r1 +ALGOL68r0&r1 +ALGOL68r0
9 I +* +× ⊥ !
8 SHLSHRUP **,DOWNLWBUPB ↑,↓,⌊,⌈ ×× ^,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 +=: ×:=,÷:=,÷×:=,÷*:=,%×:= MINUSPLUSTIMESDIVOVERBMODB ÷::=,PRUS

特殊細節:

  • 三級符號包括名字NIL
  • LWS:在ALGOL 68r0中,運算符LWS,在一個數組的這個維度的「下界狀態」為固定的(fixed)的情況下, 二者都返回TRUE
  • UPS運算符針對「上界狀態」。
  • LWBUPB運算符自動的可獲得在一個數組的不同階次(和MODE)的UNION之上,例如:UNION([]INT, [,]REAL, FLEX[,,,]CHAR)UPB

賦值和恆等關係等

編輯

這些符號在技術上不是運算符,它們轉而被當作「關聯著名字的單元」[27]

PRIO
(四級符號)
ALGOL68"傑出字符"r0&r1 +ALGOL68r0&r1 +ALGOL68C,G,R +ALGOL68r0
效果上 0 :=,IS :=:,ISNT :/=: :~=:,AT @,:,; :≠: :¬=: :=:=C,=:=R ..= .=,CT ::,CTAB ::=,IS NOT,..,.,

注意:四級符號包括名字SKIP~

IS(可替代為:=:)測試兩個引用是否相等;ISNT(可替代為:/=:)測試兩個引用是否不相等。

特殊字符

編輯
 
具有APL符號的IBM 2741英語IBM 2741鍵盤

ALGOL的「特殊」字符:

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

多數都可以在具有APL符號的IBM 2741英語IBM 2741鍵盤上找到;故而這些字符在1960年代中期起草ALGOL 68的時候就能獲得到。這些字符也是Unicode標準的一部份並且在一些流行字體中可獲得到。

「傑出字符」(worthy characters)是ALGOL 68基礎字符集的子集,ALGOL 68標準硬體表示報告出於可移植性而推薦了它[28]:

ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 "#$%'()*+,-./:;<=>@[ ]_|

這反映了在1960年代一些硬體不支持小寫字母,更不支持非ASCII字符的事實。

傳輸:輸入和輸出

編輯

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

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

注意預定義的過程newpagenewline作為實際參數而傳送。

在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))

PAR:並行處理

編輯

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

PROC
    eat = VOID: (muffins -:= 1; print(("Yum!", new line))),
    speak = VOID: (words -:= 1; print(("Yak...", new line)));
 
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只在aTRUE的情況下才求值。例如:

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

語言修訂之後與編程者的預期相反,列印仍會執行,需要如下這樣使列印不執行:

IF FALSE ANDF PROC BOOL: (print("Should not be executed"); TRUE) THEN ……

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

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

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

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

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

參見

編輯

註釋

編輯
  1. ^ ALGOL 68 Genie. [2020-04-22]. (原始內容存檔於2020-08-14). 
  2. ^ Dennis Ritchie. The Development of the C Language (PDF). April 1993 [2007-04-26]. (原始內容 (PDF)存檔於2005-06-29). The scheme of type composition adopted by C owes considerable debt to Algol 68, although it did not, perhaps, emerge in a form that Algol’s adherents would approve of. The central notion I captured from Algol was a type structure based on atomic types (including structures), composed into arrays, pointers (references), and functions (procedures). Algol 68’s concept of unions and casts also had an influence that appeared later. …… a notation for type conversions (called 『casts』 from the example of Algol 68) was invented to specify type conversions more explicitly. 
  3. ^ A History of C++: 1979−1991 (PDF). Page 12, 2nd paragraph: Algol68 [gave] operator overloading(§3.3.3), references (§3.3.4), and the ability to declare variables anywhere in a block (§3.3.1). March 1993 [2008-05-06]. (原始內容存檔 (PDF)於2006-12-10). 
  4. ^ Interview with Guido van Rossum. July 1998 [2007-04-29]. (原始內容存檔於2007-05-01). String slicing came from Algol-68 and Icon. 
  5. ^ 5.0 5.1 5.2 5.3 Revised Report on the Algorithmic Language Algol 68. 
  6. ^ Adriaan van Wijngaarden. Orthogonal design and description of a formal language (PDF). 1965. 
  7. ^ Hoare, C. a. R. Critique of ALGOL 68. ALGOL Bulletin. November 1968, 29: 27–29. I believe that the essential problem in the design of self-extending languages is in the design of the nucleus of built-in features, which the implementor will be expected to represent within the machine code of his computer. It is essential that this nucleus should have the properties: 1. Extreme simplicity and small size …… 2. Extreme efficiency of implementation …… I would therefore reckon that a language at about the level of FORTRAN would be a suitable choice for a nucleus. The language nucleus described in MR93 is far too elaborate; and some of its defects are listed in Appendix II. 
  8. ^ Dijkstra, E. W. To the Editor ALGOL 68 Mathematische Centrum. [2007-04-28]. (原始內容存檔於2007-04-21). On account of the draft report my faith in WG.2.1 (at least in its present constitution) is very low. The draft report is thick and difficult, in fact too thick and too difficult to inspire much confidence. …… Size and complexity of the defining apparatus you needed terrify me. Being well-acquainted with your ingenuity I think it a safe assumption that ALGOL 68 as conceived can hardly be defined by significantly more concise and transparent means. …… I feel inclined to put the blame on the language you tried to define. If this is correct, WG.2.1 should return to its proper subject matter, viz. programming languages. 
  9. ^ Niklaus Wirth. ALGOL Colloqium – Closing Word. 1968. The implied and rather vague goal was the specification of a universal language, a sensible goal in 1960, even 1964, but an utopia in 1968; a goal which if pursued faithfully, invariably lead towards a monster language, a species of which there already exists a sample hardly worth nor possible to compete with. 
  10. ^ Learning Algol 68 Genie (PDF). Some claim that Ada is Algol 68’s successor but many dispute that. 
  11. ^ Adriaan van Wijngaarden. Generalized ALGOL (PDF). Symbolic Languages in Data Processing, Proc. Symp. Intl, Computation Center Rome, Gordon & Beach, New York. 1962. 
  12. ^ Van Wijngaarden, A.; Mailloux, B. J.; Peck, J.; Koster, C. H. A. Draft Report on the Algorithmic Language ALGOL 68. ALGOL Bulletin. 1 March 1968, (Sup 26): 1–84 [7 April 2023] –透過Mar. 1968. 
  13. ^ Report on the algorithmic language ALGOL 68. 1969. 
  14. ^ Sidney Marshall. J. E. L. Peck , 編. ALGOL 68 Implementation (PDF). Proceedings of the IFIP Working Conference on ALGOL 68 Implementation, Munich,: 239–243. July 20–24, 1970. 
    Sidney Marshall. On the implementation of ALGOL 68 (PDF). PhD Thesis, Dartmouth College. 1972. 
  15. ^ L. Ammeraal. An interpreter for simple Algol 68 Programs (PDF). 1973. 
  16. ^ Daniel M. Berry. The importance of implementation models in ALGOL 68: or how to discover the concept of necessary environment. 
  17. ^ Liverpool Software Gazette March 1980 (PDF). [2010-03-20]. (原始內容 (PDF)存檔於2010-04-15). 
  18. ^ Revised report on the algorithmic language ALGOL 68 (PDF). 1976. 
  19. ^ Black, A. P.; Rayward-Smith, V. J. Proposals for ALGOL H - A Superlanguage of ALGOL 68. ALGOL Bulletin. 1 May 1978, (42): 36–49 [7 April 2023] –透過May. 1978. 
  20. ^ ALGOL 68 Version I Reference Manual (PDF). Control Data Services B.V., Rijswijk, Netherlands. 1976. 
  21. ^ ALGOL68 instruction at Oklahoma State University. 
  22. ^ "The Berlin ALGOL 68 implementation"
    An abstract ALGOL 68 machine and its application in a machine independent compiler – Springer. Springerlink.com. Retrieved on 2013-07-21.
  23. ^ Algol 68+, a superlanguage of Algol 68 for processing the standard-prelude (PDF). 1981. 
  24. ^ Hibbard, P.G. A Sublanguage of ALGOL 68. SIGPLAN Notices. May 1977, 12 (5): 71–79. S2CID 37914993. doi:10.1145/954652.1781177 . 
  25. ^ Open source Algol 68 implementations / algol68toc. Sourceforge.net. Retrieved on 2013-07-21.
  26. ^ a68mk2.zip 網際網路檔案館存檔,存檔日期2006-08-29.
  27. ^ 27.0 27.1 Units associated with names. 
  28. ^ Report on the Standard Hardware Representation of Algol 68 網際網路檔案館存檔,存檔日期2014-01-02.

外部連結

編輯