在Clojure REPL中使用长let表达式

在Clojure REPL中使用长let表达式,clojure,Clojure,我经常遇到这种情况,想知道是否有一个简单的解决方案。假设我有一个Clojure源文件,它有一个let表达式,如下所示: (let [a (...) b (...) c (...) d (...) e (...) f (...) g (...) h (...)] (...)) 其中,每个值取决于上述某些值 然后,当我想手动使用REPL中定义h的表达式时(假设至少有一个输入是某个巨大的map-JSON响应,或

我经常遇到这种情况,想知道是否有一个简单的解决方案。假设我有一个Clojure源文件,它有一个
let
表达式,如下所示:

(let [a (...)
      b (...)
      c (...)
      d (...)
      e (...)
      f (...)
      g (...)
      h (...)] 
  (...))
其中,每个值取决于上述某些值

然后,当我想手动使用REPL中定义
h
的表达式时(假设至少有一个输入是某个巨大的map-JSON响应,或者手动输入会更麻烦),然后我发现自己在手动操作

(def a (...))
(def b (...))
(def c (...))
(def d (...))
(def e (...))
(def f (...))
(def g (...))
我甚至还没来得及开始搞砸
h

通常这意味着在REPL中键入
(def)
,然后移动鼠标,从
let
表达式中复制
a(…)
,粘贴回
(def)
,然后按enter键,然后返回并对
b
执行相同的操作,依此类推


有没有更快的方法来解决这个问题?

这里有一个可能适合您的方法:

(let [a (...)
      b (...)
      c (...)
      d (...)
      e (...)
      f (...)
      g (...)
      h (...)
      _ (def h' h)] 
  (...))

显然,您永远不会希望在代码中签入这样的内容,但对于在REPL中进行黑客攻击来说,这可能就足够了。

您还可以编写一个宏,它接受
let
表单的绑定,并将其转换为
def
表单的序列

(defmacro letdef [bindings]
  (apply list `do (for [[s expr] (partition-all 2 bindings)]
                    `(def ~s ~expr))))

(letdef [a 1
         b 2
         c 3
         etc (+ a b c)])

(println etc) ;=> 6

伟大的为什么这不是核心的一部分?似乎这应该是一个共同的需要。不是吗?还是long
let
s不是Clojureque?如果不是的话,还有什么更惯用的方法来定义许多价值观呢?我发现自己一直都需要这个,而且我认为我没有做任何不寻常的事情,我想其他人也会需要它。所以我想知道,既然这个宏不在内核中,我对如何在clojure中编程有什么基本的不了解吗?长let(>5个绑定)是不常见的,但是kosher afaik。在进行repl驱动的开发时,我一直使用ad-hoc
def
s解决这类问题。我倾向于通过混合调试(草书非常棒)和深思熟虑的问题分解来避免大部分时间对它的需要。