Clojure - 关闭另一个命名空间中的函数

Clojure - close over a function in another namespace

假设我有以下内容:

(defn my-fn [params]
  (make-things (a-fn [ctx]
                 (do-this params)))

现在我想把它分成不同的文件,这样 a-fn 就在另一个命名空间中:

(defn my-fn [params]
  (make-things my.ns/a-fn))

但现在的问题是 params 不再关闭我的功能。应该怎么做?

重写:

(defn my-fn [params]
  (make-things (fn a-fn [ctx]
                 (do-this params)))

进入

(defn my-fn [params]
  (make-things ((fn a-fn-o [p]
                 (fn a-fn [ctx]
                   (do-this p)))
                params)))

这是编译器在您关闭变量时为您所做的。

那么在你的其他文件中做什么应该就很清楚了。函数returns一个函数你传入params:

(defn my-fn [params]
  (make-things (my.ns/a-fn params)))

;; my.ns
(defn a-fn [params]
  (fn [ctx] (do-this params)))

顺便说一句,您的 ctx 参数未使用。

正如刚才提到的那样,您可能还想考虑 using a Var to scope the params dynamically rather than lexically 而不是闭包。如果它们 "implicit arguments" 到 my.ns.

中的几个相关函数,这将特别有用
(ns my.ns)

(def ^:dynamic *params* ...) ;;Optional default value here

(defn a-fn [...]
   (do-this *params* ...))

然后在调用ns

(defn my-fn [params]
  (binding [my.ns/*params* params]
    (my.ns/a-fn ...)))

这就是 with-out-str 如何改变任何 print 变体在其主体和子计算中的行为 - 通过将 *out* 重新绑定到一个空字符串编写器。

您也可以使用部分:

(ns my.ns)

(defn a-fn [params ctx]
  (do-this params))

然后在调用上下文中:

(defn my-fn [params]
   (make-things (partial my.ns/a-fn params)))