algol语言

安德鲁·麦克格特里克(Andrew McGettrick)在其出色的教科书《 阿尔高68:第一和第二门课程》的序言中写道:

“本书源于1973-4年在斯特拉斯克莱德大学首次面向一年级本科生的演讲,其中许多人以前没有编程知识。许多学生不是将计算机科学作为主要课程,而只是将其作为一门课程。因此,他们是合适的听众,向他们授课,试图讲授Algol 68作为第一门编程语言。”

也许这句话对我来说尤为重要,因为我也是1973-1974年的一年级学生,尽管我在另一所大学-不列颠哥伦比亚大学。 此外,“追溯到那时”,UBC的入门级计算机科学课程在第二年使用Waterloo FORTRAN进行了讲授,并引入了一些IBM 360 Assembler。 没有什么比Algol 68更具异国情调了。就我而言,直到我三年级才接触Algol 68。 也许这次等待,再加上其他编程语言的经验,使我终生痴迷于这种被低估且精彩的编程语言。 多亏了Marcel van der Veer,他创建了一个非常好的Algol 68实现,称为Algol 68 Genie,现在终于在我的发行版资料库中,终于使我得以在闲暇时探索Algol 68。 我还应该提到,马塞尔的书《 学习Algol 68 Genie》对于新手和Algol 68的进修课程都非常有用。

因为我一直在重新发现Algol 68感到非常开心,所以我想我会分享一些想法和印象。

人们怎么说Algol 68

如果值得阅读Wikipedia上的Algol 68概述 ,那么真的值得阅读《算法语言Algol 68修订报告》中的这一段:

“原始作者很高兴地表示感谢,并感谢WG 2.1成员和许多其他对Algol感兴趣的人的全心全意的合作,支持,关注,批评和暴力反对。”

“批评和暴力反对”-哇! 实际上,一些委员会成员对委员会的发展方向非常不满意,以至于他们离开并开始了自己的语言定义项目,至少部分是出于对Algol 68的抗议。例如,Niklaus Wirth厌倦了Algol的复杂性68, 开始设计Pascal 。 在大约1984年至2000年左右编写并支持了相当多的Pascal代码后,我在这里告诉您,Pascal距离Algol 68尽可能远。 在我看来,这正是沃思的观点。

丹尼斯·里奇( Dennis Ritchie )在1993年在马萨诸塞州剑桥举行的第二届ACM编程语言历史会议上发表了演讲 ,他比较了Bliss,Pascal,Algol 68和C。在这次演讲中,他提出了一些有趣的观察:

  • 所有这四种语言都是“基于这种古老的,古老的机器模型,它们可以拾取,执行操作并将它们放置在其他地方”,并且“在很大程度上受到Algol 60和FORTRAN的影响”。
  • “当Steve Bourne(是创建Bourne shell的人)带着Algol 68C编译器来到Bell Labs时,他使它完成了C可以完成的工作;它具有Unix系统调用接口,等等。”
  • “我认为该语言确实确实在接受度方面受其定义的影响。尽管如此,它确实非常实用。”
  • “在某些方面,Algol 68是我一直在讨论的语言中最优雅的语言。我认为在某些方面,它甚至是最具影响力的语言,尽管作为一种语言本身,它已经消失了。”

关于Algol 68的更多观点在当今的互联网上仍然很突出。 很多都是负面的,但是哦! 我怀疑其中很大一部分都没有实际使用情况。 Rosetta Code Wiki上提供了一个非常有趣的地方,可以找到只是开始使用该语言的编码人员(还有许多其他人员,其中有些晦涩难懂)。 去那里,形成您自己的意见! 或关注我,因为我对Algol 68感到满意的地方不是那么好。

关于Algol 68的重要内容与我相关

Algol 68作为一种编程语言,提供了一些独特而有用的思想,这些思想在当时具有创新性,并从那时起在某种程度上以其他语言出现。

修订报告中明确解释了关键设计原则

设计Algol 68的委员会受到一套非常明确的原则的推动:

  • 描述的完整性和清晰度(借助二级语法的使用,这引起了很多负面意见)
  • 正交设计; 也就是说,用语言定义的基本概念可以在可以被认为是“合理的”的任何地方使用。 例如,每个可以合理预期产生值的表达式实际上都会产生一个值。
  • 通过精心的句法设计来保证安全性(再次说明二级语法); 大多数与其他语言的语义概念相关的错误都可以在编译时检测到。
  • 效率,因为程序应该高效运行(在当今的硬件上),而无需花费大量精力来优化生成的代码,此外:
    • 不进行运行时类型检查,除非在运行时提供替代配置的类型的特殊情况下(Algol 68中的united类型,类似于C中的union类型)
    • 类型无关的解析(同样是这里的两级语法),并且可以确定,在有限的步骤中,可以评估任何输入序列是否为程序
    • 鼓励使用当今著名的循环优化策略的循环结构
    • 一个符号集(带有替代符号),适用于当时计算机上可用的各种不同字符集

与当今的动态类型化语言和弱静态类型化的语言相提并论,我发现将重点放在非常强大的静态类型化(50年前!)和预期的好处上具有启发性整个行业的运行时测试。 (好的也许这并不完全公平,但是它包含了一定的真理性)。

无需额外的分组构造即可将语句分组的结构

在用Algol 60和Pascal编写的程序中,我们看到了很多beginend标记。 在C,C ++,Java等中,我们看到了很多{} 。 例如,可以使用Algol 60或Pascal将简单的表达式计算为整数值iv的绝对值av

 if iv < 0 then av := -iv else av := iv 

如果我们想设置一个布尔值,说明iv是否为负,那么我们需要开始插入beginend

 if iv < 0 then begin av := -iv; negative := true end else begin av := iv; negative := false end 

正式地,Algol 68对具有特殊含义(如ifthen)的令牌使用粗体字,对诸如print ()过程之类的名称使用斜体。 在很多人仍在使用键穿Kong进行编码的时代,这是不切实际的,而今天仍然有些奇怪。 因此,Algol 68实现通常提供了一些标记特殊符号的方法(称为stropping ),而其他所有内容均未标记。 默认情况下,Algol 68 Genie使用大写字母加斜线,因此诸如if之类的符号被编码为IF,并且事物名称只能小写。 但是,值得注意的是,可以将一个名为“ if”的变量完全适合当前的目的完全可以。 Anway ...万一有读者倾向于复制/粘贴,我在代码示例中使用了Genie约定。

此外,Algol 68具有Bourne shell和Bash继承的封闭语法。 因此,Algol 68 Genie中的上一行代码将是:

 IF iv < 0 THEN av := -iv; negative := TRUE ELSE av := iv; negative := FALSE FI 

if不明显,令牌fi关闭前面的if 。 现在,也许我是世界上唯一曾经编写过如下所示的Java的人:

if ( something )
statement ;

然后发现自己插入了对println的调用以调试该代码:

if ( something )
statement ;
System . err . println ( stuff ) ;  /* not in the then-part of if!!! */

无知地忘记将然后的部分包装在{ … } 。 当然,这还不是世界末日,但是当插入的结果不太明显时,可以说,多年来我花了很多时间调试这种事情。

但这在Algol 68中是不可能发生的。 Algol 68仍然需要begin ... end才能进行操作员和过程声明。 但是, if ...... fido ... odcase ... esac (大陵五的68 switch语句)全部关闭。

今天,我们在Go中看到了相同的概念; “ if”语句看起来像if ... {…}; {和}是必需的。 正如我已经提到的那样,Bourne shell及其后代使用类似的构造。

几乎每个表达式都产生一个值

iv < 0以上; 很明显会产生一个值,并且很可能该值是Boolean( truefalse )。 所以那没什么大不了的。

但是赋值语句也会产生一个值,即赋值完成后赋值语句的左侧。

语句序列产生最终语句(或表达式)产生的值。

“ if”语句产生的是then-part或else-part的值,具体取决于“ if”之后的表达式是true还是false

一个例子:考虑使用C,Java…三元运算符进行绝对值计算:

 av = iv < 0 ? -iv : iv; 

在Algol 68中,我们不需要额外的“三元运算符”,因为“ if”语句可以正常工作:

 av := IF iv < 0 THEN -iv ELSE iv FI 

这可能是个好时机,Algol 68使用( |)提供了“简明”版本的符号,例如beginendifthenelse等等。

 av := ( iv < 0 | -iv | iv ) 

与前面的表达式具有相同的含义。

当我第一次遇到它时,令我惊讶的是循环没有产生一个表达式。 但是,循环有一些区别,一旦被完全理解,它们最终就变得有意义。

Algol 68中的循环可能看起来像这样:

 FOR lv FROM 1 BY 1 TO 1000 WHILE 2 * lv * ly < limit DO … OD 

此处的变量ly是循环变量,由for隐式声明为整数。 它的范围是整个for ... od 其价值被保留从一个迭代到下一个。 我们可以在whiledo part中声明一个常规变量,就像在ifthen part中一样。 它的范围是whileod部分,但从一次迭代到下一次迭代都不会保留其值。 因此,例如,如果要累加数组元素的总和,则必须编写:

 INT sum := 0; FOR ai FROM LWB array TO UPB array DO sum +:= array[ai] OD 

其中运算符lwbupb提供分别为数组定义的最小和最大索引值,并且+:=符号的含义与C或Java中的+ =相同。

如果我们想将总和作为一个值返回,我们可以这样写:

 BEGIN INT sum := 0; FOR ai FROM LWB array TO UPB array DO sum +:= array[ai] OD; sum END 

当然,为了简洁起见,我们可以用()代替beginend 。 此表达式将是过程(或运算符)的合理实现,该过程返回数组元素的值之和。

正交性-相同的表达式几乎可以在任何地方使用

再次查看上面的表达式iv < 0

让我们退后一步,包括iv的定义及其值的获取。 然后代码可能看起来像:

 INT iv; read(iv); IF iv < 0 THEN … FI 

但是,我们也可以这样写:

 IF INT iv; read(iv); iv < 0 THEN … FI 

在这里我们可以看到工作的正交性-变量的声明和读取可以在if和测试变量的逻辑表达式之间进行,因为传递的值只是最终表达式的值。 此外,这与Algol 68语义一起提供了一个有趣的区别—在第一种情况下, iv的范围是围绕“ if”语句的代码; 在第二个中,作用域介于iffi 。 按照我的想法,此选项意味着我们应该在远离变量使用的地方声明较少的变量,而真正保留的变量在代码中确实具有“长寿命”。

这也具有实际重要性。 例如,考虑使用某种SQL接口在数据库中执行多个脚本并返回值以进行进一步分析的代码。 通常,在这种情况下,程序员需要做一些工作来建立与数据库的连接,将查询字符串传递给execute命令,然后检索结果。 每个实例都需要声明一些变量来保存连接,查询字符串和结果。 这些变量可以在结果累积代码中本地声明时真是太好了! 这也有助于添加具有快速复制粘贴功能的新查询分析步骤。 是的,最好将这些代码片段转换为过程调用,尤其是在使用支持lambda(匿名过程)的语言时,以避免用重复的管理步骤混淆不同的分析步骤。 但是,具有非常本地定义的管理变量可以简化所需的重构工作。

正交性的另一个重要结果是,我们可以在赋值语句的左侧和右侧获得等效的三元运算符。

假设我们正在处理带符号整数的输入流,并且希望将正整数累积为增益,将负整数累积为损耗。 然后,以下Algol 68代码将起作用:

 IF amount < 0 THEN losses +:= amount ELSE gains +:= amount FI 

但是,这里无需重复+:= amount ; 我们可以将它移到iffi ,如下所示:

 IF amount < 0 THEN losses ELSE gains FI +:= amount 

之所以可行,是因为评估测试的结果是“ if”语句产生了损失或收益表达式,并且该表达式增加了数量。 当然,我们可以使用简短的形式,至少在我看来,这可以提高这些简短表达式的可读性:

 ( amount < 0 | losses | gains ) +:= amount 

如何通过一个真实的例子来说明为什么这种以表达为导向的东西是如此的出色?

假设您正在编写哈希表工具。 您将必须实现的两个功能是“获取与给定键关联的值”和“设置与给定键关联的值”。

在面向表达的语言中,这些可以是一个功能。 为什么? 因为“获取”操作返回找到该值的位置,然后“设置”操作仅使用“获取”操作在该位置设置值。 假设我们创建了一个名为valueat的运算符,该运算符valueat两个参数-哈希表本身和键值。 然后,

 ht VALUEAT 42 

将返回键42在哈希表ht中的位置,然后

 ht VALUEAT 42 := "the meaning of everything" 

会将字符串“一切的意义”放在位置42。

这减少了支持手头应用程序所需的代码量,减少了必须测试的途径和边缘案例的数量,并且通常只为用户和维护者的生活增添了美好。

有一个简单的示例,该示例使用赋值语句左侧的过程将值存储在RosettaCode的表中。

匿名程序(lambdas)

如今,每个人似乎都希望使用匿名过程(或“ here”过程或lambda)。 Algol 68提供了开箱即用的功能,它确实非常有用。

举例来说,假设您想创建一种设施来读取带有分隔字段的文件,并为用户提供与它们的良​​好交互途径。 考虑一下awk所做的出色工作,基本上是通过提取所有与打开文件有关的垃圾,读取行,将行拆分为字段,并在此过程中提供一些有用的附带变量(例如current-line-number),此行上的字段数,依此类推。

事实证明,这在Algol 68中也很容易做到,其中的任务是编写一个带有三个参数的过程-第一个是输入文件名,第二个是字段分隔符字符串,第三个是一个处理每一行。

该过程的声明可能如下所示:

PROC each line =         # 1 #
(STRING input file name, CHAR separator, PROC (STRING, [] STRING, INT) VOID process) # 2 #
VOID: BEGIN              # 3 #
FILE inf;            # 4 #
open(inf, input file name, stand in channel); # 5 #
BOOL finished reading := FALSE;
on logical file end (inf, (REF FILE f) bool: finished reading := TRUE); # 6 #
INT linecount := 0;  # 7 #
WHILE                # 8 #
string line;
get(inf,(line, new line));
not finished reading
DO                   # 9 #
linecount +:= 1;
FLEX [1:0] STRING fields := split(line, separator);
process(line, fields, linecount)
OD;
close(inf)           # 10 #
END                      # 11 #

这是上面发生的事情:

  1. 注释1(上面的#1#)-过程的each line的声明(请注意,可以随意在名称或数字的中间插入空格)

  2. 到每个线的参数string文件名,字段分隔符char ACTER,和pro cedure被调用来处理每一行,它本身需要一个string (输入的线)的阵列string S(的字段行)和一个int (行号),并返回一个void

  3. each line返回一个void值,过程主体以begin ,这使我们可以在其定义中使用多个语句

  4. 声明输入file

  5. standard input channelfile (其名称由input file name指定)关联,然后将其打开(以供读取)

  6. Algol 68处理文件结束条件的方式有所不同; 在这里,我们使用on logical file end的I / O事件检测过程来设置标志finished reading ,我们可以在处理文件时检测到该标志

  7. 创建并初始化行数(请参见前面关于循环性质的描述)

  8. while循环尝试从输入文件中读取下一行。 如果成功,它将处理该行; 否则,退出

  9. 处理输入行-增加行数; 使用split过程创建一个与行的字段相对应的字符串数组; 调用提供的process过程以消耗该行,其字段和行数

  10. 记得close文件

  11. 过程定义的end

我们可能会像这样使用它,以便构建查找表(结合上一节中提到的假设哈希表工具):

# remapping definitions in remapping.csv file #
# new-reference|old-reference #
# 093M0770371|093X0012250 #
# 093M0770375|093X0012249 #
# 093M0770370|093X0012133 #

HASTABLE ht := new hashtable;

each delimited line("test.csv", "|", (STRING line, [] STRING fields, INT linecount) VOID: BEGIN
STRING to map := fields[1], from map := fields[2];
ht VALUEAT from map := to map
END);


在上方,我们看到了对每个分隔行的调用。 特别令人感兴趣的是声明“这里”过程或lambda,它将查找值存储到哈希表中。 在我看来,这里的一个重要教训是λ是Algol 68正交性的结果。 我认为那很整洁。

在我继续探索Algol 68时,我打算深入研究的一件事是,我可以进一步采用这种功能形式的表达方式。 例如,我看不到为什么不能逐个构建列表或哈希表元素,并由于循环过程的结果而产生完成的结构,所以上面看起来更像:

HASHTABLE ht := each delimited line as map entry("test.csv", "|",
(STRING line, [] STRING fields, INT linecount) VOID: BEGIN
STRING to map := fields[1], from map := fields[2];
(from map, to map)
END);

结论

为什么要学习古老的,尘土飞扬的和被遗忘的语言? 好吧,我们都知道了最近对COBOL的兴趣,但是从某种意义上说,也许可能不是很多用SNOBOL,Icon,APL甚至Algol 68编写的关键任务应用程序。乔治·桑塔亚那(George Santayana)要牢记的指导是: “那些不记得过去的人将被谴责以重蹈覆辙。”

对我来说,使用Algol 68开发游戏有一些关键原因(可能还有其他几种语言,这些语言似乎对我的日常工作不是绝对必要的):

  • Algol 68并未定义为对现有编程语言中某些烦恼的React; 相反,根据修订报告:

    • 该委员会(国际信息处理联合会ALGOL工作组2.1)“表达了对为许多国家的许多人服务的通用编程语言的价值的信念。”

    • “ Algol 68并不是作为Algol 60的扩展而设计的,而是基于对计算的基本概念和新的描述技术的新见解而设计的全新语言。”

  • 无论是通过复制到其他语言中的积极贡献(在Bourne shell中do … od ;在C,Java中……实现=)还是负面React(Pascal及其所有后代,Ada),Algol 68都可以声称对计算产生了深远的影响。

  • 尽管Algol 68很大程度上是“那个时代的孩子”,但受到按键和行式打印机,小型多样的字符集,1960年代和1970年代计算机的字符和单词大小的广泛变化的影响,并且没有明确地包含面向对象的知识。或函数式程序设计,其相当出色的正交性和面向表达的功能弥补了这些怪异之处,并缺乏其他有用的方式。

  • 也许最实际的原因是在桌面上安装并运行了出色的Algol 68 Genie解释器,让我可以从事这个奇怪的小嗜好!

也许我应该回到桑塔亚纳(Santanana)作最后评论:

“我们认为美是难以形容的:它是什么或它的含义永远不能说。”

翻译自: https://opensource.com/article/20/6/algol68

algol语言

algol语言_在21世纪探索Algol 68相关推荐

  1. 石正喜MySQL数据库使用教程_《21世纪高职高专系列规划教材:MySQL数据库实用教程》【摘要 书评 在线阅读】-苏宁易购图书...

    商品参数 作者: 石正喜编 出版社:北京师范大学出版社 出版时间:2014-01-01 00:00:00 版次:1 印次:1 印刷时间:2014-01-01 字数:400000 页数:298 开本:1 ...

  2. python鼻祖_科技日历| 61年前,ALGOL语言创立!它是C语言等高级语言的直接“鼻祖”...

    一提到计算机高级语言,可能很多人马上就会想到C语言.C++.Python.Java等等.ALGOL语言可能很多人都没有听说过. 但这个现在已经销声匿迹的语言却是C语言.C++.Java等高级语言的直接 ...

  3. C语言是始祖,科技日历| 61年前,ALGOL语言创立!它是C语言等高级语言的直接“鼻祖”...

    原标题:科技日历| 61年前,ALGOL语言创立!它是C语言等高级语言的直接"鼻祖" 一提到计算机高级语言,可能很多人马上就会想到C语言.C++.Python.Java等等.ALG ...

  4. algol语言_ALGOL的完整形式是什么?

    algol语言 ALGOL:算法语言 (ALGOL: Algorithmic Language) ALGOL is an abbreviation of "Algorithmic Langu ...

  5. 21世纪C语言(影印版)

    <21世纪C语言(影印版)> 基本信息 原书名:21st Century C 作者: Ben Klemens    出版社:东南大学出版社 ISBN:9787564142056 上架时间: ...

  6. ALGOL语言 发展历史

    一提到计算机高级语言,可能大家就会想到C语言.C++.Python.Java等等.ALGOL语言可能很多人都没有听说过. 但这个现在已经销声匿迹的语言却是C语言.C++.Java等高级语言的直接鼻祖, ...

  7. linux 内核编译_如何在21世纪编译Linux内核

    linux 内核编译 在计算中,内核是处理与硬件和一般系统协调通信的低级软件. 除了计算机主板上内置的一些初始固件之外,启动计算机时,内核还使您意识到它具有硬盘驱动器,屏幕,键盘和网卡. 确保为每个组 ...

  8. radian | 一款21世纪的R语言编辑器

    题目不是我说的,​而是官网翻译的.​(它潜在的意思是Rstudio不是21世纪的编辑器啦?​不想引起对立,但是我要说,radian在终端下使用真香!) 1. radian编辑器应用场景 总所周知 1 ...

  9. c语言程序设计李新华,21世纪高等学校规划教材:C语言程序设计

    <C语言程序设计>为21世纪高等学校规划教材.全书共分lO章,主要内容包括c程序设计概述.数据及运算.流程控制.数组.指针.函数.结构体文件.c语言实际应用.c语言程序设计常见错误及解决方 ...

最新文章

  1. 《数据中心虚拟化技术权威指南》一2.2 数据中心网络拓扑
  2. Oracle10.2.0.1.0升级Oracle10.2.0.2.0补丁安装指南(转载)
  3. CI框架--加载静态内容
  4. Excel 批量处理行高(图文教程) - Excel篇
  5. Ajax get请求示例
  6. SpringBoot-Feign
  7. c语言期末读程序,C语言期末程序.doc
  8. L2-005. 集合相似度-PAT团体程序设计天梯赛GPLT
  9. 穿越沙漠问题c语言算法,穿越沙漠问题---递推法
  10. exception EOleSysError in module HLServer.exe at 0009C451.问题解决
  11. TCP/IP、Http的区别--(转自任智康)
  12. 哈希摘要、证书、对称密钥、公私密钥应用场景梳理
  13. python -- 判断给定的参数是否是地理位置的经度和纬度
  14. 基于知识图谱和图卷积神经网络的应用——学习笔记
  15. 很受打动的一篇文章,很幽默让人想看完。
  16. 利用python分析电商_基于Word2Vec+SVM对电商的评论数据进行情感分析
  17. 电脑端使用文件微信聊天记录的本机/新机备份迁移
  18. Windows 下PowerShell 美化之旅(极其简单)
  19. 使用C#压缩解压文件
  20. Redis 集合高级用法

热门文章

  1. Android自定义View——实现联系人列表字母索引
  2. SqlServer_查看SQLServer版本信息
  3. Linux tr命令
  4. idea debug模式,进不了断点
  5. innodb事务的四大特性
  6. 京东科技埋点数据治理和平台建设实践
  7. 如何用纯 CSS 绘制一颗闪闪发光的璀璨钻石
  8. Jmeter函数分类及自定义开发
  9. java类型转换的方式_(原创)Java万能数据类型转换
  10. 科技发展的未来:探索数据驱动的智能科技创新