【问题标题】:Working with long let expressions in Clojure REPL在 Clojure REPL 中使用 long let 表达式
【发布时间】:2015-01-07 14:53:40
【问题描述】:

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

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

每个值都依赖于上面的一些值。

然后,当我想手动使用 REPL 中定义 h 的表达式时(假设至少有一个输入是一些巨大的地图 JSON 响应,或者输入起来更痛苦的东西手动),然后我发现自己手动做

(def a (...))
(def b (...))
(def c (...))
(def d (...))
(def e (...))
(def f (...))
(def g (...))

在我开始尝试与h 搞混之前。

所以通常这意味着在 REPL 中输入(def ),然后移动鼠标,从let 表达式中复制a (...),粘贴回(def ),然后按回车键,然后返回执行b 也一样。

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

【问题讨论】:

    标签: clojure


    【解决方案1】:

    您还可以编写一个宏,它接受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 lets 不是 Clojuresque?如果不是,那么定义大量值的更惯用方式是什么?
    • IOW 我发现自己一直都需要这个,鉴于我认为我没有做任何不寻常的事情,我认为其他人也会需要它。所以我想知道,鉴于这个宏不在核心中,是否有一些基本的东西我只是不了解如何在 clojure 中编程?
    • Long Lets(> 5 个绑定)并不常见,但符合犹太教标准。在进行 repl 驱动的开发时,我总是使用 ad-hoc defs 来解决这类问题。大多数时候,我倾向于通过混合调试(草书很棒)和深思熟虑的问题分解来避免对它的需求。
    【解决方案2】:

    这里有一个可能对你有用的技巧:

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

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

    【讨论】:

      猜你喜欢
      • 2011-04-29
      • 2014-10-21
      • 1970-01-01
      • 2019-06-19
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 2017-06-10
      • 2014-01-01
      相关资源
      最近更新 更多