什么时候可以创建自己的编程语言?


48

从长远来看,是否有更好的杀手级应用程序,算法问题类别等等,可以创造出自己的语言?

PS:可以肯定的是,我的意思是一种新的编程语言和一个编译器,而不是现有语言的新编译器。

编辑:谢谢你的答案。您能提供一些示例,这些示例绝对不需要创建DSL,或者说DSL可能是个好主意?


8
我相信应该为每个问题创建一个DSL 。
SK-logic

4
这不是LISP的优点吗?
2011年

1
@Darknight,不一定是Lisp-任何具有良好元编程能力的语言都可以。
SK-logic

2
如果您想了解编译器内部知识。
dan_waterworth 2011年

1
当您认为这会很有趣或具有教育意义。考虑到所涉及的工作量,设计需要自己的编译器的新语言永远不会达到任何有用的目的。(当然,有些人足够聪明,受过教育,并且经验丰富,知道什么时候应该忽略我的建议。)
David Thornley

Answers:


40

一个人出于教育目的写自己的语言当然很重要。了解编程语言设计和编译器设计。但是实际用途很少。

使用自己的语言,您是:

  • 给您的问题增加了极大的复杂性
  • 在编写和维护新语言和编译器方面增加了大量工作

因此,如果您打算为您的项目编写自己的语言,则它提供的其他语言所不需要的功能无需抵消上述费用。

以游戏开发为例。他们经常需要在游戏或脚本语言中使用迷你语言。他们使用这些语言来编写大量发生的游戏内事件的脚本。但是,即使在这种情况下,他们几乎总是选择现有的脚本语言,并根据需要对其进行调整。


13
我确实要提到,在“实用程序员”中,编写较小的,特定于领域的语言来帮助完成任务是非常有用的,并且受到鼓励。我不建议编写成熟的通用语言,但是有时会生成代码的元语言会有所帮助。
乔丹·帕默

4
这是一个谎言。编写语言不会增加复杂性-通常,它将大大降低复杂性。无论如何,实现和维护编译器都是一件很小的工作。
SK-logic

3
@ SK-logic,“无论如何,实现并维护编译器都是一件很小的工作”。你有没有尝试过?对于什么处理器?

1
@ThorbjørnRavn Andersen,我正在做这件事。如今,您不必直接针对任何给定的CPU-因为存在可用的出色VM,例如LLVM,.NET甚至JVM。而且,如果您不打算进行太多昂贵的优化,那么即使针对“真正的” CPU也没什么大不了的-有关这种原始方法的示例,请参见OCaml编译器。
SK-logic

7
@ThorbjørnRavn Andersen,顾名思义,编译器正在将一种语言翻译成另一种语言。目标语言的级别无关紧要。而且没有人理智地为DSL实现完全优化的编译器后端-最好重用现有的DSL。实际上,大多数现代DSL都被编译为C。至于汇编器和链接器-从系统编程的早期开始,就一直将它们与编译分开。
SK-logic

24

让我引用一下VB编译器的前首席开发人员Paul Vick的话,他现在正在研究Oslo项目和M语言:

构建一种新的语言非常困难,极其困难,即使是很大程度上基于现有语言的语言也是如此。但是许多程序员认为,“嘿,使用语言,这有多难?”然后继续研究。…可能超过98%的人根本无法获得任何吸引力,但是上帝保佑乐观主义者,因为没有他们,我们将永远无法获得2%的成功语言。我个人愿意为从未使用过的语言付出数百万美元的时间和金钱,以便我们获得C#和Java,Ruby和Python等语言。

因此,提出一种新语言是一个坏主意,这一事实不应阻止人们开发新的DSL,而应该让他们停顿一下,并希望有点谦虚。我认为,关键是从小处着手,保持小处。

DSL:绝对是个坏主意!


8
VB!= VBA。顺便说一句,在此网站上批评VBA甚至合法吗?毕竟,乔尔(Joel)帮助开发了它,对吗?
康拉德·鲁道夫

1
尽管务实的程序员是一本好书,但是在这本书中对DSL的推荐却是愚蠢的。就像他们建议每年学习一种新语言一样,恕我直言,这也是非常愚蠢的。
博士 邪恶的

2
我刚刚编辑了您的答案以再次指向Paul Vick的文章,而不是Google缓存。在2011年,他“重置了博客”并删除了所有VB内容,但在2012年,他使用不同的URL将其放回原处。听起来他删除这些东西时个人比较困难
MarkJ 2013年

2
@MarkJ非常感谢。而且,哇,该文章不能令人愉快地阅读。希望他现在做得更好。
康拉德·鲁道夫

2
感谢您的友好评论,实际上我现在正在使用JavaScript,是的,情况要好得多。:-)不知道为什么原始链接不起作用,我试图使所有旧的链接样式都起作用,我将对其进行研究。
panopticoncentral

22

什么时候合理?

当你喜欢的时候!

不要听这些人的昧评论,他们基本上说:

“不要这样做,因为它太难了,X语言比您能想到的任何一种语言都要好。”

事实是,创建DSL一直都在发生。框架是DSL。宏是DSL。每次为程序编写函数时,它就是DSL的一部分。当然,它在语法的范围之内,但是词汇是语言的一部分。这就是为什么行业经常创建自己的本地语言的原因:效率更高!

如果“不做”是正确的答案,那么我们所有人都将编写COBOL和Fortran。


3
真?我认为框架,宏和函数都是可以帮助语言保持域独立性的东西。
CurtainDog

3
@CurtainDog,仅当它成为标准库的一部分时,它才成为语言的一部分。否则,它是该语言的“方言”。

9

如果您正在考虑编写自己的语言,则可能需要阅读Martin Fowler即将出版的DSL书的部分内容。

除了真正的学习经验之外,我真的无法想到从头开始创建一种语言的业务案例。

编辑:对于DSL,有很多商业案例,但是这里的关键不是要迷失方向并保持简单。


7

我建议关键问题是:“我要解决什么问题?” 和“谁获得投资回报率?”

如果您想建立自己的技能和经验,那就要全速前进,但是不要在应该用来解决其他人问题的生产系统中。


7

似乎想要使用新语言的主要原因是,您开始发现代码中现有语言无法很好处理的模式。但是创建自己的语言存在很多问题。您会错过所有为现有语言构建的库和框架。您将花费大量时间来设计和实现新语言,而不必花费所有时间在真正的编程任务上。您将花费很多精力说服其他开发人员使用他们的语言。而且,您将很难招募和培训新开发人员。

为什么不使用Lisp之类的语言来编写语言呢?然后,您将获得一种新语言的所有功能以及既定语言的所有好处。



6

我认为您不能在创建新语言的情况下进行编程,因此很高兴意识到这就是您正在做的事情并理解这些问题。

  • 什么是语言?
    词汇,语法和语义。

VB,Java,C#等现成的语言只是一种基本语言。向其中添加类,方法等后,就已经添加了词汇和语义。有多种实现语言的方法-解析和翻译,解析和解释,在现有语言之上的宏,向现有语言添加类和方法。

  • 您想要一种语言做什么?
    善于简洁表达问题。

您如何知道是否已完成此操作?我使用的度量是编辑计数。如果单句要求A出现,我将继续在代码中实现该要求。完成并清除所有错误后,我检入代码,代码存储库向我提供了我所做的更改列表B。B 越小,语言越好。在实际和可能需求的空间中取平均值,该度量告诉我该语言的“特定于领域”。

  • 为什么简洁性好?
    因为它可以最大程度地减少错误。

如果要执行1个要求需要N个代码更改,并且您有时会犯错误,那么引入的bug的数量大致与N成正比。在N = 1的限制内,几乎不可能不引入就引入bug

请注意,这是对当今我们看到的“代码膨胀”的直接挑战。

已添加:为了响应您对示例的请求,请参见差异执行。我不会说可以很快理解它,但是它确实可以显着减少UI代码。


如果存在一句要求,我们都将使用英语编码。就像任何人类语言一样,代码需要大量样板才能具有任何含义。
CurtainDog

@狗:从AI的角度来看,那将是理想的。看一下差分执行。这是将源代码削减一个数量级的真实示例。可能需要样板,但这不是一件好事。
Mike Dunlavey,2009年

5

在您的(原始)问题中使用单词始终是“可行的”,但鉴于存在的大量受支持的成熟语言和框架,它通常不是很有用,而且很少是最优的。

但是,这是一个有趣的智力挑战。


糟糕,抱歉。非母语人士... :)
Daniel Rikowski 09年

哦,不知道,您的帖子用英文很好,很难说。也不要试图成为语法警察-道歉。
西蒙

5

仅当您团队的核心业务是编程语言时。

我曾经在金融公司创建过一种编程语言。

显然,对于建筑师自己而言,这是一个巨大的挑战,并提高了他自己的技能。

不可避免地,该语言无法像C#或Java这样的速度来增长或改进-他们拥有致力于这一目标的团队。

这种语言很快就停滞了,因为没有人愿意承担改善别人宠物项目的任务。

原来的建筑师离开了。语言枯萎了,十年后死亡。

对于那些不幸地用一种死胡同的语言工作的人来说,那十年是地狱。

因此,继续创建您自己的语言,但是请不要让其他人实际使用它。请不要期望任何人感谢您。


1
有趣的案例研究...可以通过针对Java或.NET平台的语言来避免这种停滞。这样,随着将更多语言添加到基础库中,该语言可以“增长”。
CurtainDog

2
我不确定为什么要创建针对另一种语言(如Java)的语言。为什么不只是使用Java或C#开头呢?

4

设计语言可能很有趣。但是您不必专心编程语言。

如果我构建一个中等复杂的应用程序,我喜欢添加一种宏/脚本语言,以使执行复杂的重复性任务更加容易。大多数用户不会使用此功能,但很少使用它的人非常感谢。此外,我确保支持人员帮助他们解决客户问题很有价值。


4

如果这样做可以扩展您的技能和学习,那是完全合理的。

除此之外,如果您不得不问这个问题,那就不是。如果您想弄清楚是否可以比现有语言更好地处理某种算法或某种问题域,那么首先,您需要成为要解决的领域的专家。当您的技能和经验告诉您时,您就会知道这是适当的。

您可能对此也有错,但是您需要另一位专家来说服您(或者向您表明您不是您认为的专家)。您将在这里进行一场热烈的讨论,而不是简单的问答。


4

除了自学目的,我想声明今天不需要创建自己的语言。在任何情况下。曾经 无论您想做什么,都有大量您可以采用/适应您需要的现有语言。


您的说法极具争议,对我来说听起来像是在咆哮。
SK-logic

今天,有几种框架可以创建您自己的定制DSL,而我并没有真正涵盖我想说的内容(这是2年前)。我可能应该将其重新表述为“从头开始实施一种新的通用语言在实践中永远不是正确的方法”。:)
JesperE 2011年

好的,这个“通用”的添加改变了一切。但是,我不相信“通用”语言-它们都不是真正通用的语言,因此对于新的“某种通用”语言(实际上都是DSL而言)仍然有足够的空间。
SK-logic

3

它最终取决于情况。正如nosklo所说-如果您有一个好主意,一个全新的概念或类似的东西,我强烈建议您这样做。

总的来说,我建议依靠现有技术。

但是,如果您有兴趣创建自己的“语言”,则应该查看:YACC和Lex


3

您可以,只是不要陷入反模式“重新创建方形车轮”中。

意味着您正在重新创建已完成的操作,仅比原始操作差。


如果不重建轮子,我们可能仍会使用摇滚轮子。摇滚宝贝


3

什么时候创建自己的语言?

当您想要的时候,作为一个大型的爱好项目。

对于特定领域的语言。这些可能很复杂。检出档案,看看互动小说(或文字冒险)社区中发生了什么

当您的目标非常雄心勃勃,并且您认为自己可以取得真正的进步时,例如Paul Graham的Arc项目

而且,在开发低级结构的过程中,可以使用任何具有足够适应性的语言(也许是C ++,绝对是Common Lisp)。

我希望何时避免像瘟疫一样避免陈词滥调?

当它成为实际项目的持续开发的基础时。它总是会严重落后于廉价的市售产品,并且会削弱进一步的发展。我曾在一家拥有自己版本的COBOL的公司工作,从不希望在另一家维护自己语言的公司工作。我们看到其他版本的COBOL获得了更好的功能和更好的工具,而我们也遇到了同样的问题。(我不想再与COBOL合作,但这是另外一回事了。)

您可能会创建自己的语言的情况不属于这种情况。爱好项目不用于实际开发。诸如Arc之类的东西会成功(并获得多种实现以及进一步的发展和发展)或失败(其他人不会使用它)。特定于领域的小型语言仅是项目的一部分,并且由于它很小,因此可以随着时间的推移进行改进。文字冒险语言用于编写个人游戏,而这些游戏除了是业余项目外,几乎从未用于持续开发。


3

我的观点是,DSL通常是一个“弱主意”,从长远来看,使用标准语言并将特定领域的需求作为“非DSL”的库来提高生产力。

但是,事实证明您的需求足够定制,因此最好为您的公司提供DSL(而不仅仅是经过稍微修改的gcc或lisp实现)。许多公司使用针对他们正在做什么的当前语言的插件,而无需编写/维护自己的语言。例如,我听说PHP有一个不错的插件。Lua是围绕插件设计的,ModelView使用Python,而AutoCAD具有AutoLISP作为其脚本编写器。


3

如果可以利用现有工具,编写自己的编程语言没有错。在当今世界,这意味着您要么使用现有语言(例如Java或C#)可用的语法来定义它,要么编写一个小型转换系统(宏扩展器)以现有语言生成代码。

一直到机器编码一直在重塑很多轮子...

DSL的一个很好的理由是以简洁的方式表示域数据。这使领域专家可以直接使用数据,而不必遍历其他人。然后的诀窍是使生成的程序具有易于处理的形式。


3

一般来说,答案将是不可以。在数百种语言中,通常有一种适合您的问题。

但是,在某些情况下,开发一种新语言是一种合理的选择:

  • 当您的竞争对手之一现在拥有您的主要开发平台之一时。我正在考虑Google当前对Java的依赖以及他们对“ go”的开发(如果您的工资单上有最成功的语言的作者,这会有所帮助!)。
  • 当您必须为新平台编写大量代码并且现有语言冗长且容易出错时-例如用于Web开发的php。
  • 当您遇到以前从未遇到过的规模和并行性问题时,因为没人曾经拥有这么多的硬件来处理这么多的数据,例如Scala和(在一定程度上是GO)。

2

语言最擅长的是组合性或以不同方式将相同组件组合在一起。

如果您的域问题只是需要设置一堆正交开关,那么一种语言可能不会在表单,图形UI或纯文本配置上添加太多内容。文件。(我在这里假设一个充满键,值对的文件不是您所说的“语言”。)

OTOH,如果您的配置类似于真实语言,例如 动词和名词可以以多种不同(和新颖的)组合方式组合在一起,达到任何程度的复杂性,然后一种语言将几乎成为必然,因为试图通过任何其他方法指定所需内容的组合爆炸不知所措。


1

撇开学习练习,只有当您了解其他语言,您的特定问题领域以及现有语言解决该问题领域的方式时,才创建自己的编程语言是合理的,并且这种理解足够透彻,以至于您知道一种新语言是合理的。解决方案,而无需提出问题。


1

上一次我开始在一个业余项目中进行此操作时,我开始指定我想要的语法外观,并在我重新发明序言的过程中意识到这一点。当您认为自己需要发明一种语言时,其他合适的语言可能是Lisp,lua或类似Haskell的语言。基本上,您在大学时忽略了所有这些语言,因为您认为它们永远不会有用。


我通常使用十多种非常不同的语言。包括Prolog,各种Lisps和Haskell。但是我仍然倾向于通过为其实现DSL解决几乎所有问题。而且DSL足够具体,可以与任何现有语言相距甚远-它们看起来更像是不同语言的微小部分的混合体。
SK-logic

1

如上所述,原因之一是出于教育目的。但是还有更多。例如,有很多研究语言,如Sing#在上奇异的操作系统和BitCCoyotos已设计,因为现有的语言不提供(在语言水平,例如验证)所需的功能。


1

Tom Van Cutsem最近针对这个问题写了一篇论文答案:

http://soft.vub.ac.be/~tvcutsem/whypls.html

项目符号摘要(从该页面):

  • 语言作为语法抽象机制:减少无法从使用另一种语言的内置抽象机制中抽象出来的重复“样板”代码。
  • 语言作为思想塑造者:在如何构造软件方面引起范式转变(改变“阻力最小的路径”)。
  • 简化语言:将现有范式简化为基本范式,通常是为了增加理解和洞察力。
  • 作为执法者的语言:强制执行重要的属性或不变式,可能使从程序中推断出更多有用的属性更加容易。

0

可能永远不会。

如果您想将语言嵌入任何其他语言中,Lua是您可以获得的最佳选择。

小型域特定语言目前正在使用,并且在某些应用程序中是有意义的。

除此之外,原因主要是学术上的。

由于不需要进行开发和维护,因此创建不需要的语言确实是一件坏事。我见过许多项目,它们仅引入特定于该程序的某种脚本语言,这是使基础内容的开发速度大大降低的原因。例如,自动化语言(例如Phantom,AutoHotKey,AutoIt)就是很好的例子。如果使用Lua这样的著名的新兴语言,这些工具将对IMO更好。


卢阿(Lua)很慢。但是,另一方面,它具有一些不错的元编程功能。
SK-logic

0

您的“编辑”似乎是一个完全不同的问题(“我何时应构建DSL?”,而不是人们最初理解为“何时应构建新的通用编程语言”的原始问题)。似乎人们已经彻底回答了“原始”问题,但是很少给出给出何时使用DSL的特定标准的答案。所以我提出了一个清单:

  1. 您的用户群超过几个人,通常是非技术人员和/或系统访问受到限制(因此,期望他们学习/使用现有的通用语言是不合理的)。如果在您的开发团队或软件组织内部,则可以说“只写脚本”即可。
  2. 您的用户需要经常使用它,并且需要有足够的变化和变化的行为(即,您不能仅提供由您维护的固定功能库)
  3. 用户可以指定的行为过于复杂而无法指定为数据(例如,您无法使用数据库表,用户输入矩阵,任务列表或键值集合来实现此行为……请仔细考虑因为您可以使用这些实现很多复杂性)。如果您可以使用数据输入或配置而不是DSL来实现这种行为,那么您可能应该这样做,因为它将减少工作量。某种条件,或可组合性/链接在一起,或对几个不同的抽象建模可能表明您需要的行为对于纯数据/配置而言过于复杂
  4. 但是该行为仍然受到足够的限制,您可以在简洁的DSL中指定它。最大的危险是“平台膨胀”,例如,如果用户开始请求“您可以添加...吗?”。如果他们需要连接到Internet,或从文件系统中读取或写入文件,或打开和关闭进程,则不再是DSL。(我已经看到这种情况确实发生了……用户被允许嵌入小的python调用,逐渐增长为python脚本,最终破坏任何限制/模块化/性能)

如果所有这些都是正确的,那么DSL可能是合适的。


0

从长远来看,是否有更好的杀手级应用程序,算法问题类别等等,可以创造出自己的语言?

这取决于。

让我们动动脑筋。这似乎是一个复杂的混乱局面,以至于我们遇到了任何编程语言的边界(至少现在是这样)。因此,也许为了真正虚拟化我们的大脑,我们需要其他方法以及其他语义和语法。

一般而言,仍然存在如此复杂的主题,这可能会导致其他策略,其中还包括针对给定场景的“更好”的语言。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.