有时,当使用不同的语言(C / C ++,C#)进行编程时,我想到了这种想法:
- 每种语言都用C编程语言编写吗?
- C语言是所有语言的母亲/父亲吗?
- 每个概念(OOP等)是否都在C中实现?
我的方向正确吗?
有时,当使用不同的语言(C / C ++,C#)进行编程时,我想到了这种想法:
我的方向正确吗?
Answers:
没有。
OCaml,Haskell,Lisp方言(例如Scheme)和其他几种语言经常被用于开发爱好语言。
许多语言都是用C语言实现的,因为它是一种普遍存在的语言,而诸如lexer-parser生成器(例如yacc和bison)之类的编译器编写工具则易于理解,并且几乎无处不在。
但是C本身在最初创建时最初不能用C开发。实际上,它最初是使用B语言开发的。较早的语言(如Fortran)通常使用本机汇编语言甚至机器代码来引导,远早于C出现。
无关地,像OOP这样的语言范例通常与语言无关。例如,功能范式(由Alonzo Church创立)早在任何编程语言都存在之前就已作为数学基础。过程化和结构化的编程范式来自于像约翰·冯·诺依曼这样的理论家的数学著作。面向对象是由几项不同且无关的工作开发的,其中一些来自lambda演算(功能范式),一些则来自于动态编程系统,例如Alan Kay在Xerox PARC的SmallTalk。
在这些想法产生数十年后,C只是故事的一小部分。
每种语言都用C语言编写吗?
语言是一组抽象的数学规则和限制(“如果我写这个,那就会发生”)。确实没有写任何东西。
它通常是由形式化的英语子集,数学符号以及某些特殊的规范语言混合而成的。该语法通常在EBNF或ABNF的变体中指定。
例如,以下是for
ISO Ruby语言规范中表达式的规范:
§11.5.2.3.4
for
表达式句法
- for表达式 → for 变量 [此处没有行终止符] in 表达式 子句 end
- 变量 → 左手边
|
多个左手边语义学
甲用于表达如下评价:
- 计算表达式。如果对表达式的求值由break-expression,next-expression或redo-expression终止,则行为不确定。否则,将
O
其作为结果值。让
E
是初级方法调用形式的基本表达式 [无线-终止这里] .each do | 块参数列表 | 块体 end,其中所述的值基本表达式是O
,该块参数列表是换变量,该块体是所述化合物语句的的do-子句。评估
E
; 然而,如果一个块,其块体是所述化合物语句的的do-子句的用于表达该评价过程中被调用时,在除了步骤c§11.3.3以下步骤a)和步骤e)4)应用于评估此通话。所述的值对于表达是所得到的调用的值。
这是与Scala的类型一致性规则不同的示例:
多态型[A 1 >:L 1 <:U 1,...,A Ñ >:L Ñ <:U Ñ ] T,符合多态型[A1>:L' 1 <:U' 1,...,一个ñ >:L' ñ <:U' ñ ] T'如果,假定L' 1 <:一个1 <:U' 1,...,L' ñ <:一个ñ <:U'n之一具有Ť<:T '和大号我 <:L' 我和U' 我<:U i for i∈{1,…,n}。
C语言是所有语言的母亲/父亲吗?
不它不是。C还很年轻。有很多古老的语言。由于时间旅行实际上是不可能的,因此C根本不可能对那些旧语言产生任何影响。
所有这些在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语言实现吗?
具有OO概念的第一语言是Simula(1960)和Smalltalk(1972),但是面向对象的系统早在1953年就已构建(没有将其称为)。再一次,这比C早就存在了,所以OO不可能与C有任何关系。
许多重要语言的大多数核心都是用C编写的,但是情况正在发生变化:
Sun Microsystems开发的第一个Java编译器最早是用C编写的,但是现在类库始终是用Java编写的(因为它们打算使用Java VM本身运行)。某些使用JNI(Java本机接口)的库可能会用多种其他语言部分编写,因为它们打算在JVM之外使用。
Sun / Oracle VM用C ++编写。BEA / Weblogic / Oracle VM用C编写。但是有JVM用Java,Lisp,SmallTalk(IBM)编写...
经常选择C的原因有很多:性能,可移植性,经验。
最后一个可能是最重要的:Python于1991年启动,PHP于1994/1995年启动,Perl于1988年启动,Ruby于1995年启动。在那些年中,Java刚刚发布,而C ++尚未很好地标准化。
有点相关:
不,某些语言早于C。许多语言独立于C实现,例如,请参见http://en.wikipedia.org/wiki/Lisp_%28programming_language%29
javac
来自于Martin Odersky(由Scala出名)以100%Java编写的Oracle JDK / OpenJDK,以100%Java编写的Eclipse编译器(源自IBM的Jikes编译器),来自IBM的J9,也源自Jikes和100%Java。AFAIK是GCJ
如果可以的话,我会发表评论,但我不能这样说:
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,如何用C编写第一个C编译器?这不是鸡和蛋的问题。
有很多方法可以编写一种语言的第一个编译器,称为引导程序
而且,大多数编译器都试图实现自我托管,或者以其语言对其自身进行编译,主要是为了促进语言和编译器本身的发展。
这是一些不是用C编写的编程语言的列表,以及它们以哪种语言实现的列表:
实现编译器的最佳语言可能与C相去甚远。功能语言为您提供了诸如递归方案和monadic解析器组合器之类的功能(前提是您拥有类型类),这使它们特别适合于编译器工作。
其次,要解决您的问题,即C是否是“所有编程语言的母子”?C在出现时是一种设计良好的语言,毫无疑问,它影响了语言设计者,他们后来继续做非常不同的事情。但是,归根结底,Haskell基本上以各种可能的方式离开了C。C已有45岁,并且在此期间我们学会了做得更好,这并不奇怪。
最后,要回答您的第三个问题,根本不是C实现“所有概念”。特别是,尝试用C来实现功能编程中的一些高级概念(例如变质,或者,上帝禁止,同步同构)会非常困难。我对面向对象的编程不是特别熟悉,但是我确实知道某些面向对象的语言具有求和类型。
编程语言是规范(不是软件!),通常用一些英文文档编写(带有某种形式化,例如,大多数语法的EBNF;有时它们的语义也被部分形式化)。
例如,C11由n1570定义(您应该阅读)。Scheme的某些方言由R5RS定义(您也应该阅读,它写得很好)。
编程语言可以通过某些软件来实现。有时,该软件是用编程语言本身编写的编译器。阅读有关引导编译器的信息。
可以使用已编译的编程语言本身编写编译器。如果该语言XX是全新的,则需要经过一个临时步骤,该步骤涉及使用某种其他实现语言(也许是C)编写该语言的子集的最小解释器或编译器,之后您可以丢弃该临时编译器或解释器(不必足够好即可编译其他编译器)。一旦编译了用XX编写的XX编译器,就可以丢弃临时编译器。
通常(但并非总是),运行时系统部分用C(特别是垃圾收集器)编写。
请注意,骨头是一个完全由其自身编写的Scheme编译器和运行时(您可以找到完全自举实现的许多其他示例)。