如何让clojure支持绑定中的相关值?

如何让clojure支持绑定中的相关值?,clojure,Clojure,我使用绑定作为一种手段,使它更容易在调用中传递状态。我现在有如下的东西 (binding [*private-key-path* "/Users/dcapwell/.ssh/id_dsa"] (binding [*session* (session "localhost")] ... 我需要这样做的原因是会话函数需要定义私钥路径。既然绑定不允许相关的值,那么有没有更简单的方法来完成上述操作而不需要嵌套 编辑: 目前正在使用clj-ssh.ssh进行原型设计。计划是使我目前使用的绑定

我使用绑定作为一种手段,使它更容易在调用中传递状态。我现在有如下的东西

(binding [*private-key-path*  "/Users/dcapwell/.ssh/id_dsa"]
  (binding [*session* (session "localhost")]
   ...
我需要这样做的原因是会话函数需要定义私钥路径。既然绑定不允许相关的值,那么有没有更简单的方法来完成上述操作而不需要嵌套

编辑:

目前正在使用clj-ssh.ssh进行原型设计。计划是使我目前使用的绑定大部分都是静态配置,大部分都是静态值,所以在引导时读取一次。使用绑定作为一种简化原型制作的方法,这样我就不必在看到API如何工作时不断地传递信息


我只是好奇如何让绑定相互依赖。当我使用let时,第二个绑定可以访问第一个绑定,但当我这样做时,第二个绑定似乎无法访问第一个绑定。我假设会有另一个类似于绑定的函数,但会允许第二个绑定访问第一个绑定。我还可以看到默认设置中不存在这种情况,因为它的状态比其他任何东西都多。

编辑:REPL中的一些实验

(def ^:dynamic *a* "a not bound")
(def ^:dynamic *b* "b not bound")
(defn show-a! []
  *a*)
(binding [*a* 1 *b* (show-a!)] *b*) ;; => "a not bound"

(binding [*a* 1]
  (binding [*b* (show-a!)]
    *b*)) ;; => 1
我很惊讶地知道给定的代码与以下代码不同:

(binding [*private-key-path* "/Users/dcapwell/.ssh/id_dsa"
          *session*          (session "localhost")]
  ...)
因此,Clojure在let表单中的括号比其他Lisp少,但不具有约束力

请考虑一下您的总体代码和/或API设计?一次又一次。动态绑定很糟糕。你很快就会受苦的。提示:使越来越多的代码单元可测试

我不确定你想做什么,因此我建议:

用于结构计算的一种称为图形的特征。不要再担心函数之间的依赖关系了


抱歉,我不明白为什么不将*私钥路径*作为参数传递给会话函数。无论如何,您也可以看看,绑定(如let)允许提供多个绑定,例如绑定[*out*某个流,*err*某个流]……正如James Sharp所说,私钥路径应该是会话函数的参数。对每一个可配置的设置使用绑定的globals感觉一点都不好。同意,我计划重写它,以便从配置中进行配置。大多数人只是想知道,如果需要的话,我怎么会有依赖关系。@JamesSharp我用redefs尝试过,在这种情况下,行为似乎是一样的。绑定不会发生在会话调用之前。这里的问题是私钥路径不会在会话调用之前绑定。因此,当调用会话时,该值是nil,即它在defagree中设置的值,即绑定可能不是一个好主意。目前,我只是将其用于ssh库的原型,以便了解如何打破它。我只是好奇为什么私钥路径不受会话调用时间的约束。没错,绑定的嵌套绑定形式是并行的,与let的绑定形式不同