Exit Recur Loop in Clojure

旧街凉风 提交于 2020-01-13 19:01:11

问题


I'd like break out of the below loop and return the best-min-move when line 10 evaluates to true. I've looked at the output with print statements and when line 10 does evaluate to true, it finds the data that I'm looking for but continues to recur. In Clojure is there a way to stop the loop when a statement evaluates to true? Or should I be using something other than a loop recur?

(defn minimax [board max-mark min-mark depth best-score] 
  (loop [board board
     max-mark max-mark
     min-mark min-mark
     depth depth
     best-score best-score]
  (if (= best-score (best-min-score board max-mark min-mark depth))
   (best-max-move board max-mark min-mark depth)                     
   (do                                                               
      (if (= best-score (best-min-score board min-mark max-mark depth))
       (best-min-move board min-mark max-mark depth)              
       (recur 
         (b/make-move-on board (remaining-scores board max-mark min-mark depth) max-mark)                
           min-mark 
           max-mark 
           (inc depth) 
           (dec best-score)))))))

回答1:


About loop

  • It's not loop that loops: it's recur.
  • loop is a let that forms a recur point.
  • You don't and can't break out of a loop: recur breaks you into one.

loop is equivalent to setting up and calling an anonymous function. For example

(loop [n 5, s "Hello, world!"]
  (if (zero? n)
    (first s)
    (recur (dec n) (rest s))))

... is equivalent to

((fn [n s]
  (if (zero? n)
    (first s)
    (recur (dec n) (rest s))))
 5 "Hello, world!")

With some loss of performance, loop could have been written as a macro that carries out the above transformation.


As for your code:

There are six undefined functions here. To clear compilation, we

(declare best-min-score 
         best-max-move
         best-min-move
         best-max-move
         make-move-on
         remaining-scores)

There are also two redundant forms. These do no active harm but do obscure the code.

  • The loop is not needed: the function itself is a suitable target for recur.
  • The do does nothing: it encloses a single form.

Your function reduces to

(defn minimax [board max-mark min-mark depth best-score] 
  (if (= best-score (best-min-score board max-mark min-mark depth))
    (best-max-move board max-mark min-mark depth)
    (if (= best-score (best-min-score board min-mark max-mark depth))
      (best-min-move board min-mark max-mark depth)              
      (recur 
       (make-move-on board (remaining-scores board max-mark min-mark depth) max-mark)                
       min-mark 
       max-mark 
       (inc depth) 
       (dec best-score)))))

Whereas any of the undefined functions may be recurring, the best bet is best-min-move.



来源:https://stackoverflow.com/questions/26412033/exit-recur-loop-in-clojure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!