为什么导出固定声明是一个“坏主意”?

7
根据David MacQueen在他的《Reflections on Standard ML》报告中的说法1,词汇作用域中缀指令是从Pop-2遗留下来的不良遗产。它们使解析变得复杂,并且与模块系统不兼容,因为中缀指令无法由结构导出或在签名中指定(而添加此功能也不是一个好主意)
现在我确实同意他关于私有作用域infix[r]声明是个坏主意的说法,这使得导入用户定义的运算符变得相当无用,但我想象的解决方案是在签名中导出这些声明... 而不是完全摆脱它们。在我所知道的具有固定性声明的语言中(ML和衍生语言、Haskell和衍生语言、Prolog等),我对它们是否记录了这个想法的优缺点感兴趣。更普遍地说,语言实现者的经验会带来有趣的见解,以弥补从用户角度看起来很方便的功能的缺点。
所以我的问题简而言之是,文献中是否存在引用或已知的问题支持MacQueen关于不导出固定性的观点?

2
我的观点:一般运算符的固定性是众所周知的。通常很难在具有不熟悉且未知优先级的运算符的代码中进行视觉分析。即使学习了它们的固定性,你仍需要一些时间才能熟悉到一目了然的程度。除非你打算花费大量时间,否则它们似乎会带来很多麻烦。 - rajashekar
@mods:我重新措辞了问题,使其需要更少基于个人观点的答案。 - Moth
3
根据我的经验,通常会有一些约定/模式可以帮助很多人。例如:类似于 cons 操作通常会是 infixr,而像 snoc 的操作则是 infixl,以允许方便的重复应用。Cons 和 snoc 的绑定比 append 更紧密。如果操作形成一个半环,则“乘法”将比“加法”更紧密地绑定。混合无关的运算符而不使用括号通常会避免造成混淆。 - dfeuer
1
@MothMan 大部分软件编写都是基于个人观点的。其余的则是新手试图在P中解决NP难问题。 - David Tonhofer
1个回答

3
一种可能是如果您看到类似于x op1 y op2 z这样的东西,您不知道它是意味着op1(x, op2(y, z))还是op2(op1(x, y), z)。Prolog有write_canonical,它以纯前缀形式写入,因此您可以始终确切地了解某些内容已被解析。
此外,还存在从模块导出运算符声明的问题(SWI-Prolog似乎做得很好)。
除此之外,我想不到任何缺点。可读性和一致性有巨大的优势。例如,DCG的变体定义了一个名为-->>的运算符,类似于现有的-->...这使得事情比必须使用前缀表示法编写所有内容要容易得多。

还有从模块导出运算符声明的问题(我对此很感兴趣)一种可能性是,如果你看到类似于 x op1 y op2 z 的东西,你就不知道...(难道不是对于模块中的任何函数都可以这样说吗?我认为在开发过程中使用模块时参考模块签名和文档是必须的任务...这意味着暴露给中缀签名(如果导出)也是一个必须的任务) - Moth
1
在Prolog中,x op1 y op2 z是一种数据结构。 write_canonical将以前缀形式显示它(没有任何评估): ?- write_canonical(a+bc)。 +(a,(b,c)) - Peter Ludemann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接