fox*_*nut 15 groovy functional-programming clojure imperative-programming
好的,现在不要作弊.
不,真的,花一两分钟试试这个.
"职位"有什么作用?
编辑:根据cgrand的建议进行简化.
(defn redux [[current next] flag] [(if flag current next) (inc next)])
(defn positions [coll]
(map first (reductions redux [1 2] (map = coll (rest coll)))))
Run Code Online (Sandbox Code Playgroud)
现在,这个版本怎么样?
def positions(coll) {
def (current, next) = [1, 1]
def previous = coll[0]
coll.collect {
current = (it == previous) ? current : next
next++
previous = it
current
}
}
Run Code Online (Sandbox Code Playgroud)
我正在学习Clojure,我很喜欢它,因为我一直很喜欢函数式编程.我花了更长的时间来提出Clojure解决方案,但我很高兴不得不考虑一个优雅的解决方案.Groovy解决方案没问题,但我发现这种命令式编程很无聊和机械化.经过12年的Java,我觉得Clojure的功能和编程是我需要的提升.
对,明白了.好吧,我必须诚实地说,我想知道我几个月后回到它时是否会理解Clojure代码.当然,我可以评论它,但我不需要评论我的Java代码来理解它.
所以我的问题是:这是一个越来越习惯函数式编程模式的问题吗?函数式编程大师是否正在阅读此代码并轻松理解它?您觉得哪个版本更容易理解?
编辑:这段代码的作用是根据玩家的积分计算玩家的位置,同时跟踪那些被捆绑的玩家.例如:
Pos Points
1. 36
1. 36
1. 36
4. 34
5. 32
5. 32
5. 32
8. 30
Run Code Online (Sandbox Code Playgroud)
Bri*_*per 22
我认为没有固有的可读性.这是你习惯的,你不习惯的.我能够读取您的代码的两个版本.我实际上可以更轻松地阅读你的Groovy版本,即使我不知道Groovy,因为我也花了十年时间研究C和Java,而且只用了一年时间看Clojure.这并没有说明语言,它只是说了一些关于我的事情.
同样地,我比西班牙语更容易阅读英语,但这也没有说明这些语言的内在可读性.(在简单性和一致性方面,西班牙语实际上可能是两者中"更易读"的语言,但我仍然无法阅读它).我现在正在学习日语,并且经历了一段艰难时期,但是日本本土人士对英语也是如此.
如果你一生中大部分时间都在阅读Java,那么看起来像Java的东西比那些没有Java的东西更容易阅读.直到你花了很多时间看Lispy语言看着类似C语言,这可能仍然存在.
要了解某种语言,您必须熟悉以下内容:
[vector]vs. (list),hyphens-in-names)reductions意思?你怎么样/在哪里查找它?)(map first (some set of reductions with extra accumulated values))所有这些都需要时间,练习和重复来学习和内化.但是如果你在接下来的6个月里阅读和撰写大量的Clojure,你不仅可以在6个月后理解Clojure代码,你可能会比现在更好地理解它,甚至可以简化它.这个怎么样:
(use 'clojure.contrib.seq-utils) ;;'
(defn positions [coll]
(mapcat #(repeat (count %) (inc (ffirst %)))
(partition-by second (indexed coll))))
Run Code Online (Sandbox Code Playgroud)
看看我一年前写过的Clojure代码,我对它有多糟糕感到震惊,但我能读得很好.(不是说你的Clojure代码太可怕了;我根本没有阅读它,我不是大师.)
编辑:可能不再相关.
Clojure对我来说很复杂.它包含更多需要理解的抽象.这是使用更高阶函数的代价,你必须知道它们的含义.因此,在一个孤立的案例中,必要性需要较少的知识.但抽象的力量在于它们的组合方式.必须读取和理解每个命令循环,而序列抽象允许您消除循环的复杂性并组合强大的操作.
我进一步争辩说Groovy版本至少部分功能,因为它使用了collect,它实际上是map,一个更高阶的函数.它也有一些状态.
以下是我将如何编写Clojure版本:
(defn positions2 [coll]
(let [current (atom 1)
if-same #(if (= %1 %2) @current (reset! current (inc %3)))]
(map if-same (cons (first coll) coll) coll (range (count coll)))))
Run Code Online (Sandbox Code Playgroud)
这与Groovy版本非常相似,因为它使用了一个可变的"当前",但不同之处在于它没有next/prev变量 - 而是使用不可变序列.正如Brian所说,可读性不是内在的.这个版本是我对这个特殊情况的偏好,似乎坐在中间的某个地方.
我同意蒂莫西的观点:你引入了太多的抽象.我重写了你的代码并以:
(defn positions [coll]
(reductions (fn [[_ prev-score :as prev] [_ score :as curr]]
(if (= prev-score score) prev curr))
(map vector (iterate inc 1) coll)))
Run Code Online (Sandbox Code Playgroud)
关于你的代码,
(defn use-prev [[a b]] (= a b))
(defn pairs [coll] (partition 2 1 coll))
(map use-prev (pairs coll))
Run Code Online (Sandbox Code Playgroud)
可以简单地重构为:
(map = coll (rest coll))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1941 次 |
| 最近记录: |