让膨胀或惯用的clojure?

时间:2013-10-21 10:54:41

标签: clojure idiomatic

对clojure不熟悉我很难为不同的代码构造找到一种惯用的风格。

在某些情况下,我的let绑定包含函数的大部分代码。这种臃肿,对clojure哲学或惯用的一些误解还不错?

这是一个示例测试用例。它测试添加/获取往返某个存储库的往返。长期看起来很奇怪吗?

(deftest garden-repo-add-get
  (testing "Test garden repo add/get"
    (let [repo (garden/get-garden-repo)
          initial-garden-count (count (.list-gardens repo))
          new-garden (garden/create-garden "Keukenhof")
          new-garden-id (.add-garden repo new-garden)
          fetched-garden (.get-garden repo new-garden-id)]
      (is (= (+ initial-garden-count 1) (count (.list-gardens repo))))
      (is (= (.name new-garden) (.name fetched-garden))))))

3 个答案:

答案 0 :(得分:3)

我使用let代码看到的主要问题,通常情况下,您使用的是许多中间变量,这些变量只有名称才能存在于let form中。

避免过度使用的最佳方法是使用箭头宏->->>

例如,您可以使用

避免使用repo中间变量
initial-garden-count (-> (garden/get-garden-repo)
                         (.list-gardens)
                         count)

尽管如此,在您的特定情况下,您在测试验证中使用 all 您的中间变量,因此无论如何您都需要在let语句中使用它们。也许new-garden-id是唯一可以避免的中间人:

fetched-garden (->> (.add-garden repo new-garden)
                    (.get-garden repo))

或者使用Chiron建议的方法:

fechted-gaden (.get-garden repo (.add-garden repo new-garden))

答案 1 :(得分:2)

就个人而言,这就是我在Clojure中编码的方式。 Clojure简洁,优雅,简洁 我不认为通过压缩以下将是"惯用"。

  (is (= (+ (count (.list-gardens repo)) 1) (count (.list-gardens (garden/get-garden-repo)))))

您的代码片段更易于理解,可以测试调试(在Eclipse中,IntelliJ ..)。

Clojure是关于简单性的,我想保持这种方式。

尽管如此,你的问题的答案仍然高度自以为是。

答案 2 :(得分:0)

通过查看你的函数代码,似乎函数正在使用的“东西”是具有getter / setter和方法的典型OO对象(参见有很多。{something}调用),这使你可以使用这些绑定因为对象API的设计方式。如果你必须使用对象,这很好。

在Clojure中,你基本上围绕数据结构设计你的API,比如map / vector / list / set和functions,这些(在大多数情况下)为你提供了一种API,它可能不需要那么多的绑定使用。