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 本身中就有许多 varnew 等在其他 let 绑定中使用的实例。

也许不是抛出错误,而是打印一条消息:"WARNING: 覆盖特殊符号是不良行为,不应这样做!" 在定义新变量或者在 let 绑定中已经这样做了。

是的,你不希望抛出(它会破坏向下兼容性)。你也可能想将其关闭,就像 *warn-on-reflection*。
这个似乎对我来说是正确的。我会试一下一个替代方案,可能是 `*warn-on-shadowed-specials*`,看看感觉如何。
...