Clojure循环/复发模式,使用不好?

RGr*_*run 3 clojure

我正在学习Clojure,我正在使用4Clojure 作为资源.我可以解决网站上的许多"简单"问题,但对于我来说,在函数式编程思维中思考仍然不自然(我来自Java).因此,我在大多数seq构建实现中使用循环/重复迭代模式,因为这是我以前的思考方式.

但是,当我看到更有经验的Clojure用户的答案时,他们会以更实用的方式做事.例如,在实现范围函数的问题中,我的答案如下:

(fn [start limit]
  (loop [x start y limit output '()]
    (if (< x y)
      (recur (inc x) y (conj output x))
      (reverse output))))
Run Code Online (Sandbox Code Playgroud)

虽然这有效,但其他用户做了这样的事情:

(fn [x y] (take (- y x) (iterate inc x)))

我的功能更冗长,我不知道甚至存在"迭代"功能.但是从效率的角度来看,我的回答是否更糟?循环/重复使用比替代品更糟糕吗?我担心将来会发生很多这样的事情,因为还有许多函数,比如我不知道的迭代.

fja*_*rri 5

第二个变体返回一个惰性序列,这可能确实更有效,特别是如果范围很大.

另一件事是第二种解决方案更好地传达了这个想法.换句话说,它描述了意图而不是实现.与您的代码相比,它需要更少的时间来理解它,您必须通过循环体读取并在头脑中构建控制流模型.

关于新功能的发现:是的,您可能事先不知道已经定义了某些功能.在Haskell中更容易,你可以通过它的类型签名搜索函数,但是通过一些经验,你将学会识别像这样的函数式编程模式.你会写这样的第二个变体的代码,然后找东西那样工作takeiterate标准库.