惯用语Clojure

时间:2014-05-29 14:32:30

标签: clojure coding-style

我大约一周参加Clojure和一般的函数式编程 - 我的所有背景都在OOP中。我想充分利用Clojure的易读性和内在逻辑,但现在我不知道我是否成功地做到了这一点并且没有把我的思想包裹在它周围完全,或者如果我真的以一种糟糕的方式滥用语言。

例如:

(ns waterfall-quiz.response-parser
  (:require [clojure.java.io :as io]))

(defn process-input
  [input]
  (finalize-input
    (normalize-height
      (map-input
        (numberize-vector
          (vectorize-input
            (clean-input input)))))))

(defn clean-input
  "Removes extraneous whitespace."
  [input]
  (clojure.string/replace input #"\s+" " "))

(defn vectorize-input
  "Turns input into a vector."
  [input]
  (clojure.string/split input #"\s"))

(...)

我非常怀疑进程输入函数,它调用所有其他函数来格式化一些输入。它是引用透明的,但它看起来很脆弱 - 是否有更智能的方法将所有功能链接在一起?

另一个例子:

(defn map-builder
  "Transforms the vector of waterfalls into a map of waterfalls."
  [vectorized-db]
  (assoc waterfall-db
  (keyword (str 'waterfall (first (re-seq #"[0-9]+" (str (first vectorized-db))))))
  (subs (str (first vectorized-db)) (+ 2 (.indexOf (str (first vectorized-db)) ":")))))

在编写该功能时,我不断地在括号中忘记了我的位置 - 它应该被分解为更小的功能吗?

1 个答案:

答案 0 :(得分:8)

最能改善代码的两个惯用工具Clojure是let->宏。

let允许您逐步构建本地绑定

->以更易读和更易编辑的形式将一系列函数调用链接在一起

(defn process-input
  [input]
  (-> input
      clean-input
      vectorize-input
      numberize-vector
      map-input
      normalize-height
      finalize-input))

(defn map-builder
  "Transforms the vector of waterfalls into a map of waterfalls."
  [waterfall-db vectorized-db]
  (let [key-str (str (first vectorized-db))
        key (->> key-str
                 (re-seq #"[0-9]+")
                 first
                 (str 'waterfall)
                 keyword)
        val (subs key-str (+ 2 (.indexOf key-str ":")))]
    (assoc waterfall-db key val)))

我还冒昧地将waterfall-db作为地图构建器的arg,以便在功能代码中更容易使用(可能借助于swap!reduce或{ {1}})。