【问题标题】:Idiomatic Clojure惯用的 Clojure
【发布时间】:2014-05-29 14:32:30
【问题描述】:

我大约有一周的时间学习 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"))

(...)

我很怀疑 process-input 函数,它调用所有其他函数来格式化一些输入。它在引用上是透明的,但看起来很脆弱——有没有更聪明的方法将所有功能链接在一起?

另一个例子:

(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)) ":")))))

在编写该函数时,我经常忘记括号中的位置——是否应该将其分解为更小的函数?

【问题讨论】:

  • 我建议你把这个帖子移到codereview.stackexchange.com
  • (finalize-input (normalize-height (map-input (numberize-vector (vectorize-input (clean-input input))))))(-> input clean-input vectorize-input numberize-vector map-input normalize-height finalize-input) 相同,但后者更易于阅读和修改。
  • 迈克,看看 4clojure.com。尝试至少浏览所有简单和中等示例,并查看前 10 名玩家的解决方案(不是我的!)。

标签: clojure coding-style


【解决方案1】:

最能改进代码的两个惯用工具 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 设为 map-builder 的 arg,以便可以更轻松地在函数式代码中使用它(也许在 swap!reduceupdate-in 的帮助下)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-29
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 2012-05-13
    • 2014-01-21
    • 2015-12-19
    相关资源
    最近更新 更多