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)

现在交换定义函数f和g的顺序。

(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投票
...