项目特定的DSL是一种负担吗?

12 浏览
0 Comments

项目特定的DSL是一种负担吗?

关闭。这个问题是不适合主题的,目前不接受答案。


想改进这个问题吗?更新问题以使其适合Stack Overflow的主题

改进这个问题

我从我在一个非常好的回答中发表的评论中的类似问题中分叉出了这个问题。我最初问的是关于AST宏的问题,这引发了Lisper们非常详细和有思想的回应。谢谢。

惰性求值vs宏

我在评论中提出的问题是项目特定DSL是否实际上是一个好主意。当然,这完全是主观的 - 毕竟,在您编写非常表达性的语言时,在表达性API和实际DSL之间画哪条线?例如,我认为大多数Rubyists称为\' DSL \'的东西实际上只是设计良好的API,仅此而已。

注意,我在说的是项目特定的API。我认为在合适的情况下使用正则表达式或SQL没什么问题。

但是尽管如此,我认为我们都能够对API和DSL之间画出一个模糊、朦胧的界限。当然,它们都是API,但随便吧。

在一端,你有Lisp,DSLs似乎是通过宏得到积极鼓励的。另一端,你有Java之类的语言,DSLs几乎是不可能的。

DSL的支持者会认为它们增加了灵活性、表现力和一致性(例如,使用与语言自己的数字相同的运算符的自定义数字对象)。

反对者会说它们可能会导致子语言,除了DSL编写人员以外,没有人知道,破坏了首先拥有不同编程语言的意义,并且会导致没有人能理解的代码,因为与API的协作方式不同。

我不得不说,在很多方面我都同意双方的说法。有些Java API非常难懂,因为缺乏表现力。尽管如此,我通常总能弄清楚正在发生什么,而不必阅读文档——而这绝对不能说适用于自定义DSL。也许DSL的支持者认为你应该总是阅读API的文档。我不同意,但我也跑题了。

但是让我们看看一些现在很流行的大型语言。即C#和Java。它们都不太会进行DSL,但它们非常受欢迎。这难道不正是因为它们不允许像DSL这样的东西,让平庸的代码编写人员 churn出仍然可理解的代码吗?DSL(领域专用语言)允许平庸的程序员创造出难以理解的垃圾代码,这是否是 Lisp 没有被充分使用的原因,尽管在熟练使用 DSL 的人手中,DSL 的样子会像什么呢?

admin 更改状态以发布 2023年5月21日
0
0 Comments

DSL(领域特定语言)在Java中被广泛使用,但是Java中并没有“内部”DSL。与Java不同的是,Lisp拥有几种在不编写新的外部语言的情况下改变语言语法和语义的方式。在Java中,大多数DSL要么是外部的(通常基于XML),要么是使用预处理器实现的。

如果您要编写新的编程语言,也就是领域特定的编程语言,您需要:

  • 规定其规格
  • 记录其文档
  • 测试其
  • 使其强大
  • 使其可调试
  • 使其高效...等等

Lisp并不是一个能够为您完成所有这些任务的魔法弹药。Lisp给您的是可以直接将一个或多个DSL包含到语言中,并允许您重用或改变Lisp设施来实现您新语言的部分。

Lisp在其历史中实现了许多语言。其中许多是研究语言,没有太多关注软件工程实践。其中一些语言花费了更多的精力——例如,因为它们是某个产品的一部分。

如果您为项目开发语言,则需要确保遵循良好的软件工程实践,并且具备相应的资源。

0
0 Comments

当然,关于DSL存在支持和反对的争论,而且“库”或“API”和“DSL”之间有一个模糊的界限。你在问题中已经涵盖了这一部分,所以我不会讨论这些主观观点,而是聚焦于DSL是否是一种负担的问题。\n\n这里有一个很好的项目可以用来考虑这个问题,那就是将语言构建作为其主要特点的Racket。易于建立任何定义上的“语言”,包括DSL或非DSL,通过解释器构建或(更常见的方式)通过为新语言定义宏,并且可能还有一个针对不同语法的解析器。因此,Racket源代码树中有很多语言,其中一些具有根本不同的执行语义。下面是一些例子:Lazy Racket是您期望的意思;Type Racket是一种静态类型的语言;Scribble是用于编写文档和其他散文的语言;Slideshow是一种用于编写……幻灯片的语言;RackLog/DataLog是语义和语法都非常不同的语言。\n\n实际上,在Racket中创建新语言非常容易,即使它是仅适用于非常有限用途甚至仅仅是一个人使用的“小语言”。例如,我们有这种“小语言”,用于创建网页、决定哪些文件包含在分发安装程序中,以及许多其他用途。请查看此教程,了解如何设计一门语言。\n\n确实,一门有用的DSL和只有一个人使用的DSL之间之间是有一条细微的界线——但事实上,与库相比,定义语言所能获得的抽象化程度是相当高的。即使它是一个“单人语言”,这个概念也非常有用。这个领域面临的一个难题是考虑互操作性——Racket允许每个模块使用自己的语言编写,这带来了诸如以下问题:当懒惰语言和默认语言中的函数互相作用时,评估过程如何进行;或者如何确保类型化的代码可以与默认的非类型化语言互动,并且仍然获得静态类型语言的常规优势。

0