请在 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 投票

我认为另一个方向也应该警告。如果变量从动态重新定义为词法,也应发出警告。

by
我认为另一种方式确实有一个警告。
0 投票
by
...