程式设计语言
编程语言是编写计算机程序的符号系统。
通常用其语法(形式)和语义(含义)来描述编程语言。这些通常由形式语言定义。
语言通常以编译器或解释器的形式至少具有一个实现,允许执行使用语言编写的程序。
编程语言理论是计算机科学的子领域,它研究了编程语言的设计,实施,分析,表征和分类。
定义
定义什么构成编程语言时,有很多考虑因素。
计算机语言与编程语言
一词计算机语言有时与编程语言互换使用。但是,两个术语的用法在作者之间有所不同,包括每个术语的确切范围。一种用法将编程语言描述为计算机语言的子集。同样,与表达计算机程序不同的计算中使用的语言是一般指定的计算机语言。例如,有时将标记语言称为计算机语言,以强调它们并不是要用于编程。按照计算理论所描述的,对计算机语言进行分类的一种方法是通过它们表达的计算。大多数实用的编程语言都已经完成,并且所有图灵完整的语言都可以实现相同的算法。 ANSI/ISO SQL-92和慈善机构是不完整的语言的示例,但通常称为编程语言。但是,一些作者将“编程语言”一词限制为图灵完整语言。
另一种用法将编程语言视为编程抽像机和计算机语言的理论构造,这是在具有有限硬件资源的物理计算机上运行的子集。 John C. Reynolds强调,形式规范语言与旨在执行的语言一样多。他还认为,影响计算机行为的文本甚至图形输入格式是编程语言,尽管事实上通常不是整理完整的,并且指出对编程语言概念的无知是以输入形式出现许多缺陷的原因。
域和目标
在大多数实际情况下,编程语言涉及计算机;因此,通常以这种方式定义和研究编程语言。编程语言与自然语言不同,因为自然语言仅用于人之间的互动,而编程语言也允许人类将说明传达给机器。
该语言的领域也值得考虑。定义结构化数据的XML , HTML或Troff之类的标记语言通常不被视为编程语言。但是,如果定义了计算语义,则可以与标记语言共享语法。例如, XSLT是一种完全使用XML语法的图灵完整语言。此外,主要用于构造文档的乳胶还包含图灵完整的子集。
抽象
编程语言通常包含用于定义和操纵数据结构或控制执行流的抽象。编程语言支持足够抽象的实际必要性由抽象原则表达。有时将该原则作为向程序员提出的建议,以正确地使用此类抽象。
历史
早期发展
通过修改其电路或设置物理控制的库,在没有存储程序的帮助下编程了很早的计算机,例如巨像。
稍后,程序可以用机器语言编写,程序员以数字形式编写了硬件可以直接执行的数字形式。例如,在两个内存位置添加值的指令可能包含3个数字:选择“ add”操作的“ OpCode”和两个内存位置。该程序以十进制或二进制形式的形式从打孔卡,纸带,磁带或计算机前面板上的开关中读取。机器语言后来被称为第一代编程语言(1GL)。
下一步是开发所谓的第二代编程语言(2GL)或汇编语言,这些语言仍然与特定计算机的指令集体系结构紧密相关。这些使该程序变得更加人性化,并放松了乏味且容易出错的地址计算的程序员。
1950年代编写了第一种高级编程语言或第三代编程语言(3GL)。 Plankalkül是一种为计算机设计的早期高级编程语言,该语言是1943年至1945年之间由Konrad Zuse开发的。但是,直到1998年和2000年才实施。
John Mauchly的简短代码于1949年提议,是为电子计算机开发的首批高级语言之一。与机器代码不同,简短的代码语句以可理解的形式表示数学表达式。但是,每次运行时必须将程序转换为机器代码,这使得该过程比运行等效的机器代码要慢得多。
阿里克·格伦尼(Alick Glennie)在曼彻斯特大学(University of Manchester)在1950年代初期开发了自动码。作为编程语言,它使用编译器自动将语言转换为机器代码。第一批代码和编译器于1952年开发了曼彻斯特大学的Mark 1计算机,被认为是第一个编译的高级编程语言。
RA Brooker于1954年为Mark 1开发了第二个自动代码,称为“ Mark 1 Autocode”。布鲁克还在1950年代与曼彻斯特大学一起为Ferranti Mercury开发了一项汽车代码。 EDSAC 2的版本是由剑桥大学数学实验室的DF Hartley于1961年设计的。它被称为Edsac 2 Autocode,这是Mercury Autocode的直接开发,适用于当地情况,并以其对象代码优化和源源语言而闻名当时先进的诊断。 Atlas Autocode是曼彻斯特大学Atlas 1机器开发的当代但独立的开发线索。
1954年,约翰·贝克斯(John Backus)在IBM发明了Fortran 。这是第一个使用功能性实现的高级通用编程语言,而不是纸上的设计。它仍然是高性能计算的一种流行语言,用于基准和对世界上最快的超级计算机进行基准测试和排名的程序。
格雷斯·霍珀(Grace Hopper)在美国设计了另一种早期的编程语言,称为流程。它是为1955年至1959年的雷明顿兰德(Remington Rand)的Univac I开发的。霍珀(Hopper原型。该流程编译器于1958年初公开发售,并在1959年实质上完成。流动性是COBOL设计的主要影响,因为只有IT及其直接后代Aimaco当时实际使用。
精致
高级语言的使用增加引入了低级编程语言或系统编程语言的要求。这些语言在不同程度上提供了汇编语言和高级语言之间的设施。它们可用于执行需要直接访问硬件设施但仍提供更高级别的控制结构和错误检查的任务。
从1960年代到1970年代后期的时期,正在使用主要语言范式的发展:
- APL介绍了阵列编程并影响了功能编程。
- 阿尔戈尔(Algol)完善了结构化的程序编程和语言规范的纪律; “关于算法语言Algol 60的修订报告”成为了以后语言规范的撰写模型。
- LISP于1958年实施,是第一个动态类型的功能编程语言。
- 在1960年代, Simula是旨在支持面向对象的编程的第一语言。在1970年代中期, SmallTalk随后使用了第一种“纯粹”面向对象的语言。
- C是在1969年至1973年之间开发的,是UNIX操作系统的系统编程语言,并且仍然受欢迎。
- Prolog于1972年设计,是第一种逻辑编程语言。
- 1978年, ML在LISP之上建立了多态性系统,开创了静态型功能编程语言。
这些语言中的每一种都产生了后代,大多数现代的编程语言在其血统中至少算出其中一种。
1960年代和1970年代还看到了有关结构化编程的优点以及是否应设计编程语言来支持它的辩论。埃德斯格·迪克斯特拉(Edsger Dijkstra)在ACM通讯中发表的1968年著名信中指出,应从所有“高级”编程语言中消除goto陈述。
合并和增长
1980年代是相对巩固的岁月。 C ++组合面向对象和系统编程。美国政府标准化ADA ,这是一种源自Pascal的系统编程语言,旨在由国防承包商使用。在日本和其他地方,花费了巨额资金来调查结合逻辑编程结构的所谓“第五代”语言。功能语言社区转移到标准化ML和LISP。所有这些运动都没有发明新的范式,而是根据过去几十年来发明的思想阐述的。
在1980年代,用于编程大规模系统的语言设计的一个重要趋势是,越来越重视使用模块或大规模组织单位的代码单位。 Modula-2 ,ADA和ML在1980年代都开发了著名的模块系统,这些模块系统通常与通用编程结构相关。
1990年代中期互联网的快速增长为新语言创造了机会。佩尔(Perl )最初是1987年首次发布的Unix脚本工具,在动态网站上很普遍。 Java开始用于服务器端编程,并且字节码虚拟机在商业环境中再次受到欢迎,他们的承诺是“一次写作,在任何地方运行”( UCSD Pascal在1980年代初期一直很受欢迎)。这些发展并非从根本上新颖。相反,它们是许多现有语言和范式的改进(尽管它们的语法通常基于编程语言的C家族)。
在行业和研究中,编程语言的演变仍在继续。当前方向包括安全性和可靠性验证,新型模块化(混合物,代表,方面)和数据库集成,例如Microsoft的Linq 。
第四代编程语言(4GL)是计算机编程语言,旨在与3GL相比,提供更高的内部计算机硬件详细信息抽象。第五代编程语言(5GL)是基于对程序的约束解决问题的编程语言,而不是使用程序员编写的算法。
元素
所有编程语言都有一些原始的构建块,用于描述数据以及应用于它们的过程或转换(例如添加两个数字或从集合中选择项目)。这些原语是由句法和语义规则定义的,分别描述了它们的结构和含义。
句法
编程语言的表面形式称为其语法。大多数编程语言纯粹是文字的;他们使用文本序列,包括单词,数字和标点符号,就像书面自然语言一样。另一方面,某些编程语言本质上是图形的,使用符号之间的视觉关系来指定程序。
语言的语法描述了形成句法正确程序的符号的可能组合。符号组合的含义由语义(参考实现中的形式或硬编码)来处理。由于大多数语言都是文本的,因此本文讨论了文本语法。
通常使用正则表达式(用于词汇结构)和Backus -Naur形式(用于语法结构)的组合来定义编程语言语法。以下是基于LISP的简单语法:
expression ::= atom | list
atom ::= number | symbol
number ::= [+-]?['0'-'9']+
symbol ::= ['A'-'Z''a'-'z'].*
list ::= '(' expression* ')'
该语法指定以下内容:
- 表达是原子或列表;
- 原子是数字或符号;
- 一个数字是一个或多个十进制数字的不间断序列,在此之前,有一个或负号。
- 一个符号是字母,后跟任何字符的零或更多字符(不包括空格);和
- 列表是匹配的一对括号,其中包含零或更多的表达式。
以下是该语法中形成良好的令牌序列的示例:12345
,()
和(a b c232 (1))
.
并非所有句法正确的程序在语义上都是正确的。根据该语言的规则,许多句法正确的程序仍然是错误的;并可能(取决于语言规范和实现的声音)会导致翻译或执行的错误。在某些情况下,此类程序可能表现出不确定的行为。即使一个程序在某种语言中定义明确,它仍然具有编写该语言的人的意义。
以自然语言为例,可能无法为语法正确的句子分配含义,或者该句子可能是错误的:
- “无色绿色的想法疯狂地睡觉。”语法上有很好的形式,但没有普遍接受的含义。
- “约翰是已婚单身汉。”具有语法良好的形式,但表达了不可能真实的含义。
以下C语言片段在语法上是正确的,但执行未定义的操作(操作)*p >> 4
对于具有复杂类型和的值没有意义p->im
没有定义,因为p
是空指针):
complex *p = NULL;
complex abs_p = sqrt(*p >> 4 + p->im);
如果省略了第一行上的类型声明,则该程序将触发未定义变量的错误p
在汇编期间。但是,由于类型声明仅提供语义信息,因此该程序在句法上仍然是正确的。
指定编程语言所需的语法可以通过其在乔姆斯基层次结构中的位置进行分类。大多数编程语言的语法可以使用2型语法(即,它们是无上下文的语法)指定的。包括Perl和LISP在内的某些语言包含允许在解析阶段执行的构造。具有允许程序员改变解析器行为的构造的语言使语法分析成为不可决定的问题,并且通常模糊解析和执行之间的区别。与LISP的宏观系统和Perl相比BEGIN
可能包含一般计算的块,c宏仅仅是字符串替换,不需要代码执行。
语义
静态语义
静态语义定义了对有效文本结构的限制,这些文本在标准的句法形式主义中很难或不可能表达。对于编译的语言,静态语义本质上包括可以在编译时检查的那些语义规则。示例包括检查每个标识符是否在使用之前就声明了它(用需要声明的语言)或案例语句臂上的标签是不同的。这种类型的许多重要限制,例如检查标识符是否在适当的上下文中使用(例如不将整数添加到函数名称),或者可以通过将其定义为规则来强制执行适当的数字和类型参数在称为类型系统的逻辑中。其他形式的静态分析(例如数据流分析)也可能是静态语义的一部分。 Java和C#等编程语言具有确定的分配分析,这是一种数据流分析的一种形式,作为它们各自的静态语义的一部分。
动态语义
指定数据后,必须指示机器对数据执行操作。例如,语义可以定义将表达式评估为值的策略,或者控制结构有条件执行语句的方式。语言的动态语义(也称为执行语义)定义了语言的各种构造应产生程序行为。有许多定义执行语义的方法。自然语言通常用于指定实践中常用的语言的执行语义。大量的学术研究涉及编程语言的正式语义,从而使执行语义可以正式指定。该研究领域的结果显示,在学术界以外的编程语言设计和实施中的应用有限。
类型系统
类型系统定义了编程语言如何将价值和表达式分为类型,如何操纵这些类型以及它们如何交互。类型系统的目的是通过检测某些不正确的操作来验证并通常在用该语言编写的程序中执行一定的正确性。任何可定义的类型系统都涉及权衡取舍:虽然它拒绝许多不正确的程序,但它也可以禁止一些正确的,尽管是不寻常的程序。为了绕过这一缺点,许多语言具有类型的漏洞,通常不受组织的铸造,这些语言可能被程序员使用,以明确允许在不同类型之间进行正常不允许的操作。在大多数类型的语言中,类型系统仅用于键入检查程序,但是许多语言,通常是功能性的语言,推断类型,使程序员摆脱编写类型注释的需求。类型系统的形式设计和研究称为类型理论。
类型与未型语言
如果每个操作的规范定义了适用该操作的数据类型,则将输入语言。例如,由代表的数据"this text between the quotes"
是字符串,在许多编程语言中,将数字除以字符串没有含义,也不会执行。在编译程序(“静态”类型检查)时,可以检测到无效的操作,并通过编译错误消息拒绝编译器,或者可以在程序运行时检测到它(“动态”类型检查),结果在运行时例外。许多语言允许称为异常处理程序的函数来处理此异常,例如,结果始终返回“ -1”。
打字语言的一种特殊情况是单型语言。这些通常是脚本或标记语言,例如REXX或SGML ,并且只有一种数据类型(通常是字符字符串),这些字符串均用于符号和数字数据。
相比之下,一种未经类似的语言(例如大多数汇编语言)允许对任何数据进行任何操作,通常是各个长度的位序列。高水平的非型语言包括BCPL , TCL和FORT的某些品种。
实际上,尽管很少有语言从类型理论(验证或拒绝所有操作)中键入,但大多数现代语言都提供了一定程度的打字。许多生产语言提供了绕过或颠覆类型系统的手段,交易类型的安全性,以对程序的执行进行更好的控制(请参阅铸造)。
静态相对于动态打字
在静态键入中,所有表达式的类型都在程序执行之前(通常在编译时)确定。例如,1和(2+2)是整数表达式;它们不能传递给期望字符串或存储在定义以持有日期的变量中的函数。
静态类型的语言可以显然是键入的或类型的。在第一种情况下,程序员必须在某些文本位置上明确编写类型(例如,在变量声明上)。在第二种情况下,编译器基于上下文渗透了表达式和声明的类型。显然,大多数主流静态型语言,例如C ++ , C#和Java 。传统上,完整的推理与Haskell和ML等功能语言有关。但是,许多明显的语言都支持部分类型的推断。例如,在某些有限的情况下, C ++ , Java和C#所有推断类型。此外,某些编程语言允许将某些类型自动转换为其他类型。例如,可以在程序期望浮子的情况下使用int。
动态键入(也称为潜在键入)确定运行时操作的类型安全。换句话说,类型与运行时值而不是文本表达式关联。与类型扣除的语言一样,动态类型的语言不需要程序员在表达式上编写明确的类型注释。除其他外,这可能允许单个变量参考程序执行中不同点的不同类型的值。但是,在实际执行一块代码之前,无法自动检测到类型错误,这可能会使调试变得更加困难。 LISP , SmallTalk , Perl , Python , JavaScript和Ruby都是动态型语言的示例。
弱打字
弱键入允许一种类型的值将其视为另一种类型,例如将字符串视为数字。这有时可能很有用,但是它还可以使某些程序故障在编译时甚至在运行时都没有发现。
强大的打字可防止这些程序故障。尝试对错误类型的值进行操作会导致错误。强大的语言通常被称为类型保护或安全。
“弱输入”的替代定义是指诸如Perl和JavaScript之类的语言,该语言允许大量隐式类型的转换。例如,在JavaScript中,表达式2 * x
隐式转换x
一个数字,即使x
是null
,undefined
, 一个Array
,或一串字母。这种隐式转换通常很有用,但是它们可以掩盖编程错误。现在通常认为强大而静态的正交概念,但文献中的用法有所不同。有些人使用强烈键入的术语表示强烈的含义,静态键入,甚至更令人困惑的是,只是静态键入。因此, C被称为强键入和弱型,静态键入。
对于一些专业程序员来说,C可能“弱,静态键入”似乎很奇怪。但是,使用通用指针,即void*指针,确实允许将指针铸成其他指针,而无需进行明确的铸造。这与以某种方式在C中以某种类型的数据类型施放一系列字节非常相似(int)
或者(char)
.
标准库和运行时间系统
大多数编程语言都有关联的核心库(有时称为“标准库”,尤其是在作为已发表语言标准的一部分中包含的情况下),该语言的所有实现通常都可以使用。核心库通常包括常用算法,数据结构以及输入和输出机制的定义。
语言及其核心库之间的界线因语言而异。在某些情况下,语言设计师可以将库视为与语言的单独实体。但是,语言的核心库通常被其用户视为语言的一部分,并且某些语言规格甚至要求在所有实现中提供此库。确实,某些语言的设计是使某些句法构造的含义甚至无法描述核心库。例如,在Java中,字符串文字定义为java.lang.String
班级;同样,在SmallTalk中,匿名函数表达式(一个“块”)构造了库的实例BlockContext
班级。相反,方案包含多个相干子集,足以构建语言的其余部分作为库宏,因此语言设计师甚至不愿意说必须将语言的哪些部分实现为语言构造,并且必须将哪些语言实现为零件图书馆。
设计和实施
编程语言与自然语言共享属性,其目的是作为通信的工具,其句法形式与语义分开,并显示相关语言的语言家族与一种分支。但是,作为人工结构,它们在基本方式上也与通过用法发展的语言有所不同。一个重要的区别在于,编程语言可以全面描述和研究,因为它具有精确且有限的定义。相比之下,自然语言的用户在不同社区中给出的含义发生了变化。虽然构造的语言也是以特定目的从头开始设计的人造语言,但它们缺乏编程语言具有的精确和完整的语义定义。
许多编程语言都是从头开始设计的,已更改以满足新需求,并与其他语言结合使用。许多人最终被废弃了。尽管已经尝试设计一种用于所有目的的“通用”编程语言,但所有这些语言都没有被普遍接受为填补这一角色。对各种编程语言的需求来自使用语言的多样性:
- 程序范围从个人爱好者编写的小脚本到数百个程序员编写的庞大系统。
- 程序员的专业知识范围从需要简单性的新手到可能对相当复杂的专家感到满意。
- 程序必须平衡从微控制器到超级计算机的系统的速度,尺寸和简单性。
- 程序可以写一次,而不会因世代而变化,否则它们可能会经历不断的修改。
- 程序员的口味可能会有所不同:他们可能习惯于讨论问题并用特定语言表达问题。
编程语言开发的一种普遍趋势是增加更高的抽象水平来解决问题的能力。最早的编程语言与计算机的基础硬件非常紧密。随着新的编程语言的发展,已经添加了功能,即让程序员表达的想法与简单翻译更遥远的想法为基础硬件说明。由于程序员与计算机的复杂性息息相关,因此他们的程序可以通过程序员的精力更少地进行计算。这使他们能够编写每个时间单元的更多功能。
已经提出了自然语言编程,以消除对编程专业语言的需求。但是,这个目标仍然遥不可及,其利益开放了辩论。 Edsger W. Dijkstra的立场是,使用形式语言对于防止毫无意义的构造至关重要,并将自然语言编程视为“愚蠢”。艾伦·佩里斯(Alan Perlis)同样不屑一顾。混合方法已采用结构化的英语和SQL采用。
语言的设计师和用户必须构建许多管理和实现编程实践的工件。这些工件中最重要的是语言规范和实施。
规格
编程语言的规范是语言用户和实施者可以用来同意源代码是否是该语言的有效程序,如果是这样的行为。
编程语言规范可以采用几种表格,包括以下内容:
- 语言的语法,静态语义和执行语义的明确定义。虽然通常使用正式语法指定语法,但语义定义可以用自然语言(例如,在C语言中)或正式语义(例如,如标准ML和方案规范)编写。
- 对语言翻译器的行为的描述(例如, C ++和Fortran规范)。该语言的语法和语义必须从这种描述中推断出来,该描述可以用自然语言或正式语言编写。
- 参考或模型实现,有时用要指定的语言(例如, Prolog或ANSI REXX )编写。语言的语法和语义在参考实现的行为中是明确的。
执行
编程语言的实现提供了一种用该语言编写程序并在硬件和软件的配置上执行程序的方法。从广义上讲,有两种编程语言实施方法:编译和解释。通常可以使用任何一种技术实现一种语言。
编译器的输出可以通过硬件或称为解释器的程序执行。在使用解释器方法的某些实现中,编译和口译之间没有明显的边界。例如,基本编译的某些实现,然后一次执行源一行。
直接在硬件上执行的程序通常比在软件中解释的程序更快。
提高解释程序性能的一种技术是及时的汇编。在此处,在执行之前,虚拟机将翻译要用于机器代码的字节码的块,用于在硬件上直接执行。
专有语言
尽管大多数最常用的编程语言都具有完全开放的规格和实现,但许多编程语言仅作为专有编程语言存在,并且仅可从单个供应商获得的实现,这可能声称这种专有语言是其智慧财产.专有的编程语言是通常的特定于领域的语言或单一产品的内部脚本语言;一些专有语言仅在供应商内部使用,而另一些则可用于外部用户。
专有和开放之间的边界上存在一些编程语言;例如, Oracle Corporation主张Java编程语言某些方面的专有权利,而Microsoft的S C#编程语言(已开放系统的大多数部分)也将通用语言运行时(CLR)作为封闭环境。
尽管其专有性质,但许多专有语言仍被广泛使用。示例包括MATLAB , VBSCRIPT和WOLFRAM语言。某些语言可能会使从闭合到开放的过渡;例如, Erlang最初是爱立信的内部编程语言。
使用
已经创建了数千种不同的编程语言,主要是在计算字段中。单个软件项目通常使用五种编程语言或更多。
编程语言与大多数其他形式的人类表达不同,因为它们需要更高的精度和完整性。当使用自然语言与他人交流时,人类作家和说话者可能是模棱两可的,犯了很小的错误,并且仍然期望他们的意图可以理解。但是,从象征性地说,计算机“正是做他们被告知要做的事情”,并且无法“理解”程序员打算编写的代码。语言定义,程序和程序的输入的组合必须完全指定该程序控制域内执行程序时发生的外部行为。另一方面,关于算法的想法可以通过使用伪代码与执行所需的精确性传达给人类,该伪代码将自然语言与以编程语言编写的代码交织在一起。
编程语言提供了一种结构化机制,用于定义数据段,以及可以在该数据上自动执行的操作或转换。程序员使用语言中存在的抽象来表示计算中涉及的概念。这些概念表示为可用的最简单元素的集合(称为原始元素)。编程是程序员结合这些原始程序以构成新程序的过程,或使现有程序适应新用途或不断变化的环境。
计算机的程序可以在没有人交互的情况下在批处理过程中执行,或者用户可能在解释器的交互式会话中键入命令。在这种情况下,“命令”只是程序,其执行被束缚在一起。当一种语言可以通过解释器(例如Unix Shell或其他命令行接口)运行其命令,而无需编译时,它被称为脚本语言。
测量语言使用
确定哪种最广泛使用的编程语言很困难,因为用法的定义会因上下文而变化。一种语言可能会占用更多的程序员小时,另一种语言具有更多的代码行,而三分之一的语言可能会消耗最多的CPU时间。某些语言在特定类型的应用程序中非常受欢迎。例如, COBOL在公司数据中心(通常在大型大型机)中仍然很强。科学和工程应用中的福特; ADA在航空航天,运输,军事,实时和嵌入式应用中;和嵌入式应用程序和操作系统中的C。其他语言定期用于编写许多不同类型的应用程序。
已经提出了各种衡量语言流行的方法,每个方法都有不同的偏见,而不是被提出的偏见:
- 计算提及该语言的招聘广告的数量
- 售出或描述语言的书籍数量
- 估计用语言编写的代码行的数量的估计 - 可能低估了公众搜索中经常发现的语言
- 使用Web搜索引擎找到的语言参考计数(即,对语言的名称)。
stackify.com报告了来自各个互联网站点的信息,并报告了十种最受欢迎的编程语言(按整体受欢迎程度下降): Java , C , C ++ , Python , C# , JavaScript ,JavaScript , VB .NET , R ,R, PHP和MATLAB和MATLAB 。
方言,口味和实现
编程语言或数据交换语言的方言是(相对较小的)语言的(相对较小)的语言,不会改变其内在性质。借助方案和第四语言,实施者可能认为标准不足,不足或违法,因此他们经常会偏离标准,从而做出新的方言。在其他情况下,创建了一种方言,用于在特定于域的语言中,通常是子集。在LISP世界中,大多数使用基本S-表达语法和类似LISP的语义的语言被认为是LISP方言,尽管它们像球拍和clojure一样差异很大。由于一种语言具有多种方言是很常见的,因此没有经验的程序员很难找到正确的文档。基本语言有许多方言。
分类法
编程语言没有总体分类方案。给定的编程语言通常没有单一的祖先语言。语言通常是通过将几种前身语言与当时流通中的新想法相结合而产生的。起源于一种语言的想法将在一个相关语言家族中扩散,然后突然跨越家族差距,以完全不同的家庭出现。
可以沿多个轴对语言进行分类的事实更加复杂。例如,Java既是面向对象的语言(因为它鼓励面向对象的组织)和并发语言(因为它包含用于并行运行多个线程的内置构造)。 Python是一种面向对象的脚本语言。
在广泛的笔触中,编程语言通过编程范式和预期的使用域进行了分类,通用编程语言与特定领域的编程语言区别开来。传统上,编程语言被认为是用命令句子(即发行命令)描述计算的。这些通常称为命令性编程语言。关于编程语言的大量研究旨在模糊程序之间的区别,作为一组说明,作为对所需答案的主张,这是声明性编程的主要特征。更精致的范式包括程序编程,面向对象的编程,功能编程和逻辑编程;某些语言是范式或多范式的混合体。汇编语言不是一个范式,而是基础机器架构的直接模型。通过目的,编程语言可能被视为通用语言,系统编程语言,脚本语言,特定于领域的语言或并发/分布式语言(或这些语言的组合)。一些通用语言的设计很大程度上是具有教育目标的。
编程语言也可以通过与编程范式无关的因素进行分类。例如,大多数编程语言都使用英语关键字,而少数语言则不使用。其他语言可能被归类为故意深奥的。