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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.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
从java调用Clojure时Clojure状态的作用域_Clojure - Fatal编程技术网

从java调用Clojure时Clojure状态的作用域

从java调用Clojure时Clojure状态的作用域,clojure,Clojure,我是Clojure的新手,所以这可能是一个非常明显的问题,但我找不到任何有用的答案 我正在用Spring Boot实现一个REST服务,它使用Clojure通过多次调用Compiler.eval()来计算结果。我有一些Clojure的东西,应该在所有请求(常量、函数、全局变量等)之间共享,还有一些每个请求的东西,应该对每个请求进行隔离和唯一 我将此服务作为可执行JAR运行,并在类路径中使用clojure.JAR。然而,从JVM的角度来看,您只能通过静态方法访问Clojure,这意味着每个JVM只

我是Clojure的新手,所以这可能是一个非常明显的问题,但我找不到任何有用的答案

我正在用Spring Boot实现一个REST服务,它使用Clojure通过多次调用Compiler.eval()来计算结果。我有一些Clojure的东西,应该在所有请求(常量、函数、全局变量等)之间共享,还有一些每个请求的东西,应该对每个请求进行隔离和唯一

我将此服务作为可执行JAR运行,并在类路径中使用clojure.JAR。然而,从JVM的角度来看,您只能通过静态方法访问Clojure,这意味着每个JVM只有一个“Clojure实例”。这意味着,如果您在一个请求期间进行eval(def a 1),那么其他请求也会看到“a”

问题1:我应该在哪里以及如何在Clojure中定义动态(请求范围)变量/符号


问题2:假设我希望每个请求都有一个完全“新”的Clojure实例。我怎样才能做到这一点?例如,我可以在同一个JVM中使用相同名称和相同名称空间的变量,但是使用不同的值?我知道我可以通过使用新的类加载器来加载一组全新的Clojure类,但这似乎非常麻烦。

在Clojure中不应该使用全局变量,除非需要跟踪某些全局“状态”,而这些状态必须在所有函数之间共享。它是一种函数式语言(嗯,主要是函数式语言),处理事情的函数式方式是将所有必需的东西作为参数传递。这就是如何获得引用透明性,以及如何避免函数看到和影响彼此的值

我不知道您为什么要使用SpringBoot来实现这一点,但也许您可以看看Clojure原生web库是如何工作的。它们通常将某种“请求上下文”传递给处理程序,所有必要的信息都存储在处理程序中

例如,或

因此,回答你的(1):在每个请求中传递它们。 和(2):如果您在每个请求中传递新的值,则不需要这样做。

尽管在Clojure中使用一个请求的本地全局变量(请原谅这个丑陋的表达式)并不是一般推荐的web服务方式,但假设您对此有一个有效的用例。一个这样的用例可以是构建一个类似REPL的在线应用程序

隔离请求的一种可能性是为每个请求创建一个临时(随机)名称空间,并在每个请求之后擦除名称空间。用于
sandbox
ing(来自
src/trycoljure/models/eval.clj
的片段):


至于1)我会使用
调用
并传递每个请求的状态,这不仅仅与web请求相关。假设一个Java程序想要运行多个独立的Clojure程序。我希望能够执行新的Clojure().compiler().load(…)。但由于所有方法都是静态的,所以您实际上无法将一个程序与另一个程序分开,除非您使用单独的类加载器,或者在各自的JVM中启动每个类加载器。因此,尽管它是一种函数式语言,但它本质上充满了静态。这是一个设计缺陷。
(defn make-sandbox []
  (sandbox try-clojure-tester
           :timeout 2000
           :init '(do (require '[clojure.repl :refer [doc source]])
                      (future (Thread/sleep 600000)
                              (-> *ns* .getName remove-ns)))))