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

欢迎!有关如何工作的更多信息,请参阅关于页面。

+1
编译器

以下两个代码片段的行为差异很大,只取决于你定义函数的顺序。我发现这种行为很令人惊讶,可能不是预期的。

(ns jimka-test
  (:require [clojure.pprint :refer [cl-format]]))

(declare f)

(defn g []
  (map f '(1 2 3)))

(def ^:dynamic f (fn [x] (* x x)))

(defn h []
  (assert (= (g) '(1 4 9)))
  (binding [f (fn [x] (+ x x))]
    (assert (= (g) '(2 4 6))
            (cl-format false "(g) returned ~A" (g)))))

(h)

现在交换fg定义的顺序。

(ns jimka-test
  (:require [clojure.pprint :refer [cl-format]]))

(declare f)

(def ^:dynamic f (fn [x] (* x x)))

(defn g []
  (map f '(1 2 3)))

(defn h []
  (assert (= (g) '(1 4 9)))
  (binding [f (fn [x] (+ x x))]
    (assert (= (g) '(2 4 6))
            (cl-format false "(g) returned ~A" (g)))))

(h)

我的建议是,如果声明了一个非动态变量,那么后续的动态定义应该引发警告。

这个问题也在clojureverse上进行了讨论

2 个答案

0

我认为也应该警告相反的方向。如果变量从动态重新定义为词法,也应有警告发出。

我认为另一种方法确实有一个警告。
0
...