2024年Clojure状态调查!中分享你的观点。

欢迎!请参阅关于页面以获取更多关于此页面如何工作的信息。

+1投票
错误

`
=> (ns foo)
nil
=> (def a 1)

'foo/a

=> (ns bar (:require [foo :refer :all]))
nil
=> (def a 2)
编译器异常 java.lang.IllegalStateException: a 已经在命名空间 bar 中引用了: #'foo/a,编译:(NO_SOURCE_PATH:4:1)

clojure.lang.Compiler.analyzeSeq (Compiler.java:6745)
clojure.lang.Compiler.analyze (Compiler.java:6529)
clojure.lang.Compiler.analyze (Compiler.java:6490)
clojure.lang.Compiler.eval (Compiler.java:6801)
clojure.lang.Compiler.eval (Compiler.java:6760)
clojure.core/eval (core.clj:3079)
clojure.main/repl/read-eval-print--7095/fn--7098 (main.clj:240)
clojure.main/repl/read-eval-print--7095 (main.clj:240)
clojure.main/repl/fn--7104 (main.clj:258)
clojure.main/repl (main.clj:258)
clojure.main/repl-opt (main.clj:324)
clojure.main/main (main.clj:422)

原因
状态异常 a 已经在命名空间 bar 中引用了: #'foo/a

clojure.lang.Namespace.warnOrFailOnReplace (Namespace.java:88)
clojure.lang.Namespace.intern (Namespace.java:72)
clojure.lang.Compiler$DefExpr$Parser.parse (Compiler.java:534)
clojure.lang.Compiler.analyzeSeq (Compiler.java:6738)
clojure.lang.Compiler.analyze (Compiler.java:6529)

`

我预计(在最坏的情况下)重命名空间加载时会有类似的警告,而不是在这里抛出异常。

22 个回答

0投票

评论由:alexmiller 发布

能否为此问题提供一个一个不依赖于 core.matrix 的更好的可重复性测试用例?另外,当 (pst **e) 时,请包括它。

0投票

评论由:jafingerhut 发布

我已经尝试了最小化Leiningen项目,看看是否可以引起关于重新定义的警告,以确定是否可以引发异常。使用 'lein new try1' 创建基础项目,然后编辑 src/try1/core.clj 以包含以下函数定义

`
(defn merge
"此 merge 的定义替换了 clojure.core/merge"
[x y]
(- x y))

(defn
[x y]
(
x y))
`

然后使用 'lein repl' 启动一个REPL,并看到了这种行为

user=> (require '[try1.core :as c]) 警告:merge 已在命名空间:try1.core 中指代:#'clojure.core/merge,将替换为:#'try1.core/merge 警告:* 已在命名空间:try1.core 中指代:#'clojure.core/*,将替换为:#'try1.core/* nil user=> (require '[try1.core :as c]) nil user=> (require '[try1.core :as c] :reload) 警告:merge 已在命名空间:try1.core 中指代:#'clojure.core/merge,将替换为:#'try1.core/merge 警告:* 已在命名空间:try1.core 中指代:#'clojure.core/*,将替换为:#'try1.core/* nil

这一切看起来都像是我预期的行为,我没有看到 Mike 报告的异常。

看起来 Counterclockwise 中的 Ctrl+Alt+L 做的事情可能与 (require ... :reload) 不同,或者 Mike 的命名空间中除了重新定义 clojure.core 中的名称之外还有其他不同之处,这导致了这个问题。

0投票

评论由:alexmiller 发布

现在将其标记为 NR(未修复)- 很高兴看到它通过一个容易复制的测试案例重新打开。

0投票

由 mikera 发布的评论

如何复现

(ns op)
(defn (link: a b) (clojure.core/ a b)) ;; 提示警告
(ns use-op (:require (link: op :refer :all))) ;; 提示警告
(ns use-op (:require (link: op :refer :all))) ;; 出错!

我认为 Counterclockwise 简单地再次使用 CTRL-Alt+L 加载命名空间,这导致 ns 表达式被重新执行。

文档字符串表明 ns 可以多次使用("设置为 name (未评估) 命名的命名空间 ns(如果需要则创建它”)所以我会期望多次调用 ns 是无操作的

0投票

评论由:alexmiller 发布

重复 CLJ-1578。

0投票

由 mikera 发布的评论

这仍然影响着我,并导致随着 core.matrix 最新版本的更新而出现损坏。我不知道这是回归还是不是,但这确实在 1.7.0-RC1 中发生了。

我们能否为 1.7 修复它?由于这个原因而导致代码失败并强制用户代码重构(我的用例是向 clojure.core.matrix 命名空间添加一个新变量,用户代码中先前的变量定义出错)真是一件令人烦恼的事情。

0投票

由 mikera 发布的评论

关闭问题,因为我认为这更适合在相关问题中处理

0投票

由 mikera 发布的评论

重新开启问题,因为CLJ-1578显然并没有解决这个具体问题,它只涵盖了clojure.core中的vars。

我仍然希望看到这个问题在所有命名空间中都得到修复,而不仅仅是在clojure.core。

0投票
评论者:mikera

复现

=> (ns foo)
nil
=> (def a 1)
#'foo/a
=> (ns bar (:require [foo :refer :all]))
nil
=> (def a 2)
编译器异常 java.lang.IllegalStateException: a 已经引用了: #'foo/a 在命名空间: bar,编译:(NO_SOURCE_PATH:1:1)
=> *clojure-version*
{:major 1, :minor 7, :incremental 0, :qualifier "RC1"}

堆栈跟踪

编译器异常 java.lang.RuntimeException: 无法在这种上下文中解析符号:pst,编译:(NO_SOURCE_PATH:1:1)
    clojure.lang.Compiler.analyze (Compiler.java:6543)
    clojure.lang.Compiler.analyze (Compiler.java:6485)
    clojure.lang.Compiler$InvokeExpr.parse (Compiler.java:3737)
    clojure.lang.Compiler.analyzeSeq (Compiler.java:6735)
    clojure.lang.Compiler.analyze (Compiler.java:6524)
    clojure.lang.Compiler.analyze (Compiler.java:6485)
    clojure.lang.Compiler$BodyExpr$Parser.parse (Compiler.java:5861)
    clojure.lang.Compiler$FnMethod.parse (Compiler.java:5296)
    clojure.lang.Compiler$FnExpr.parse (Compiler.java:3925)
    clojure.lang.Compiler.analyzeSeq (Compiler.java:6731)
    clojure.lang.Compiler.analyze (Compiler.java:6524)
    clojure.lang.Compiler.eval (Compiler.java:6789)
原因
运行时异常 无法在这种上下文中解析符号:pst
    clojure.lang.Util.runtimeException (Util.java:221)
    clojure.lang.Compiler.resolveIn (Compiler.java:7029)
    clojure.lang.Compiler.resolve (Compiler.java:6973)
    clojure.lang.Compiler.analyzeSymbol (Compiler.java:6934)
    clojure.lang.Compiler.analyze (Compiler.java:6506)
    clojure.lang.Compiler.analyze (Compiler.java:6485)

0投票

评论者:bronsa

正如我在CLJ-1578中已经评论的那样,我认为这不是一个错误,并且我认为这个任务应该被拒绝。

重载非clojure.core的vars始终(至少从1.2版本开始)会抛出异常。

0投票

评论者:bronsa

Mike,可能将这个问题在clojure-dev ml(邮件列表)上提出来,以获取一些意见是有意义的。

0投票
span>

由 mikera 发布的评论

如果您喜欢,可以将其重新分类为功能请求。

我仍然认为这是一个缺陷,因为我希望:refer :all 可以正常工作。

无论如何,这个问题都在我的领域(数据科学/探索性统计学/数据管理)中导致用户代码中断。使用/引用所有功能对于设置便利的探索性工作命名空间非常有用,因此我不同意强迫用户明确要求使用每个var(正如Nicola在CLJ-1578中建议的那样)是一个实际的解决方案。

它还导致我在REPL和重新加载命名空间时遇到问题。

如果Clojure核心团队真的想保持这种令人烦恼的行为,我们至少需要有一种方法在库级别将其关闭。也许可以添加到clojure.core.matrix命名空间的一些命名空间元数据,以阻止这种情况发生?

0投票
span>

评论者:bronsa

Mike,这只是我个人的看法,我不是核心团队的一员,也不代表他们发言,这就是为什么我建议你在clojure-dev ml上写。

此外,为了澄清,您报告的问题在重新加载命名空间时不会出现,因为异常在重新定义发生时立即抛出。

0投票
span>

评论由:alexmiller 发布

您可以使用:exclude 做这个

(ns bar (:require [foo :refer :all :exclude (a)]))

0投票
span>

由 mikera 发布的评论

亚历克斯,这当问题发生时是一个修复,但它并不解决未来的用户代码破坏问题,除非用户准确预测到将添加哪些符号到 "bar"中。这又似乎给用户带来了一种不合理的工作负担。

我想我争辩的是,如果用户在自己命名的空间中定义了一个var,他们很高兴替换他们 previously use'd / refer-all'd的任何命名空间中类似命名的var。

如果用户真的担心意外地覆盖事物,我对一个类似于 warn-on-reflectionwarn-on-replace 感到非常满意。我之前在 CLJ-1257 中提出过类似的想法,甚至编写了一个补丁,以这种方式解决了整个问题。我们能在 1.7 中获得这个补丁或类似的解决方案吗?

...