哪种非理论,实用的编程语言没有保留关键字?


22

我一直在寻找一种没有保留关键字的实用编程语言,但没有运气。

我正在为自己的娱乐和娱乐而设计一种编程语言,现在还不需要添加任何关键字,这就是导致我进行搜索和提出问题的原因:

我认为对于语言的最终用户而言,给编译器编写者带来便利并不重要。如今,计算机已经足够强大,可以从上下文中推断出含义。作家在写小说时只需要标记名词,动词等,为什么程序员必须用function x() {}or set x = 1var x = 1etc 标记函数和变量?我何时可以从语句的上下文中推断出它是函数声明或调用,还是标签是对值的赋值或对该标签值的引用?

这是我当前的解析器正在做的事情的一个具体示例,不需要保留的关键字来支持通常会产生一些杂音的常见事物,例如funcor functionor decor not。

功能声明

sum3(a,b,c) -> a + b + c.

功能调用

x = sum3(1,2,3).

名为x的匿名函数

x = (a,b,c) -> a + b + c.
y = x(1,2,3).

我想知道为什么关键字对成功的编程语言如此重要?


8
Forth非常实用,并且没有任何关键字。
SK-logic

4
@JamesAnderson,不,它们只是单词,与所有其他单词相同。没有任何特殊含义。
SK-logic

7
运算符和标点符号是否算作“关键字”?如果是,则由于不定义语法,因此可能不存在任何语言。
Emilio Garavaglia 2013年

2
@ SK-logic:通常。但是,如果您还没有标记化,什么是“标识符”?由于令牌是“任何可识别的字符串”,因此在给出语法规则之前,“ int”,“ myvalue”和“ +”没有区别。如果未将“ +”定义为运算符,则它只能是诸如其他unicode单个字符串之类的名称。从纯粹的语法观点来看,运算符仅是“单个字符关键字”。
Emilio Garavaglia 2013年

2
在这种情况下,关键字是什么?它是对编译器有特殊含义的标识符吗?它是程序员不应该用作变量或其他内容的标识符吗?如果必须专门指定关键字,是否算作无关键字?(很久以前,我看到了一个ALGOL系统,其中的关键词需要用引号引起来。)
David Thornley

Answers:


12

MUMPS非常成功,已广泛用于保险和医疗保健,并且没有保留字眼。我会说它们在编写更清晰的代码方面有帮助,但并非绝对必要。APL是另一个示例。APL认为,核工业中一次性脚本的用途尤其广泛。APL家族的成员J也缺少关键字。

关键字可帮助编译器编写者更轻松地实现解析。APL是著名的右联想。它们还有助于加强约定并提高可读性。APL不以大多数人的可读性而闻名。


2
+1为“关键字可帮助编译器编写者更轻松地实现解析”。我认为就是这样。发明关键字是为了减少解析器必须保留在内存中的上下文数量,当时整个编译器及其工作集必须容纳十几KB的RAM。
约尔格W¯¯米塔格

2
为APL编写解析器比其他任何语言都容易!考虑到APL解释器的第一个实现是使用晶体管和二极管完成的。
詹姆斯·安德森

2
我认为使用关键字的主要原因是为了使人们更容易地解析语言。如果语言像他们的机器代码一样完全由数字和位模式组成,计算机会更快乐。
詹姆斯·安德森

6
APL缺少关键字,它需要自己的字体来弥补不足。
Blrfl 2013年

@Blrfl这就是J,K和Q的要点。它们在某种程度上都是ASCII的APL。
世界工程师

9

Lisp是一种没有关键字的众所周知的语言。它与关键字最接近的东西称为特殊形式-它们的数量在方言之间可能会有所不同-会从解释器中获得特殊待遇。除此之外,就如何使用它们而言,它们与常规函数没有区别,除了它们无法重新定义(至少在我熟悉的Lisps中)。

这导致一种简单的语法(但是很繁琐),并且是使Lisp拥有如此强大的宏系统的原因之一。另一方面,Lisp通常被认为很难阅读。APL和MUMPS,甚至更是如此,我已经看到两者都描述为Brainf * ck的一半。关键字确实对本部门有所帮助,也使我们的人员更容易阅读代码。

因此,我不会说成功的语言需要关键字,但是它们肯定会帮助一种语言成功。


1
IIRC Lisp没有关键字。特殊形式必须由编译器特殊对待,但是它们的名称是常规符号。
2013年

2
关键字是语法的功能,Lisp都不具备。我认为在Lisp中谈论关键字甚至没有任何意义。
约尔格W¯¯米塔格

2
我同意约尔格。我认为当一种语言的标记必须明确定义为特殊标记才能与结构相似的标记区别开来时,就可以谈论关键字。不同的标记导致不同的语法树。例如,if如果未将C定义为特殊字符(关键字),则C将是有效标识符。这意味着它if不是标识符,并if = 10给出了语法错误。如果我没有记错的话,Lisp的最小语法不区分defunfxy+(defun f (x y) (+ x y))
Giorgio 2013年

@Giorgio尤其if Common Lisp中(和其他Lisp的-2)有效的变量名称(defparameter if nil)不会破坏任何东西,它可以在形式使用像(unless if (setf if t))
tobyodavies

但是,同样(defun if ...)会失败。从注释中记下笔记并编辑答案。我可以同意,例如,特殊形式不是与C处于同一级别的关键字,它们仍然是Lisp最接近的东西。
scrwtp

8

TCL没有关键字,实际上只有12个语法规则。虽然它不像以前那样流行,但它具有预期的利基,并且嵌入在ECAD和路由器中,因此在我看来,它无疑是实用的。

我也认为这可能表明为什么许多语言不采用这种方法。是的,完全可以编写TCL解析器(可以说比许多其他语言更容易),但是您不能为该语言编写非常有用的BNF语法,而且许多人似乎在学习该语言时遇到了麻烦。我怀疑这至少部分是由于缺少关键字。


2
在这方面,Tcl与Lisp非常相似,只是Tcl具有“一切都是字符串”而不是“一切都是列表”。一个列表只是其中包含空格的字符串,而过程调用只是一个列表,其第一个元素被解释为过程的名称,其余元素被解释为其过程的参数。这本质上是Lisp S-Expression。
约尔格W¯¯米塔格

是的,它们都使用波兰语表示法并且是同构符号,因此具有非常相似的语义
jk。

5

如今,计算机已经足够强大,可以从上下文中推断出含义。

这是否意味着您想要的语法不是上下文无关的?祝好运。

这不是关于强大与否的问题。关于语言,有永恒不变的规则-数学规则。这以及编程语言在语法上应易于使用的事实,将使CFG成为未来几十年的规则。

顺便说一句,在Haskell中像语法一样,您只需编写类似

f x y = (x+1)*(y-1)

定义功能。但是请注意,在这种情况下,“关键字”是“ =”。如果您错过它,那么解析器中将会发生可怕的事情。

但这是我同意的一点,我发现这比所有引入其他语言的功能的def,dcl,fun,fn,function或what-not关键字直观得多。

但是,该语法可以用普通的旧版LALR(1)编写,此处“从上下文推断”没有任何含义。


1
+1可以解决这个问题(如今,计算机已经足够强大,可以从上下文中推断出含义)。我认为之所以首选CFG语法,是因为它们允许归纳定义程序结​​构。我不明白为什么即使在100年后也想改变这一点,也许我只是缺乏想象力?
乔治

2
CFG已经死了,已经死了几十年了。HTML中的JavaScript,甚至C中的C格式字符串,甚至OCAMl中的嵌套注释-所有这些内容都不是上下文无关的。而且,在PEG和GLR时代,为什么现在要限制自己选择这样一个任意选择的形式主义?
SK-logic

1
@Ingo,是的,您是对的,错误地选择了一个例子。我的意思是混合可扩展(即高阶)语法,不是CFG。
SK-logic

2
@ SK-logic:我不知道您从哪里得到CFG已经死了的信息。我一直在和我的一位前同事交谈,在过去的20年中,他一直在教编译器构造,而CFG似乎还没有死。
乔治

1
@Ingo:据我所知,非CF方面是通过语义分析解析树来处理的。例如,{ int x = 0; x = "HELLO"; }应该产生一个解析树,但是当编译器在第二个赋值中查找x时,会看到它已被声明为int并发出类型错误。因此,即使程序的CF结构正确,也会拒绝该程序。
Giorgio

4

据我所知,Smalltalk是关键字最少的语言(如果我不算Brainfuck之类的语言)。Smalltalk的关键字 truefalsenilselfsuperthisContext

我设计了一种语言,灵感来自小话,没有关键字。但是经过一段时间的使用,我最终添加了一些关键字,主要用于语法糖。

因此,我认为没有关键字的语言是可能的,但这不是很实用,这就是所有流行语言都带有关键字的原因。


如果Smalltalk中有支持消息的隐式接收器发送,那么至少truefalse并且nil可以被定义为在该接收机隐式的方法,而且,给出的反射能力,可能是其它三个为好。
约尔格W¯¯米塔格

1
这些不是关键字,它们是伪变量。“伪”,因为truefalse以及nil由环境提供的著名的价值观和selfsuperthisContext你不能设置变量,但其值修改为执行的结果。
Frank Shearar

3

您似乎在错误的假设下努力工作,那里的关键字使编译器的工作变得更容易。尽管它们确实使编译器的工作变得更容易,但它们还有一个更重要的好处:它们使阅读代码的人更容易

是的,您可以查看大量上下文并弄清楚您正在查看函数声明或变量声明,但是取决于上下文和所涉及代码的复杂性,可能需要很长时间才能弄清楚。或者,您可以在其中有一个方便的关键字,例如functionvar,您会立即知道要查看的内容。

是的,他们使代码更复杂的,但考虑到计划花更多的时间在维护比在生产中,他们的代码被读取,调试和维护很多比它被创建,试图为您的语言设计出使编写变得容易而不是易于阅读是有害的过早优化的经典案例。

另外,不要轻视使编译器的工作更容易的概念。解析越容易,代码的编译速度就越快,这意味着编辑-构建-调试周期变得更快,这意味着您的工作效率提高了。

当您拥有大型,复杂的代码库时,这可能在生产力上造成不小的差异。例如,在我工作的地方,有一个正在运行的程序,大约有400万行Delphi。我们还有另一个大约300,000行C ++的模块。它们的编译时间大约相同。(大约3分钟。)如果我们有400万行C ++,则可能要花一个小时才能完成!


所有的优点。+1

如果小说中的每一个名词,动词,副词和形容词都被标记成这样,那将使阅读变得更加困难!

@JarrodRoberson:可以,但是代码不是一本新书。自然语言与编程语言有很大不同。自然语言可以直观地理解,而编程语言则具有形式语义。 用来阅读和理解其含义的技术非常不同,尝试像您一样将两者等同起来是错误的。
梅森惠勒2013年

我说的是编译器作家,它不同于编译器。编译器在更快的硬件上变得更快,编译器作者是人类,我们不遵守摩尔定律!

我倾向于使用的代码库比小说的长度大几个数量级,大多数是> 1,000,000+ 代码,最长的小说是<2,000,000单词!就像小说一样,它们是人类所阅读的,实际上花在阅读代码上的时间要多于编写代码的时间!如果代码库已有10多年的历史,并且代码行数超过1,000,000,则开发人员在10年以上的时间内读取的代码数量比最初创建时所花的时间少。

2

有一些罕见的例子。

APL仅使用符号-但是很多符号!您需要特殊的键盘才能使用该语言。

看到这篇维基百科文章

CORAL 66-具有关键字,但只有用单引号引起来时才能识别它们。

PL / 1也有关键字-但您也可以将它们用作变量或过程名称。

总而言之,您的问题有点像问“为什么口头语言有单词?”。


补充一点,如果您喜欢APL的外观,但又不想购买新键盘,那么J就是问题。
AakashM

0

主要原因是人和计算机都更容易解析。要在没有关键字的情况下消除复杂语言的歧义,就需要使用许多符号作为语法,这将造成不必要的混乱。它比容易阅读function得多$!{}。上下文并不能解决所有歧义。


1
我认为答案中的关键词很复杂,一种经过充分设计的语言应该简单而不是复杂

1
@贾罗德·罗伯森:达芬奇:“简单是终极的精巧”,《圣Exupéry》,Antonine de SaintExupéry:“似乎没有多余的东西可以达到完美,而没有多余的东西可以达到完美”。
Giorgio

1
@Jarrod:所有有意义的表达性计算机语言都是复杂的。
DeadMG

1
@DeadMG:方案非常简单,同时又富有表现力。不幸的是,据我所知它缺乏标准化的库。
乔治

Erlang很有表现力,语法上并不复杂。我认为所有功能语言最终都将具有较少保留关键字的表现力。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.