It seems that most new programming languages that have appeared in the last 20 years have been written in C. This makes complete sense as C can be seen as a sort of portable assembly language. But what I'm curious about is whether this has constrained the design of the languages in any way. What prompted my question was thinking about how the C stack is used directly in Python for calling functions. Obviously the programming language designer can do whatever they want in whatever language they want, but it seems to me that the language you choose to write your new language in puts you in a certain mindset and gives you certain shortcuts that are difficult to ignore. Are there other characteristics of these languages that come from being written in that language (good or bad)?
似乎在过去的20年里出现的大多数新的编程语言都是在C语言中编写的,因此C可以被看作是一种可移植的汇编语言。但我好奇的是,这是否以任何方式限制了语言的设计。促使我提出这个问题的原因是思考如何在Python中直接使用C堆栈来调用函数。显然,编程语言设计者可以用他们想要的任何语言来做任何他们想做的事情,但是在我看来,你选择编写新语言的语言会让你处于某种思维模式,并给你一些难以忽视的捷径。这些语言还有其他的特点吗(好还是坏)?
9 个解决方案
#1
4
Even with a C implementation, you're surprisingly free in terms of implementation. For example, chicken scheme uses C as an intermediate, but still manages to use the stack as a nursery generation in its garbage collector.
即使有了C实现,在实现方面您也会感到意外的*。例如,chicken scheme使用C作为中介,但仍然在其垃圾收集器中使用堆栈作为托儿所生成。
That said, there are some cases where there are constraints. Case in point: The GHC haskell compiler has a perl script called the Evil Mangler to alter the GCC-outputted assembly code to implement some important optimizations. They've been moving to internally-generated assembly and LLVM partially for that reason. That said, this hasn't constrained the language design - only the compiler's choice of available optimizations.
也就是说,有些情况下存在约束条件。恰当的例子:GHC haskell编译器有一个名为Evil Mangler的perl脚本,用于修改gcc输出的汇编代码,以实现一些重要的优化。由于这个原因,他们已经转向了内部生成的程序集和LLVM。也就是说,这并没有限制语言设计——只有编译器选择可用的优化。
#2
8
I tend to disagree.
我倾向于不同意。
I don't think it's so much that a language's compiler or interpreter is implemented in C — after all, you can implement a virtual machine with C that is completely unlike its host environment, meaning that you can get away from a C / near-assembly language mindset.
我不认为语言的编译器或解释器是在C语言中实现的,毕竟,您可以实现一个与宿主环境完全不同的虚拟机,这意味着您可以摆脱C /接近汇编语言的思维模式。
However, it's more difficult to claim that the C language itself didn't have any influence on the design of later languages. Take for example the usage of curly braces { }
to group statements into blocks, the notion that whitespace and indentation is mostly unimportant, native type's names (int
, char
, etc.) and other keywords, or the way how variables are defined (ie. type declaration first, followed by the variable's name, optional initialization). Many of today's popular and wide-spread languages (C++, Java, C#, and I'm sure there are even more) share these concepts with C. (These probably weren't completely new with C, but AFAIK C came up with that particular mix of language syntax.)
然而,更难以断言C语言本身对后来语言的设计没有任何影响。例如,使用花括号{}将语句分组成块,空格和缩进的概念大多不重要,本机类型的名称(int, char,等等)和其他关键字,或者变量的定义方式(例如)。首先是类型声明,然后是变量名,可选的初始化)。现在很多流行的、广泛传播的语言(c++、Java、c#,我确信还有更多)都与C分享了这些概念(这些对C来说可能并不是全新的,但是AFAIK C提出了这种语言语法的混合)。
#3
5
No, in short. The reality is, look around at the languages that are written in C. Lua, for example, is about as far from C as you can get without becoming Perl. It has first-class functions, fully automated memory management, etc.
不,简而言之。实际情况是,看看在C. Lua中编写的语言,就像您在不成为Perl的情况下所能得到的那样。它具有一流的功能,完全自动化的内存管理等。
It's unusual for new languages to be affected by their implementation language, unless said language contains serious limitations. While I definitely disapprove of C, it's not a limited language, just very error-prone and slow to program in compared to more modern languages. Oh, except in the CRT. For example, Lua doesn't contain directory functionality, because it's not part of the CRT so they can't portably implement it in standard C. That is one way in which C is limited. But in terms of language features, it's not limited.
新语言受其实现语言的影响是很不寻常的,除非所述语言包含严重的限制。虽然我绝对不赞成C语言,但它并不是一种有限的语言,与更现代的语言相比,它很容易出错,编程速度也很慢。哦,除了CRT。例如,Lua不包含目录功能,因为它不是CRT的一部分,所以它们不能在标准C中实现它。但就语言功能而言,它并不局限。
If you wanted to construct an argument saying that languages implemented in C have XYZ limitations or characteristics, you would have to show that doing things another way is impossible in C.
如果你想构造一个论点,说在C中实现的语言有XYZ限制或特征,你就必须表明用另一种方式来做是不可能的。
#4
4
The C stack is just the system stack, and this concept predates C by quite a bit. If you study theory of computing you will see that using a stack is very powerful.
C栈只是系统堆栈,这个概念比C早了很多。如果你学习计算理论,你会发现使用堆栈是非常强大的。
Using C to implement languages has probably had very little effect on those languages, though the familiarity with C (and other C like languages) of people who design and implement languages has probably influenced their design a great deal. It is very difficult to not be influenced by things you've seen before even when you aren't actively copying the best bits of another language.
使用C实现语言对这些语言的影响可能很小,尽管设计和实现语言的人对C(以及其他C类语言)的熟悉程度可能对他们的设计产生了很大的影响。即使你没有积极地复制另一种语言的精华,你也很难不被你以前见过的东西所影响。
Many languages do use C as the glue between them and other things, though. Part of this is that many OSes provide a C API, so to access that it's easy to use C. Additionally, C is just so common and simple that many other languages have some sort of way to interface with it. If you want to glue two modules together which are written in different languages then using C as the middle man is probably the easiest solution.
然而,许多语言确实使用C作为它们和其他事物之间的粘合剂。部分原因是许多OSes提供了一个C API,因此要访问它就很容易使用C。此外,C是如此的普通和简单,以至于许多其他语言都有某种与它交互的方式。如果您想将两个用不同语言编写的模块粘在一起,那么使用C作为中间部分可能是最简单的解决方案。
Where implementing a language in C has probably influenced other languages the most is probably things like how escapes are done in strings, which probably isn't that limiting.
用C语言实现一种语言可能对其他语言的影响最大的可能是诸如如何在字符串中执行转义之类的事情,这可能并没有那么大的限制。
#5
3
The only thing that has constrained language design is the imagination and technical skill of the language designers. As you said, C can be thought of as a "portable assembly language". If that is true, then asking if C has constrained a design is akin to asking if assembly has constrained language design. Since all code written in any language is eventually executed as assembly, every language would suffer the same constraints. Therefore, the C language itself imposes no constraints that would be overcome by using a different language.
限制语言设计的唯一因素是语言设计者的想象力和技术能力。正如您所说,C可以被认为是一种“可移植汇编语言”。如果这是真的,那么询问C是否限制了设计,就相当于问程序集是否限制了语言设计。由于使用任何语言编写的所有代码最终都作为汇编执行,所以每种语言都会受到相同的限制。因此,C语言本身没有通过使用另一种语言来克服的约束。
That being said, there are some things that are easier to do in one language vs another. Many language designers take this into account. If the language is being designed to be, say, powerful at string processing but performance is not a concern, then using a language with better built-in string processing facilities (such as C++) might be more optimal.
也就是说,有一些事情用一种语言比用另一种语言更容易做。许多语言设计师都考虑到了这一点。如果语言被设计成能够处理字符串,但是性能并不重要,那么使用内置更好的字符串处理工具(如c++)的语言可能更理想。
Many developers choose C for several reasons. First, C is a very common language. Open source projects in particular like that it is relatively easier to find an experienced C-language developer than it is to find an equivalently-skilled developer in some other languages. Second, C typically lends itself to micro-optimization. When writing a parser for a scripted language, the efficiency of the parser has a big impact on the overall performance of scripts written in that language. For compiled languages, a more efficient compiler can reduce compile times. Many C compilers are very good at generating extremely optimized code (which is also part of the reason why many embedded systems are programmed in C), and performance-critical code can be written in inline assembly. Also, C is standardized and is generally a static target. Code can be written to the ANSI/C89 standard and not have to worry about it being incompatible with a future version of C. The revisions made in the C99 standard add functionality but don't break existing code. Finally, C is extremely portable. If at least one compiler exists for a given platform, it's most likely a C compiler. Using a highly-portable language like C makes it easier to maximize the number of platforms that can use the new language.
许多开发人员选择C有几个原因。首先,C是一种非常普遍的语言。特别是像这样的开放源码项目,找到一个有经验的c语言开发人员要比找到一些其他语言的技能相当的开发人员要容易得多。其次,C通常适合于微优化。当为脚本语言编写解析器时,解析器的效率对用脚本编写的脚本的整体性能有很大的影响。对于编译语言来说,一个更高效的编译器可以减少编译时间。许多C编译器非常擅长生成极其优化的代码(这也是许多嵌入式系统在C中编程的原因之一),而且性能关键代码可以在内联汇编中编写。此外,C是标准化的,通常是静态目标。代码可以编写到ANSI/C89标准,不必担心它与c的未来版本不兼容。最后,C是非常便携的。如果在给定的平台上至少存在一个编译器,那么它很可能是一个C编译器。使用像C这样的高可移植性语言可以更容易地最大化使用这种新语言的平台的数量。
#6
3
The one limitation that comes to mind is extensibility and compiler hosting. Consider the case of C#. The compiler is written in C/C++ and is entirely native code. This makes it very difficult to use in process with a C# application.
我想到的一个限制是可扩展性和编译器宿主。考虑c#的情况。编译器是用C/ c++编写的,完全是本机代码。这使得在c#应用程序的进程中使用非常困难。
This has broad implications for the tooling chain of C#. Any code which wants to take advantage of the real C# parser or binding engine has to have at least one component which is written in native code. This eventually results in most of the tooling chain for the C# language being written in C++ which is a bit backwards for a language.
这对c#的工具链有广泛的影响。任何想要利用c#解析器或绑定引擎的代码都必须至少有一个用本地代码编写的组件。这最终导致c#语言的大多数工具链都是用c++编写的,这对于语言来说有点落后。
This doesn't limit the language per say but definitely has an effect on the experience around the language.
这并不会限制语言的表达,但肯定会对语言的体验产生影响。
#7
2
Garbage collection. Language implementations on top of Java or .NET use the VM's GC. Those on top of C tend to use reference counting.
垃圾收集。Java或. net之上的语言实现使用VM的GC。在C上面的那些倾向于使用引用计数。
#8
1
One thing I can think of is that functions are not necessarily first class members in the language, and this is can't be blamed on C alone (I am not talking about passing a function pointer, though it can be argued that C provides you with that feature).
我能想到的一件事是,函数不一定是语言中的第一类成员,这不能单独归咎于C(我说的不是传递函数指针,尽管可以认为C为您提供了这个特性)。
If one were to write a DSL in groovy (/scheme/lisp/haskell/lua/javascript/and some more that I am not sure of), functions can become first class members. Making functions first class members and allowing for anonymous functions allows to write concise and more human readable code (like demonstrated by LINQ).
如果要在groovy中编写DSL (/scheme/lisp/haskell/lua/javascript/还有一些我不确定的),函数可以成为一流的成员。使函数成为第一类成员并允许匿名函数可以编写简洁的、更易于阅读的代码(如LINQ所示)。
Yes, eventually all of these are running under C (or assembly if you want to get to that level), but in terms of providing the user of the language the ability to express themselves better, these abstractions do a wonderful job.
是的,最终所有这些都运行在C(或程序集,如果您想达到那个级别)下,但是就提供语言的用户更好地表达自己的能力而言,这些抽象做得很好。
#9
1
Implementing a compiler/interpreter in C doesn't have any major limitations. On the other hand, implementing a language X to C compiler does. For example, according to the Wikipedia article on C--, when compiling a higher level language to C you can't do precise garbage collection, efficient exception handling, or tail recursion optimization. This is the kind of problem that C-- was intended to solve.
在C语言中实现编译器/解释器没有任何主要的限制。另一方面,实现一种语言X到C编译器是可以的。例如,根据Wikipedia关于C的文章,当将高级语言编译为C时,您不能执行精确的垃圾收集、有效的异常处理或尾部递归优化。这就是C要解决的问题。
#1
4
Even with a C implementation, you're surprisingly free in terms of implementation. For example, chicken scheme uses C as an intermediate, but still manages to use the stack as a nursery generation in its garbage collector.
即使有了C实现,在实现方面您也会感到意外的*。例如,chicken scheme使用C作为中介,但仍然在其垃圾收集器中使用堆栈作为托儿所生成。
That said, there are some cases where there are constraints. Case in point: The GHC haskell compiler has a perl script called the Evil Mangler to alter the GCC-outputted assembly code to implement some important optimizations. They've been moving to internally-generated assembly and LLVM partially for that reason. That said, this hasn't constrained the language design - only the compiler's choice of available optimizations.
也就是说,有些情况下存在约束条件。恰当的例子:GHC haskell编译器有一个名为Evil Mangler的perl脚本,用于修改gcc输出的汇编代码,以实现一些重要的优化。由于这个原因,他们已经转向了内部生成的程序集和LLVM。也就是说,这并没有限制语言设计——只有编译器选择可用的优化。
#2
8
I tend to disagree.
我倾向于不同意。
I don't think it's so much that a language's compiler or interpreter is implemented in C — after all, you can implement a virtual machine with C that is completely unlike its host environment, meaning that you can get away from a C / near-assembly language mindset.
我不认为语言的编译器或解释器是在C语言中实现的,毕竟,您可以实现一个与宿主环境完全不同的虚拟机,这意味着您可以摆脱C /接近汇编语言的思维模式。
However, it's more difficult to claim that the C language itself didn't have any influence on the design of later languages. Take for example the usage of curly braces { }
to group statements into blocks, the notion that whitespace and indentation is mostly unimportant, native type's names (int
, char
, etc.) and other keywords, or the way how variables are defined (ie. type declaration first, followed by the variable's name, optional initialization). Many of today's popular and wide-spread languages (C++, Java, C#, and I'm sure there are even more) share these concepts with C. (These probably weren't completely new with C, but AFAIK C came up with that particular mix of language syntax.)
然而,更难以断言C语言本身对后来语言的设计没有任何影响。例如,使用花括号{}将语句分组成块,空格和缩进的概念大多不重要,本机类型的名称(int, char,等等)和其他关键字,或者变量的定义方式(例如)。首先是类型声明,然后是变量名,可选的初始化)。现在很多流行的、广泛传播的语言(c++、Java、c#,我确信还有更多)都与C分享了这些概念(这些对C来说可能并不是全新的,但是AFAIK C提出了这种语言语法的混合)。
#3
5
No, in short. The reality is, look around at the languages that are written in C. Lua, for example, is about as far from C as you can get without becoming Perl. It has first-class functions, fully automated memory management, etc.
不,简而言之。实际情况是,看看在C. Lua中编写的语言,就像您在不成为Perl的情况下所能得到的那样。它具有一流的功能,完全自动化的内存管理等。
It's unusual for new languages to be affected by their implementation language, unless said language contains serious limitations. While I definitely disapprove of C, it's not a limited language, just very error-prone and slow to program in compared to more modern languages. Oh, except in the CRT. For example, Lua doesn't contain directory functionality, because it's not part of the CRT so they can't portably implement it in standard C. That is one way in which C is limited. But in terms of language features, it's not limited.
新语言受其实现语言的影响是很不寻常的,除非所述语言包含严重的限制。虽然我绝对不赞成C语言,但它并不是一种有限的语言,与更现代的语言相比,它很容易出错,编程速度也很慢。哦,除了CRT。例如,Lua不包含目录功能,因为它不是CRT的一部分,所以它们不能在标准C中实现它。但就语言功能而言,它并不局限。
If you wanted to construct an argument saying that languages implemented in C have XYZ limitations or characteristics, you would have to show that doing things another way is impossible in C.
如果你想构造一个论点,说在C中实现的语言有XYZ限制或特征,你就必须表明用另一种方式来做是不可能的。
#4
4
The C stack is just the system stack, and this concept predates C by quite a bit. If you study theory of computing you will see that using a stack is very powerful.
C栈只是系统堆栈,这个概念比C早了很多。如果你学习计算理论,你会发现使用堆栈是非常强大的。
Using C to implement languages has probably had very little effect on those languages, though the familiarity with C (and other C like languages) of people who design and implement languages has probably influenced their design a great deal. It is very difficult to not be influenced by things you've seen before even when you aren't actively copying the best bits of another language.
使用C实现语言对这些语言的影响可能很小,尽管设计和实现语言的人对C(以及其他C类语言)的熟悉程度可能对他们的设计产生了很大的影响。即使你没有积极地复制另一种语言的精华,你也很难不被你以前见过的东西所影响。
Many languages do use C as the glue between them and other things, though. Part of this is that many OSes provide a C API, so to access that it's easy to use C. Additionally, C is just so common and simple that many other languages have some sort of way to interface with it. If you want to glue two modules together which are written in different languages then using C as the middle man is probably the easiest solution.
然而,许多语言确实使用C作为它们和其他事物之间的粘合剂。部分原因是许多OSes提供了一个C API,因此要访问它就很容易使用C。此外,C是如此的普通和简单,以至于许多其他语言都有某种与它交互的方式。如果您想将两个用不同语言编写的模块粘在一起,那么使用C作为中间部分可能是最简单的解决方案。
Where implementing a language in C has probably influenced other languages the most is probably things like how escapes are done in strings, which probably isn't that limiting.
用C语言实现一种语言可能对其他语言的影响最大的可能是诸如如何在字符串中执行转义之类的事情,这可能并没有那么大的限制。
#5
3
The only thing that has constrained language design is the imagination and technical skill of the language designers. As you said, C can be thought of as a "portable assembly language". If that is true, then asking if C has constrained a design is akin to asking if assembly has constrained language design. Since all code written in any language is eventually executed as assembly, every language would suffer the same constraints. Therefore, the C language itself imposes no constraints that would be overcome by using a different language.
限制语言设计的唯一因素是语言设计者的想象力和技术能力。正如您所说,C可以被认为是一种“可移植汇编语言”。如果这是真的,那么询问C是否限制了设计,就相当于问程序集是否限制了语言设计。由于使用任何语言编写的所有代码最终都作为汇编执行,所以每种语言都会受到相同的限制。因此,C语言本身没有通过使用另一种语言来克服的约束。
That being said, there are some things that are easier to do in one language vs another. Many language designers take this into account. If the language is being designed to be, say, powerful at string processing but performance is not a concern, then using a language with better built-in string processing facilities (such as C++) might be more optimal.
也就是说,有一些事情用一种语言比用另一种语言更容易做。许多语言设计师都考虑到了这一点。如果语言被设计成能够处理字符串,但是性能并不重要,那么使用内置更好的字符串处理工具(如c++)的语言可能更理想。
Many developers choose C for several reasons. First, C is a very common language. Open source projects in particular like that it is relatively easier to find an experienced C-language developer than it is to find an equivalently-skilled developer in some other languages. Second, C typically lends itself to micro-optimization. When writing a parser for a scripted language, the efficiency of the parser has a big impact on the overall performance of scripts written in that language. For compiled languages, a more efficient compiler can reduce compile times. Many C compilers are very good at generating extremely optimized code (which is also part of the reason why many embedded systems are programmed in C), and performance-critical code can be written in inline assembly. Also, C is standardized and is generally a static target. Code can be written to the ANSI/C89 standard and not have to worry about it being incompatible with a future version of C. The revisions made in the C99 standard add functionality but don't break existing code. Finally, C is extremely portable. If at least one compiler exists for a given platform, it's most likely a C compiler. Using a highly-portable language like C makes it easier to maximize the number of platforms that can use the new language.
许多开发人员选择C有几个原因。首先,C是一种非常普遍的语言。特别是像这样的开放源码项目,找到一个有经验的c语言开发人员要比找到一些其他语言的技能相当的开发人员要容易得多。其次,C通常适合于微优化。当为脚本语言编写解析器时,解析器的效率对用脚本编写的脚本的整体性能有很大的影响。对于编译语言来说,一个更高效的编译器可以减少编译时间。许多C编译器非常擅长生成极其优化的代码(这也是许多嵌入式系统在C中编程的原因之一),而且性能关键代码可以在内联汇编中编写。此外,C是标准化的,通常是静态目标。代码可以编写到ANSI/C89标准,不必担心它与c的未来版本不兼容。最后,C是非常便携的。如果在给定的平台上至少存在一个编译器,那么它很可能是一个C编译器。使用像C这样的高可移植性语言可以更容易地最大化使用这种新语言的平台的数量。
#6
3
The one limitation that comes to mind is extensibility and compiler hosting. Consider the case of C#. The compiler is written in C/C++ and is entirely native code. This makes it very difficult to use in process with a C# application.
我想到的一个限制是可扩展性和编译器宿主。考虑c#的情况。编译器是用C/ c++编写的,完全是本机代码。这使得在c#应用程序的进程中使用非常困难。
This has broad implications for the tooling chain of C#. Any code which wants to take advantage of the real C# parser or binding engine has to have at least one component which is written in native code. This eventually results in most of the tooling chain for the C# language being written in C++ which is a bit backwards for a language.
这对c#的工具链有广泛的影响。任何想要利用c#解析器或绑定引擎的代码都必须至少有一个用本地代码编写的组件。这最终导致c#语言的大多数工具链都是用c++编写的,这对于语言来说有点落后。
This doesn't limit the language per say but definitely has an effect on the experience around the language.
这并不会限制语言的表达,但肯定会对语言的体验产生影响。
#7
2
Garbage collection. Language implementations on top of Java or .NET use the VM's GC. Those on top of C tend to use reference counting.
垃圾收集。Java或. net之上的语言实现使用VM的GC。在C上面的那些倾向于使用引用计数。
#8
1
One thing I can think of is that functions are not necessarily first class members in the language, and this is can't be blamed on C alone (I am not talking about passing a function pointer, though it can be argued that C provides you with that feature).
我能想到的一件事是,函数不一定是语言中的第一类成员,这不能单独归咎于C(我说的不是传递函数指针,尽管可以认为C为您提供了这个特性)。
If one were to write a DSL in groovy (/scheme/lisp/haskell/lua/javascript/and some more that I am not sure of), functions can become first class members. Making functions first class members and allowing for anonymous functions allows to write concise and more human readable code (like demonstrated by LINQ).
如果要在groovy中编写DSL (/scheme/lisp/haskell/lua/javascript/还有一些我不确定的),函数可以成为一流的成员。使函数成为第一类成员并允许匿名函数可以编写简洁的、更易于阅读的代码(如LINQ所示)。
Yes, eventually all of these are running under C (or assembly if you want to get to that level), but in terms of providing the user of the language the ability to express themselves better, these abstractions do a wonderful job.
是的,最终所有这些都运行在C(或程序集,如果您想达到那个级别)下,但是就提供语言的用户更好地表达自己的能力而言,这些抽象做得很好。
#9
1
Implementing a compiler/interpreter in C doesn't have any major limitations. On the other hand, implementing a language X to C compiler does. For example, according to the Wikipedia article on C--, when compiling a higher level language to C you can't do precise garbage collection, efficient exception handling, or tail recursion optimization. This is the kind of problem that C-- was intended to solve.
在C语言中实现编译器/解释器没有任何主要的限制。另一方面,实现一种语言X到C编译器是可以的。例如,根据Wikipedia关于C的文章,当将高级语言编译为C时,您不能执行精确的垃圾收集、有效的异常处理或尾部递归优化。这就是C要解决的问题。