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](https://clojure.atlassian.net/browse/CLJ-1411) (由 alex+import 报告)
0

编写一个“修复”,如果变量或局部变量会隐藏特殊符号,则抛出异常,结果出奇地不是太糟糕。然而,在 clojure 本身中,有许多使用在 let 绑定中的 varnew 等。

也许不是抛出错误,而是打印“警告:隐藏特殊符号是不良的,不应这样做!”这已经在定义新变量或 let 绑定时做到了一两处。

是的,你不希望抛出异常,这会破坏向后兼容性。你还可以选择将其关闭,就像 *warn-on-reflection*。
看来这是正确的。我将尝试一个替代选项,可能是 `*warn-on-shadowed-specials*`,看看感觉如何。
...