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

欢迎!请参阅关于页面以了解更多有关如何使用本网站的信息。

0
Clojure

以下代码失败(在1.6和最新的1.7-alpha4版本中均如此)

`
user=> (ns foo)
nil
foo=> (def inc inc)
WARNING: inc 已经在命名空间foo中引用为: #'clojure.core/inc,将替换为: #'foo/inc

'foo/inc

;; 注意在这一时刻 incalready unbound,这导致以下异常
foo=> inc

foo=> (ns bar)
nil
bar=> (require ['foo :refer ['inc]])
WARNING: inc 已经在命名空间bar中引用为: #'clojure.core/inc,将替换为: #'foo/inc
nil
bar=> (inc 8)

IllegalStateException 正在尝试调用未绑定函数:#'foo/inc clojure.lang.Var$Unbound.throwArity (Var.java:43)
`

进一步的调查表明 foo/inc 未绑定

foo/inc
=> #

进一步的调查还表明,用几乎任何其他内容替换 (def inc inc),例如 (def inc dec),(def inc clojure.core/inc),或 (def inc (fn (link: n) (+ n 1))),都不会引发异常(但仍然会有警告)。

我期望
a) foo/inc 应该绑定并具有与 clojure.core/inc 相同的值
b) 在要求 foo/inc 时不出现错误
c) bar/inc 应绑定到 foo/inc

22 个答案

0

评论由:bronsa 提出

第二个错误应该是可以预料的,正确的语法应该是 (require (link: 'foo :refer ['inc])) (注意 inc 前面的引号)

0

评论由:mikera 提出

感谢 Nicola 的发现 - 我已经编辑了描述。但是仍然出现相同的错误,只是消息略有不同。

0

评论者:alexmiller

查看评论...

0

评论由:mikera 提出

@Alex什么评论?请注意即使语法正确,错误仍然发生...

0

评论由:mikera 提出

似乎被提前关闭

0

评论者:alexmiller

我无法使用正确的语法进行复现

`
Clojure 1.7.0-master-SNAPSHOT
user=> (ns foo)
nil
foo=> (def inc inc)
WARNING: inc 已经在命名空间foo中引用为: #'clojure.core/inc,将替换为: #'foo/inc

'foo/inc

foo=> (ns bar)
nil
bar=> (require ['foo :refer ['inc]])
WARNING: inc 已经在命名空间bar中引用为: #'clojure.core/inc,将替换为: #'foo/inc
nil
`

0

评论由:mikera 提出

问题是变量仍然未绑定,并导致如下错误

=> (foo/inc 8)
IllegalStateException 正在尝试调用未绑定函数:#'foo/inc clojure.lang.Var$Unbound.throwArity (Var.java:43)

我认为这不应该是预期的 - 或者我是不是漏掉了什么?

0

评论者:alexmiller

啊,我会看看的。但现在不行。:)

0

评论者:jafingerhut

补充了一些更多详细信息更新了描述。如果你使用(def inc (fn (link: n) (+ n 1)))而不是(def inc inc),例如,异常就会消失。但仍会存在警告。

0

评论人:tcrayford

不确定这是否是同一个问题(我认为可能是一样的),但我用AOT编译重现了相同的错误信息

在以下git仓库中重现:https://github.com/yeller/compiler_update_not_referenced_bug

克隆它,运行lein do clean, uberjar, test,每次都会出现这个错误信息

0

评论者:jafingerhut

Mike,我认为将示例中的(def inc inc)替换为(def inc clojure.core/inc)应该被作为一个合理的解决方案,除非你有某些需要将inc定义为clojure.core之外的值的用例(如果是这样,为什么?)

(def inc inc)行为如此的原因是,如果不是绝对必要的,至少在Clojure程序中通常用于定义递归函数,例如(定义fib (链接: n) (如果(<= n 1) 1 (+ (fib衰减n)(fib下半年 - n))),以便在主体中解析fib的出现到被定义的fib

0

评论者:alexmiller

将此问题转移到1.7版本,直到我能更深入地查看。

0

评论由:mikera 提出

Andy - 目前这个解决方案对我来说是可行的。

我认为这不是一个紧急问题,但它可能揭示了关于命名空间不同时间状态的假设的微妙复杂性。也许语义应该是这样的:
- 应在var被加入之前运行def语句本身。例如(def inc(inc 5))应导致(def inc 6)
- 在def语句完成后运行的所有编译/延迟执行的项应使用新的var(即新的var应被函数、懒序列等引用)

0

评论者:jafingerhut

我不确定你的建议在这个情况下意义何在

(def inc(fn [x](inc x)))

第二增量是要在创建新增量之前还是之后解释/解析的?因为它是一个(fn ...),所以它应该是后期行为吗?除此之外还有哪些情况会导致后期行为,而不是前期行为?

更有趣的是(并不是说人们常常这样写代码,但编译器今天可以处理它)

`
(def inc (if (> (inc y) 5)

       (fn [x] (inc x))
       (fn [x] (dec x))))

`

我认为当前编译器的行为'在一个def的身体中,定义的符号始终指向新的变量,而不是任何之前定义的变量'是相当容易解释的。

0

评论人:tcrayford

我应该把在那个东西中复现的AOT问题作为一个新问题提交吗?

...