22

似乎过去 20 年出现的大多数新编程语言都是用 C 编写的。这是完全有道理的,因为 C 可以被视为一种可移植的汇编语言。但我很好奇的是,这是否以任何方式限制了语言的设计。促使我提出问题的原因是考虑如何在 Python 中直接使用 C 堆栈来调用函数。显然,编程语言设计者可以用他们想要的任何语言做任何他们想做的事,但在我看来,你选择编写新语言的语言会让你处于某种心态,并给你一些难以忽视的捷径。这些语言的其他特征是否来自用该语言编写的(好或坏)?

4

9 回答 9

8

我倾向于不同意。

我不认为语言的编译器或解释器是用 C 实现的——毕竟,你可以用 C 实现一个完全不同于它的宿主环境的虚拟机,这意味着你可以摆脱 C / 近 -汇编语言思维。

然而,更难断言 C 语言本身对后来的语言设计没有任何影响。例如,使用花括号{ }将语句分组为块,空格和缩进并不重要的概念,本机类型的名称(int,char等)和其他关键字,或者变量的定义方式(即首先类型声明,后跟变量名,可选初始化)。当今许多流行且广泛传播的语言(C++、Java、C#,我相信还有更多)与 C 共享这些概念。(这些可能对 C 来说并不是全新的,但 AFAIK C 提出了这一点语言语法的特殊组合。)

于 2010-08-18T15:40:21.290 回答
5

不,简而言之。现实情况是,看看用 C 编写的语言。例如,Lua 与 C 相差无几,而无需成为 Perl。它具有一流的功能,全自动内存管理等。

新语言受其实现语言的影响是不寻常的,除非所述语言包含严重的限制。虽然我绝对不赞成 C,但它不是一种受限语言,与更现代的语言相比,它非常容易出错且编程速度慢。哦,除了在 CRT 中。例如,Lua 不包含目录功能,因为它不是 CRT 的一部分,因此他们无法在标准 C 中可移植地实现它。这是 C 受到限制的一种方式。但就语言功能而言,它不受限制。

如果你想构造一个论点,说用 C 实现的语言具有 XYZ 限制或特征,你必须证明在 C 中以另一种方式做事是不可能的。

于 2010-08-18T15:36:31.213 回答
5

即使使用 C 实现,您在实现方面也出奇地自由。例如,小鸡方案使用 C 作为中间体,但仍设法将堆栈用作其垃圾收集器中的苗圃代。

也就是说,在某些情况下存在限制。恰当的例子:GHC haskell 编译器有一个称为Evil Mangler的 perl 脚本来更改 GCC 输出的汇编代码以实现一些重要的优化。出于这个原因,他们一直在转向内部生成的程序集和 LLVM。也就是说,这并没有限制语言设计——只有编译器对可用优化的选择。

于 2010-08-18T15:39:27.620 回答
4

C 堆栈只是系统堆栈,这个概念比 C 早了很多。如果您学习计算理论,您会发现使用堆栈非常强大。

使用 C 来实现语言可能对这些语言影响很小,尽管设计和实现语言的人对 C(和其他类似 C 的语言)的熟悉程度可能对他们的设计产生了很大影响。即使您没有积极复制另一种语言的最佳部分,也很难不受以前所见事物的影响。

但是,许多语言确实使用 C 作为它们与其他事物之间的粘合剂。部分原因是许多操作系统都提供了 C API,因此要访问它很容易使用 C。此外,C 是如此常见和简单,以至于许多其他语言都有某种与之交互的方式。如果您想将两个用不同语言编写的模块粘合在一起,那么使用 C 作为中间人可能是最简单的解决方案。

用 C 语言实现一种语言可能对其他语言产生了最大的影响,最可能是诸如如何在字符串中完成转义之类的事情,这可能不是那么限制。

于 2010-08-18T15:49:39.017 回答
3

唯一限制语言设计的是语言设计者的想象力和技术能力。正如您所说,C 可以被认为是一种“可移植的汇编语言”。如果这是真的,那么询问 C 是否限制了设计类似于询问汇编是否限制了语言设计。由于以任何语言编写的所有代码最终都作为汇编执行,因此每种语言都会受到相同的约束。因此,C 语言本身没有施加使用其他语言可以克服的限制。

话虽如此,用一种语言比另一种语言更容易做一些事情。许多语言设计者都考虑到了这一点。例如,如果该语言被设计为在字符串处理方面功能强大但性能不是问题,那么使用具有更好的内置字符串处理工具(如 C++)的语言可能会更优化。

许多开发人员选择 C ​​有几个原因。首先,C 是一种非常通用的语言。尤其是在开源项目中,找到一个有经验的 C 语言开发人员比找到一个具有同等技能的其他语言开发人员要容易得多。其次,C 通常适合于微优化。在为脚本语言编写解析器时,解析器的效率对用该语言编写的脚本的整体性能有很大影响。对于编译语言,更高效的编译器可以减少编译时间。许多 C 编译器非常擅长生成极其优化的代码(这也是许多嵌入式系统使用 C 编程的部分原因),并且性能关键代码可以用内联汇编编写。此外,C 是标准化的,通常是静态目标。代码可以按照 ANSI/C89 标准编写,而不必担心它与 C 的未来版本不兼容。C99 标准中所做的修订增加了功能,但不会破坏现有代码。最后,C 语言非常便携。如果给定平台至少存在一个编译器,则它很可能是 C 编译器。使用像 C 这样的高度可移植的语言可以更容易地最大化可以使用新语言的平台数量。

于 2010-08-18T15:53:25.393 回答
3

想到的一个限制是可扩展性和编译器托管。考虑 C# 的情况。编译器是用 C/C++ 编写的,完全是本机代码。这使得在 C# 应用程序的进程中使用 变得非常困难。

这对 C# 的工具链具有广泛的影响。任何想要利用真正的 C# 解析器或绑定引擎的代码都必须至少有一个用本机代码编写的组件。这最终导致 C# 语言的大部分工具链都是用 C++ 编写的,这对于一种语言来说有点倒退。

这不会限制每个人说的语言,但肯定会对语言的体验产生影响。

于 2010-08-18T17:09:09.713 回答
2

垃圾收集。Java 或 .NET 之上的语言实现使用 VM 的 GC。那些在 C 之上的人倾向于使用引用计数。

于 2010-08-18T15:44:15.497 回答
1

在 C 中实现编译器/解释器没有任何重大限制。另一方面,实现语言 X 到 C 编译器确实如此。例如,根据关于 C-- 的 Wikipedia 文章,在将高级语言编译为 C 时,您无法进行精确的垃圾收集、高效的异常处理或尾递归优化。这就是 C-- 旨在解决的问题。

于 2010-08-18T16:20:49.237 回答
1

我能想到的一件事是函数不一定是语言中的第一类成员,这不能单独归咎于 C(我不是在谈论传递函数指针,尽管可以说 C 为您提供具有该功能)。

如果要在 groovy 中编写 DSL(/scheme/lisp/haskell/lua/javascript/ 以及我不确定的更多内容),函数可以成为一流的成员。使函数成为第一类成员并允许匿名函数允许编写简洁且更易于人类阅读的代码(如 LINQ 所演示的)。

是的,最终所有这些都在 C 下运行(或者如果你想达到那个水平,也可以在汇编下运行),但是就为语言的用户提供更好地表达自己的能力而言,这些抽象做得很好。

于 2010-08-18T15:37:21.683 回答