Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

clojure - Best way to use recur loop


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The code that you already suggest is great, except for the complexity of nth as pointed out by @amalloy (which can be addressed by turning the lazy sequence into a vector). The loop is a fundamental building block for looping. However, when looping, sequences are often involved and there are many functions for constructing sequences and expressing algorithms on sequences. Knowing these functions can save you some time and to some extent make algorithms simpler or more concise.

Here is alternative way of expressing your algorithm. You can construct a lazy sequence of variance by starting from an initial variance and iterate division by 2.

Here is an example of a sequence of length 7 with an initial variance of 3:

(take 7 (iterate #(/ % 2) 3))
;; => (3 3/2 3/4 3/8 3/16 3/32 3/64)

We can now pass a sequence constructed in this way to reduce to express the loop.

(defn deforms2 [points depth variance]
  (reduce (comp vec deform)

          ;; Initial value
          (vec points)

          ;; Sequence of variances that we reduce over
          (take depth (iterate #(/ % 2) variance))))

This code is slightly different from your initial code, in that no deformation takes place if depth has the value 0:

(= pts (deforms2 pts 0 my-variance))
;; => true

The equivalent modification of the original code would mean to initialize the looping variable np with points instead of (deform points variance), making things more intuitive, in my opinion.

The reduce function does two things for you when expressing an iterative algorithm:

  1. It stops the looping when the input sequence is empty.
  2. It steps to the next element of the input sequence at every iteration.

In other words, you don't have to worry about those two concerns meaning less risk of bugs. It is similar in philosophy to foreach loops found in other languages.

Note also that I reduce using (comp vec deform) instead of just deform. This is a quick fix (not necessarily an optimal fix) to address the complexity of indexing operations, as pointed out by @amalloy.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...