有时在用不同的语言(C / C ++,C#)进行编程时,这种想法浮现在我脑海:


每种语言都用C编程语言编写吗?
C语言是所有语言的母亲/父亲?
每个概念(OOP等)都用C实现吗?

我的方向正确吗?

评论

@ X.L.Ant:许多(甚至大多数)C编译器都是用C编写的。

@Neil:C ++不能编译为任何东西。 C ++是一种语言。语言不编译,编译器编译。

@ X.L.Ant:我不这么认为。但是,例如,第一个Oberon编译器是用Oberon编写的,然后手动翻译(我猜是编译的一种形式)到Fortran。然后使用Fortran编译器对该编译器进行编译,使用生成的Oberon编译器来编译Oberon编译器,从那时起,将使用编译器的先前版本来编译下一个编译器。
@Neil真的不是那么学究。没错:语言是一种规范。它可以实现为编译器,解释器,混合器等。您可以为某种语言编写编译器,但是编译器不是该语言。我猜这个问题会引起混乱,因为除了参考实现之外,在任何地方都没有针对任何语言编写规范。但是即使在那种情况下,我也会认为语言(即作者心目中的理想)与实现/编译器/解释器/等不同。

唐纳德:这是一个很合理的问题,答案很明确。答案是否定的,没有理由不赞成。相反,请考虑回答和解释。

#1 楼



OCaml,Haskell,Lisp方言(例如Scheme)和其他几种语言经常被用于开发爱好语言。

许多语言都是用C语言实现的,普遍存在的语言以及诸如lexer-parser生成器之类的编译器编写工具(例如yacc和bison)已经被很好地理解并且几乎无处不在。最初创建。实际上,它最初是使用B语言开发的。较早的语言(如Fortran)通常在C尚未出现之前就使用本机汇编语言甚至机器代码进行引导。例如,功能范式(由Alonzo Church创立)是数学的基础,早于任何编程语言都存在。过程化和结构化的编程范式来自于像约翰·冯·诺依曼这样的理论家的数学著作。面向对象是由几项不同且无关的努力开发出来的,其中有些来自lambda演算(功能范式),有些则来自于动态编程系统,例如艾伦·凯(Alan Kay)在施乐PARC的SmallTalk。这些想法诞生几十年后,故事的一小部分。

评论


虽然确实很明显第一个C编译器显然不能用C编写,但现在肯定有可能。

– reirab
2014年12月22日15:14

@reirab可能且正确。 GCC用C编写,通常使用GCC进行编译。

– Darkhogg
2014年12月22日23:30

当然,GCC现在正在用C ++重写,但这并不像第一个C编译器无法用C编写的事实那样重要。

– Greyfade
2014年12月23日的1:35

@greyfade gcc已经有一段时间没有C了。它不是“现在正在被重写”,而是“已经用C ++编写了两年以上”(尽管它比这更旧,那是当合并发生时才将其移至C ++)。

–user40980
2014年12月23日下午4:26

@greyfade不是“ C,但具有C ++功能”,类似于C ++的定义吗?

– KutuluMike
2014年12月23日12:52

#2 楼


每一种语言都是用C语言编写的吗?


语言是一组抽象的数学规则和限制(“如果我写的话,那会发生”)。它实际上不是用任何东西编写的。

它通常是由形式化的英语子集,数学符号以及某些特殊的规范语言混合而成的。语法通常是在EBNF或ABNF的变体中指定的。例如,这是ISO Ruby语言规范中的for表达式的规范:


§11.5.2.3.4for表达式

语法



for-expression→for变量[此处无行终止符]在表达式中从句结尾


for变量→左侧|多个左侧


语义
/>
for-expression的计算方式如下:


计算表达式。如果对表达式的求值是由break-expression,next-expression或redo-expression终止的,则该行为不确定。否则,让O为结果值。

E为形式为primary-expression [此处没有行终止符]的主方法调用。块参数列表|















函数体,主体函数,主体表达式的值是O。 >评估E;但是,如果在评估过程中调用了一个块体为表达式的子句的复合语句的块,则除步骤c)和步骤e)4)以外,第11.3.3节中的步骤应予执行。

for-expression的值是调用的结果值。



这里是一个与Scala的类型一致性规则不同的示例:


多态类型[a1>:L1 <:U1,…,an>:Ln <:Un] T符合多态类型[a1>:L′1 <:U′1,…,an>:L'n < :U'n] T'如果假设L'1 <:a1 <:U'1,…,L'n <:an <:U'n一个人具有T <:T'和Li <:L'i并且U'i <:U i for i∈{1,…,n}。




C语言是所有语言的母亲/父亲吗? >

不,不是。 C还很年轻。有很多古老的语言。由于时间旅行实际上是不可能的,因此C根本不可能对那些旧语言产生任何影响。


Plankalkül(1943)
Speedcoding(1953)
Fortran(1954)
IPL(1956)
Lisp(1958)
Algol(1958)
COBOL(1959)
JOVIAL(1960)
APL(1962)
SIMULA(1962)
SNOBOL(1962)
CPL(1963)
BASIC(1964)
PL / I(1964)
角色扮演(1964)
BCPL(1966)
ISWIM(1966)
MUMPS(1967)
Forth(1968)
B(1969)
极乐(1970)
帕斯卡(1971)
KRL(1971)
小话(1972)

所有这些在C发明之前就已经存在。即使在C存在之后,其他许多人也对C毫无影响。 PASCAL语言家族(ALGOL-58,ALGOL-60,ALGOL-X,ALGOL-W,PASCAL,Modula-2,Oberon,Oberon-2,Active Oberon,Component Pascal)是完全独立的谱系。整个Lisp系列(LISP,Franz Lisp,InterLisp,MacLisp,Scheme,Flavours,LOOPS,CommonLoops,Dylan,CommonLisp,Arc,Clojure,Racket等)也不相关。功能语言(ISWIM,KRL,Miranda,ML,SML,CAML,OCaml,F#,Haskell,Gofer,Clean)和整个依存类型家族(Agda,Coq,GURU,Idris)离C越远。对于Smalltalk系列(Smalltalk,Self,Newspeak,Us,Korz),逻辑编程系列(PLANNER,Prolog,Mercury),SQL以及许多其他产品也是如此。每个概念(OOP等)都用C语言实现吗?


最早的具有面向对象概念的语言是Simula(1960)和Smalltalk(1972),但是面向对象的系统早在1953年就已经建立(没有这样称呼)。再一次,这比C早就存在了,所以OO不可能与C有任何关系。

评论


1970年:Niklaus Wirth创建了一种程序语言Pascal。评论家立即谴责Pascal,因为它使用x:= x + y语法,而不是更熟悉的类似C的x = x + y。尽管C尚未被发明,但仍发生了这种批评。

–leftaround关于
2014年12月22日23:35

@leftaroundabout:那是一个很棒的博客,这是我多年来的最爱之一。

–Jörg W Mittag
2014年12月22日23:38

@FrancisDavey:谢谢。我开始从内存中编译列表,然后通过在Wikipedia上查找不记得的日期来添加日期。之后,我在Wikipedia上找到了语言的时间表,并从中选择了更多的语言。由于有关BCPL的文章引用了1966,但时间轴引用了1967,所以我没有注意到我已经添加了BCPL。我将删除重复项。

–Jörg W Mittag
2014年12月23日在23:03

在您的列表中,“ htroF”不是反拼吗?

–chux-恢复莫妮卡
2015年1月3日,下午6:53

“时间旅行实际上是不可能的” –这是一个极具争议的主张。当然不会减损此答案的价值。

–康拉德·鲁道夫(Konrad Rudolph)
2015年3月14日在16:37



#3 楼

许多重要语言的大多数核心都是用C编写的,但是事情正在发生变化:


Python的参考实现(CPython)是用C编写的(但是还有其他实现用C编写)其他语言,例如Jython / Java,PyPy / Python,IronPython / C#...)
PHP Zend Engine用C编写。 ,但现在类库始终使用Java编写(因为它们打算使用Java VM本身运行)。某些使用JNI(Java本机接口)的库可能会用多种其他语言部分编写,因为它们打算在JVM之外使用。

Sun / Oracle VM用C ++编写。 BEA / Weblogic / Oracle VM用C编写。但是有JVM用Java,Lisp,SmallTalk(IBM)编写。带有大量用Perl和C编写的模块(但是Pugs是Perl 6编程语言的编译器和解释器,是用Haskell编写的)。
正式的Ruby解释器,通常称为Matz的Ruby解释器或MRI用C语言编写,并使用其自己的特定于Ruby的虚拟机(但JRuby是在Java虚拟机上运行的Java实现; Rubinius是C ++字节码虚拟机,使用LLVM在运行时编译为机器代码。 ..)
大约50%的R用C写成,而C当然是用C写成的! (但是第一个针对PDP-11的C编译器是B和汇编器的结合。)

经常选择C的原因很多:性能,可移植性,经验。 >
最后一个可能是最重要的:Python于1991年启动,PHP在1994/1995年,Perl在1988年,Ruby在1995年。在那些年中,Java刚刚发布,而C ++还没有很好的标准化。 >

有些相关:


没有运行时的功能语言是否可以用C编写?


评论


从编译器/解释器的实现角度来看,C已经/是一个参考点。另外,它直接或间接地影响了许多后来的语言(至少在语法上)。

–manlio
2014-12-22 10:41



很快,您就可以说C#是用C#编写的! (有点儿)

– DLeh
2014年12月22日在18:44

大多数Mono(包括C#编译器和许多/大部分.NET基类库)都是用C#编写的。

–凯蒂·基莲(Katie Kilian)
2014年12月23日下午6:31

问题答案“ C是所有语言的父母吗?”是“否”,因此我认为提供很多用C编写的示例没有帮助。反示例将有所帮助,但是您的选择仍然是C派生的。例如,即使Java,Python等现在是自托管的,它们仍然是从C启动的,因此它们就像是C的“孙子代”。LISP,FORTRAN,ML和(当然)机器代码之类的语言都是真正的反例,因为C从未参与他们的创造。

–Warbo
2014年12月23日在18:39

当然,要尽可能多地实现许多语言的愿望。但是,似乎大多数语言都依赖C,因为大多数语言都需要能够调用C才有用。大多数现代操作系统API和有用的库都倾向于具有C绑定。您还必须注意“写入”的含义。语言实现通常包含多个部分:至少是编译器和运行时系统。运行时系统通常用C编写,以更好地与OS交互。

–别名
2014年12月24日,0:21

#4 楼

否,某些语言早于C。许多语言是独立于C实现的,例如参见http://en.wikipedia.org/wiki/Lisp_%28programming_language%29

评论


Java有许多实现,大多数是用Java编写的。 Objective-C的GNU实现是用C编写的(我相信它们是最近更新的C ++),LLVM实现是用C ++编写的,并且曾经有一个用C#编写的解释器。 Python有很多实现,一种是用RPython编写的,一种是用Java编写的,一种是C#编写的,一种是C编写的。PHP有六个主要实现,两种是用Java编写的,两种是C#编写的,一种是C编写的,一种是C ++编写的。

–Jörg W Mittag
2014年12月22日在9:28

不会。语言设计师当然会受到其他语言的影响,但如果愿意,他们可以选择忽略这些影响。

–Jörg W Mittag
2014年12月22日上午11:08

@FaizanRabbani语言从本质上讲是范式,模式和折衷的概念和选择-通常是“从其他语言创建/改编的语言”,但这与编译器的实现语言完全无关;语言X可以从语言Y派生而来,但可以用C或其他完全实现的语言实现-通常就是这种情况。在这种情况下,“概念祖先”很重要,但是编译器语言只是几乎不相关的技术细微差别,可以随着时间的流逝而变化。

– Peteris
2014年12月22日在16:44



最后一个链接是否具有可疑的价值-它中有太多错误,无法真正加以重视。

–未知编码器
2014年12月22日下午16:50

@SebastianGodelet:HotSpot不是Java语言的实现。它是JVM字节码语言的实现。那是两种完全不同的语言。 Java语言使用最广泛的实现是由Martin Odersky(由Scala出名)用100%Java写的Oracle JDK / OpenJDK中的javac,用100%Java(从IBM的Jikes编译器派生)编写的Eclipse编译器。来自IBM的J9,也来自Jikes和100%Java。 AFAIK是唯一在某种程度上广泛使用并且不是用Java编写的Java编译器

–Jörg W Mittag
2014年12月23日在15:54

#5 楼

如果可以的话,我会发表评论,但我不能这样说:

C如此普遍存在的原因之一是因为它是最早开发的语言之一,并且数量众多现代语言的基础是其结构(Java,Go,PHP,Perl等)的基础-似乎它的存在空间比实际更多。

另一个经常被遗忘的原因是1973 Unix是用C重写的,并且Unix的许多系统调用也可以作为C程序/函数使用,从而使两者高度互连。由于Unix是整个现代编程发展的重要组成部分,因此C陷入了臭名昭著的局面。

说了这么多,您的问题的答案是“否”。 C基于一种称为ALGOL的语言,并且有很多竞争对手都使用ALGOL(FORTRAN,Lisp,COBOL)和C(没人想到)。面向对象的编程,可以说是编程设计中最大的范式转变,并不是源于C的-尽管C ++是一种非常流行的OOP语言(它首先出现在Lisp或Simula 67中,具体取决于您询问的人)。到OOP出现时,C已经成为一种流行的语言,因此它不必成为第一门语言-它是如此流行,以至于C ++的“扩展”可以说也成为主要的OOP语言之一。它仍然在现代使用,主要是由于其强大的内存控制功能(您可以直接分配和取消分配结构创建的内存),从而使其可以在内存预算紧张的情况下(例如视频游戏)和高度优化的编译器(显然取决于编译器)。诚然,随着Java JIT编译和语言存储管理器变得更加先进,即使这些功能也正在逐渐失去优势。

评论


除了先前的回答(尤其是在前一个答案中)提出和解释的观点外,这似乎没有提供任何实质性的内容,除了一个有疑问的说法,即“ C基于一种称为ALGOL的语言”

– gna
2014-12-22 14:22



C在ALGOL中的基础几乎没有问题...请参阅cm.bell-labs.com/who/dmr/chist.html,en.wikipedia.org/wiki/C_%28programming_language%29)

– WannabeCoder
2014-12-22 14:41

实际的故事要比这复杂得多和有趣的;我想说的是,这里的布置方式对读者几乎没有帮助

– gna
2014-12-22 17:56



#6 楼

显然不是。如果以前不存在C,如何用C编写第一个C编译器?这不是鸡与蛋的问题。 -托管或自行编译其语言,主要是为了推广该语言和编译器本身

评论


第一个Oberon编译器是用Oberon编写的。如果您是一名教授,并且有很多学生可以为您手动翻译编译器(Wirth教授有),那很好。

–Jörg W Mittag
2014-12-22 21:38

上面链接的引导文章中提到的@Jorg,所以我不必理会,因为这个问题是关于C的,所以没有C编译器

–phuclv
2014年12月23日下午2:39

@JörgWMittag-第一个自动化的Oberon编译器是用Oberon编写的。真正的第一个Oberon编译器是一群学生。

– nnnnnn
2014年12月23日在22:33

@nnnnnn:我会认为“一群学生”是解释器而不是编译器。

–PaŭloEbermann
2014年12月25日18:23

@PaŭloEbermann要添加另一个人为元素:“计算机”最初是一个职位。

–chux-恢复莫妮卡
2015年1月3日,下午6:59

#7 楼

以下是一些不是用C语言编写的编程语言,以及它们用以下语言实现的列表:


Haskell-Haskell
Idris-Haskell
Adga -Haskell
冲突-Haskell
PureScript-Haskell
榆木-Haskell
水星-水星
铁锈-锈(最初是OCaml)
Go-前进/>水晶-水晶
OCaml-OCaml
弗雷格-弗雷格+ Java
哈克斯-OCaml + Haxe
斯卡拉-Scala
富他克-哈斯克尔
ATS- ATS

实现编译器的最佳语言可能与C相去甚远。功能性语言为您提供了诸如递归方案和monadic解析器组合器之类的功能(前提是您拥有类型类),这使得它们尤其如此第二,解决您的问题,即C是否是“所有编程语言的母/父”-并非如此。 C语言在当时就已经是一种精心设计的语言,毫无疑问,它影响了语言设计师,他们后来又做了很多不同的事情。但是,归根结底,Haskell基本上以各种可能的方式离开了C。 C已有45岁,同时我们学会了做得更好也就不足为奇了。

最后,要回答您的第三个问题,C实施“所有概念”并不是完全不可能”。特别是,试图用C来实现功能编程中的一些高级概念(例如变质,或者,上帝禁止,同步同构)会非常困难。我对面向对象的编程不是特别熟悉,但是我确实知道某些面向对象的语言具有求和类型。

评论


C从来不是“一种设计得令人难以置信的语言”。我们今天看到的疣从一开始就是众所周知的疣。但是,它足以成为易于开发人员使用的Unix操作系统的本地语言,在Bell Labs将Unix推入大学之后,C / Unix成为了一代计算机专业人员最喜欢的语言/ OS。

–所罗门慢
17年9月22日在21:06

PS。,在C中没有很多原始想法。如果您正在寻找所有块结构,过程式编程语言的母亲/父亲,您可能想看看ALGOL。

–所罗门慢
17-09-22在21:09



Lisp宏比C更好,并且ALGOL和Smalltalk具有块,闭包和嵌套函数来帮助组织代码。实际上,Lisp可以用作汇编程序的宏处理器,并且可以创建比早期C. Simula短而快的代码(对S表达式的自定义处理)。 Lisp,APL和Smalltalk具有完全功能的“ shell”(shell和程序之间的代码相同),这与Unix的“ sh”和“ C”不同,从而允许解释和编译的代码相互交错。 Lisp(rplaca / rplacd)中的指针更容易。

–aoeu256
19年8月9日在12:53

C的最大优点是为C构建“编译器”更加容易,因此它可以更容易地传播……就像病毒一样,而且由于C的存在,现代程序员对如何构建模块化程序毫无头绪(可变性会损害模块性),没有副词/组合器/高阶函数的概念[每次都手动编写循环],并且我们的CPU受“冯·诺依曼”瓶颈的限制,因为我们的操作系统是用C编写的,因此我们需要CPU运行C代码以实现向后兼容性。

–aoeu256
19年8月9日在13:00

#8 楼

编程语言是规范(不是软件!),通常用一些英文文档编写(带有某种形式化,例如EBNF用于大多数语法;有时它们的语义也被部分形式化)。例如,C11是由n1570定义(您应该阅读)。 Scheme的某些方言由R5RS定义(您也应该阅读,它写得很好)。

编程语言可以由某些软件来实现。有时,该软件是用编程语言本身编写的编译器。阅读有关引导式编译器的信息。

可以用已编译的编程语言编写一个编译器。如果该语言XX是全新的,则需要经过一个临时步骤,该步骤涉及使用某种其他实现语言(也许是C)编写该语言的子集的最小解释器或编译器,之后您可以丢弃该临时编译器或解释器(不必足够好即可编译其他编译器)。一旦编译了用XX编写的XX编译器,您就可以丢弃临时编译器。

运行时系统通常(但并非总是)部分用C语言编写(特别是垃圾收集器)。 >
请注意,bones是完全由其自身编写的Scheme编译器和运行时(并且您可以找到许多其他完全自举实现的示例)。编译器语言。

如今,许多编程语言实现都是免费软件或开源软件。随时学习(或为它们的源代码做贡献)!

评论


高朗有一段时间了。用C编写,直到用Go编写为止。

–亨利·马林诺夫斯基
20年8月20日在19:11