Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matrix 使第二个命名空间选择要加载的第三个命名空间_Matrix_Clojure_Dependencies - Fatal编程技术网

Matrix 使第二个命名空间选择要加载的第三个命名空间

Matrix 使第二个命名空间选择要加载的第三个命名空间,matrix,clojure,dependencies,Matrix,Clojure,Dependencies,命名空间foo定义了一组用算术运算符定义的函数。这些是标量算术运算符或矩阵算术运算符,具体取决于foo是否需要标量算术或矩阵算术命名空间。(foo.cljc中没有太多的代码,但复制它就够傻的了。我知道core.matrix——这就是矩阵算术的定义——可以处理原始标量,但在这种情况下,它比Clojure的内置算术慢得多,foo函数的速度对我的ap很重要。)折叠。) 命名空间bar-s需要标量算法。名称空间bar-m需要矩阵运算。两个名称空间都需要名称空间foo中定义的函数,但是bar-s需要标量版

命名空间
foo
定义了一组用算术运算符定义的函数。这些是标量算术运算符或矩阵算术运算符,具体取决于
foo
是否需要
标量算术
矩阵算术
命名空间。(foo.cljc中没有太多的代码,但复制它就够傻的了。我知道core.matrix——这就是
矩阵算术
的定义——可以处理原始标量,但在这种情况下,它比Clojure的内置算术慢得多,
foo
函数的速度对我的ap很重要。)折叠。)

命名空间
bar-s
需要标量算法。名称空间
bar-m
需要矩阵运算。两个名称空间都需要名称空间
foo
中定义的函数,但是
bar-s
需要标量版本的函数,而
bar-m
需要矩阵形式的函数。我们可以假设,在同一会话中,我将只加载
bar-m
bar-s
中的一个。(如果我不需要这个假设,那很好,但我可以接受。)

我试图找出
bar-s
bar-m
指定加载哪个版本的
foo
——也就是说,如何强制
foo
加载
标量算术
命名空间,或加载
矩阵算术
命名空间。(或者:如果有更好的、完全不同的方法来完成我想做的事情,我很乐意重新思考。)

目前,这就是我正在做的。这似乎是可行的:我有另一个名称空间,
config
,在其中我定义了一个包含布尔值的原子。在
bar-s
bar-m
中,我将这个原子重置为一个值,该值将选择我想要的算术实现,然后我
需要
foo
foo
检查原子,然后
根据原子要求
标量算术
矩阵算术

这可能是我想要的最好的方法,但这是一种奇怪的方法,我想知道是否有更好的方法。我认为,如果我只在会话开始时重置atom,我不会有问题,但我担心会有一些我不知道的问题

以下是设置的玩具版本:

(ns scalar-arithmetic)

(defmacro m* [x y] `(* ~x ~y))
;; Using (def m* *) instead would lose Clojure's special optimizations for *

(defmacro inv [x]  `(/ 1.0 ~x))

;;;;;;;;;;;;;;;;;
(ns matrix-arithmetic
  (:require [clojure.core.matrix :as mx]))

(def m* mx/mmul)     ; matrix multiplication
(def inv mx/inverse) ; matrix inverse

;;;;;;;;;;;;;;;;;
(ns foo
  (require [config]))

(if @config/use-core-matrix
   (require '[matrix-arithmetic :refer [m* inv]])
   (require '[scalar-arithmetic :refer [m* inv]]))

(defn fooey [r s] (m* r (inv s))) ; could have either scalar or matrix meaning

;; The next two namespaces would not both be loaded in the same session.

;;;;;;;;;;;;;;;;;
(ns bar-s
   (require [config]))

(reset! config/use-core-matrix true)
(require '[foo])

;;;;;;;;;;;;;;;;;
(ns bar-m
  (require [foo])) ;; default value of use-core-matrix is false, so this is enough.

可能会有帮助。这似乎是一个规范的多方法用例。为什么不使用多种方法呢?@JonahB,你可能是对的。不确定。老实说,我没有想过多种方法,但我应该想到。那会像普通的Clojure
+
-
*
/
一样快吗?目前,我将标量运算符定义为宏,这样与原始数学运算符相比,我就不会损失速度。(这是针对性能关键的代码)我可以运行基准测试,但考虑到我对多方法的理解,我认为它们应该更慢。我相信,我已经确定协议会更慢。@nrako,谢谢你给我这个答案的指针。似乎这应该是相关的,但我还不知道如何使用这个答案中的想法。我当然不想在每个操作符调用上都加载名称空间。对于性能敏感的操作,使用协议的基于类型的分派应该是最快的。所有jvm调度都必须是类型化的,协议提供提示并允许普通函数无法实现的缓存。可能值得分享反馈基准。对于上面的用例,请参见core.matrix及其实现。