灵活性如何影响语言的语法?

时间:2019-04-03 12:38:41

标签: programming-languages language-design usability flexibility

我目前正在写自己的语言(shameless plug),该语言以灵活性为中心。我正在尝试使语言语法的几乎任何部分都可以通过扩展/插件之类来交换。在编写整个内容时,这使我产生了思考。我想知道这种灵活性如何影响语言。

我知道Lisp由于其广泛的宏系统而通常被称为最可扩展的语言之一。我确实了解宏的概念,但是我尚未找到一种允许某人更改其解析方式的语言。据我所知,几乎每种语言都有很长的规范所定义的极其具体的语法。

我的问题是,灵活的语法会如何影响语言的直观性和可用性?我知道基本的“语法变化时人们可能会感到困惑”和“语义分析将很困难”。这些都是我已经开始弥补的事情。我正在寻找关于使用灵活语法的利弊的更具概念性的答案。

语言设计的话题对我来说仍然很陌生,因此如果我问一个明显的或愚蠢的问题,我深表歉意!

编辑: 我只是想澄清我在问的问题。就语言理论而言,语言语法的灵活性到底在哪里?我实际上并不需要具有灵活性的示例或项目/语言,我想了解它如何影响该语言的可读性,功能以及类似的东西。

4 个答案:

答案 0 :(得分:1)

Perl是我所知道的最灵活的语言。看一下Moose,这是Perl 5的后现代对象系统。它的语法与Perl的语法有很大不同,但是仍然非常Perl-ish。

IMO,灵活性最大的问题是中缀符号的优先级。但是我不知道允许数据类型具有自己的中缀语法。例如,取套。最好在其语法中使用。但是,不仅编译器必须识别这些符号,还必须告知它们它们的优先顺序。

答案 1 :(得分:1)

Common Lisp允许更改其解析方式-请参阅阅读器宏。 Racket允许修改其解析器,请参见球拍语言。

当然,如果您使用正确的解析技术(例如PEG),则可以与功能强大的宏一起进行灵活,动态可扩展的解析。看看这里的example-主要是C语法,但可以同时使用语法和语义宏进行扩展。

关于优先级,PEG与Pratt的配合非常好。

要回答您的最新问题-令人惊讶的是,关于编程语言可读性的研究很少。您可能想看看Blackwell博士小组was up to的情况,但这还不是结论性的。

因此,我只能共享我的手头轶事-灵活的语法语言有助于eDSL的构建,并且我认为eDSL是消除代码不必要的复杂性,使代码可以长期维护的唯一方法。我认为,非灵活语言是该行业犯下的最大错误之一,必须尽快解决所有问题。

答案 2 :(得分:1)

灵活性允许您操纵语言的语法。例如,Lisp宏可以使您编写程序,这些程序可以编写程序并在编译时对有效的Lisp表达式进行语法处理。例如循环宏:

(loop for x from 1 to 5
      do(format t "~A~%" x))

1
2
3
4
5
NIL

我们可以看到如何使用macroexpand-1转换代码:

(pprint(macroexpand-1 '(loop for x from 1 to 5
                 do (format t "~a~%" x))))

然后我们可以看到如何转换对该宏的调用:

  (LET ((X 1))
(DECLARE (TYPE (AND REAL NUMBER) X))
(TAGBODY
 SB-LOOP::NEXT-LOOP
  (WHEN (> X '5) (GO SB-LOOP::END-LOOP))
  (FORMAT T "~a~%" X)
  (SB-LOOP::LOOP-DESETQ X (1+ X))
  (GO SB-LOOP::NEXT-LOOP)
 SB-LOOP::END-LOOP)))

语言灵活性仅允许您在一种语言中创建自己的嵌入式语言,并根据所使用的字符减少程序的长度。因此,从理论上讲,由于我们可以操纵语法,因此这会使语言非常难以阅读。例如,我们可以创建转换为有效代码的无效代码:

(defmacro backwards (expr)
   (reverse expr))
BACKWARDS
CL-USER> (backwards ("hello world" nil format))
"hello world"
CL-USER> 

显然,由于以下原因,以上代码可能会变得复杂:

 ("hello world" nil format)

不是有效的Lisp表达式。

答案 3 :(得分:0)

感谢SK-logic的回答,将我指向了Alan Blackwell的方向。我给他发送了一封电子邮件,询问他对此事的立场,然后他做出了绝对绝妙的解释。在这里:

  

所以回答您的StackOverflow问题的人说   灵活的语法可能对DSL有用,这是正确的。   实际上,使用C预处理程序来实现   创建替代语法(该语法将在   初始编译阶段)。许多早期的esolang都是这样建造的   方式。

     

在实践中,我认为我们不得不说很多DSL   在常规编程语言中实现为库,并且   库设计比语法要重要得多。那里   可能更具有视觉语言多样性的目的,但是   可定制的通用编译器,用于任意图形语法   真的很难-比更改文本语法功能更糟糕。

     

您的设计可能启用了一些有趣的东西,因此   我不会阻止实验。但是,我认为原因之一是   可定制的语法并不常见。这与著名的   程序员的编辑器EMACS。在EMACS中,所有内容均可自定义-全部   键绑定以及所有编辑器功能。玩起来很有趣,而且   过去,我们许多人制作了自己的个性化版本   只有我们知道如何操作。但是事实证明这是一个真实的   麻烦大家的编辑完全不同。你可以   从不倾身并在别人的会议上提出建议,并且   团队始终必须知道谁登录了,才能知道   编辑将工作。事实证明,多年来,我们都   开始使用默认的发行版和按键绑定,   一切都变得更容易。

目前,这只是我一直在寻找的一种解释。如果有人觉得自己有更好的解释或要补充的内容,请随时与我联系。