在语法上有必要使用不同的打开和关闭分隔符
本文关键字:分隔符 语法 | 更新日期: 2023-09-27 18:00:45
在对智能引号和编程语言进行类比时,我突然想到,用于打开和关闭分隔符的不同字符可能没有必要,而只是可读性方面的一种选择。
例如,Ruby的匿名函数中的参数使用相同的管道来打开和关闭。哈斯克尔在使用白色空间时带有极端的偏见。
我不是在问是否需要不同的分隔符类型——括号用于索引器,大括号用于块——而是在大多数语言中,不同的开括号和闭括号(例如(
和)
)在语法上是否是所必需的,或者只是设计者的偏好。
语法上没有必要,但如果打开和关闭分隔符相同,则会使嵌套变得困难(或不可能)。证据A是POSIX外壳,其中
var=`command`
已替换为
var=$(command)
正是因为具有相同的开头和结尾分隔符的代码没有嵌套。
具有不同的分隔符允许嵌套。Ruby的块参数列表不支持嵌套,所以可以使用相同的分隔符。
在C和C++中,可以嵌套裸大括号,并打开嵌套的词法作用域:
{
int a = 42;
{
int a = 24;
{
printf("%d'n", a); // prints 24
}
}
}
使用相同的delimeter,这是不明确的:
|
int a = 42;
|
int a = 24;
| // Is this an open or close pipe?
printf("%d'n", a); // 24? 42?
| // could be a pair
| // of open+close
|
考虑到C语法规则的普遍性,可能还有许多其他语言存在类似的问题(例如perl)。
print |foo|bar||
可能意味着:
print (foo(bar))
或
print (foo)bar()
这两者都是有效的Haskell,具有不同的含义。但你在问,原则上是否可以调整语言以不要求这样做?
你可以做一件不可读的事情。与其应用并置函数,不如为应用程序引入一个前缀2-参数运算符,称之为*
。然后:
foo (bar (baz quux)) bax
可以毫不含糊地写:
* * foo * bar * baz quux bax
应用程序和一个常量符号就足以编码组合子微积分,所以,在技术上,不,你根本不需要括号(图灵机也不需要括号)。
但你不能只是把所有的括号都熨成条形,然后让它明确地有意义。
Unlambda是一个没有括号、大括号等的语言的例子。它们被一个表示"应用"的运算符(Backtick)取代。类似地,在Haskell中,您可以编写a $ b c
而不是a (b c)
。因此,有一些方法可以避免使用不同的分隔符。
从编写编译器的开发人员的角度来看,我认为使用分隔符更容易。我不确定你所说的不同的分隔符到底是什么意思,但从技术上讲,你可以在语言中使用任何你喜欢的符号。看看这里的语言。只要看看当if语句有左大括号和右大括号时解析它有多容易:
if (true)
{
doSomething();
thenDoSomethingElse();
}
与相反
if true
doSomething
thenDoSomethingElse
除了选项卡之外,我还应该如何表明我希望这两个方法都作为if
主体的一部分执行。大括号让解析器清楚地知道,所有这些都是一起进行的。这样做的语言的问题是"悬挂的其他问题":
if true
if someCondition
doSomething
else
doSomethingElse
你最好让你的解析器足够聪明,知道如何匹配else语句。我认为明确的分隔符使这更容易。
正如其他人所提到的,它们不是必需的。还有其他方式可以指示块何时开始/结束。也就是说,不同的打开和关闭分隔符为阅读代码的人提供了更多的信息。这些信息不仅可以帮助读者了解代码在做什么,还可以它打算做什么。
例如,许多编码标准要求在C.中的单个语句if块周围使用大括号