2024 年 Clojure 状态调查!中分享您的想法。

欢迎!有关本网站如何运作的更多信息,请参阅 关于 页面。

+1
编译器

编译器不会对 let 绑定(或 def-ing)特殊符号提出异议,但这些绑定只有在不作为列表开头时才有效

这些是有效的

(let [try :a] try) => :a (let [try (constantly :a)] (apply try :b)) => :a

这不起作用

(let [try (constantly :a)] (try :b)) => :b

这对于所有特殊符号都成立,而不仅仅是像 try 和 new 这样公开暴露的符号,还包括如 fn** 这样的内部符号。

我期望得到一致的行为:要么编译器根本不允许遮挡特殊符号,要么遮挡特殊符号在所有情况下都有效。

6 个回答

0

评论由:bronsa 发表

我不认为遮挡特殊符号是一个好主意,但可能将所有特殊符号转换为命名空间限定(目前只有 clojure.core/import* 是命名空间限定的)并首先在局部环境中查找符号,然后在之后回退到特殊符号映射,可能会帮助那些情况。

0

评论由:oakley jurgens 发表

我认为遮挡特殊符号不是一个好主意。如果可行,我们就需要更改 clojure.core 中大多数宏来使其安全(即显式地为每个特殊符号的使用添加命名空间)。我们如何处理那些不是仅仅针对特定实现的特殊符号,如 trynew?每个使用这些的用户的一级占位符都可能变得不安全。

我个人的偏好是禁止遮挡特殊符号。

0

评论由:bronsa 发表

情况不会是这样,因为我在建议中包括使语法引号对命名字符符号做出反应。
例如,`def将扩展为'clojure.core/def。

0

评论由:oakley jurgens 发表

这是真的,但宏不必使用语法引号。例如,请参见when的定义。

0
参考: https://clojure.atlassian.net/browse/CLJ-1411(由alex+import报告)
0

编写一个“修复”,如果变量或局部变量会隐藏特殊对象,将抛出异常,竟然不是太糟糕。然而,只是在clojure本身中,就有许多在let绑定中使用的varnew等实例。

也许不能抛出错误,因为它会破坏向后兼容性。也许您还需要将其关闭,就像*warn-on-reflection*一样。

没错,您不想抛出异常,因为这样会破坏向后兼容性。也可能想禁用它,就像*warn-on-reflection*。
我觉得这看起来没问题。我将尝试另一种方法,也许叫做 `*warn-on-shadowed-specials*`,看看感受如何。
...