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 中的大多数宏,以确保它们是安全的(即,明确地为每个特殊符号的使用添加命名空间)。我们如何处理像 try 和 new 这样的不仅与实现相关的特殊符号?使用那些宏的每第三个JUnit测试可能都会变得不安全。

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

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)(由aleξ+import报告)
0

编写一个“修复”来抛出一个变量或局部变量会掩盖特殊符号的情况,出人意料地并不太差。然而,仅仅是Clojure本身中就有许多实例使用varnew和其他在let绑定中使用的变量。

也许与其抛出一个错误,不如打印出“警告:掩盖特殊符号是不好的,不应该这样做!”这一提示已在定义新变量或在let绑定中使用时在几个地方实现了。

是的,你不希望抛出,这会破坏向后兼容性,你可能还希望像*warn-on-reflection*一样将其关闭。
这似乎是正确的。我将尝试一个替代方案,比如`*warn-on-shadowed-specials*`,看看感觉如何。
...