Common Lisp的LOOP和Iterate有什么区别?

时间:2015-11-16 20:30:50

标签: loops common-lisp

Common Lisp内置了一个强大的Loop宏。它非常实用且功能强大,而且我经常使用它。

我也听说过一个非常类似的东西,名为Iterate。它看起来与Loop非常相似,但它有更多的Lispy感觉。这两者有什么不同?除了简单的风格偏好外,是否有任何理由可以改用其中任何一种?

1 个答案:

答案 0 :(得分:0)

iterate 的一些独特之处:

子句没有严格的顺序

loop 要求所有 for 子句都出现在循环体之前,例如 while 之前。 iter 没问题:

(iter (for x in '(1 2 99)
  (while (< x 10))
  (for y = (print x))
  (collect (list x y)))

累积子句可以嵌套

collectappending 等可以出现在任何地方:

(iter (for x in '(1 2 3))
  (case x
    (1 (collect :a))
    (2 (collect :b))))

finding

;; Finding the longest list in a list of lists:
(iter (for lst in '((a) (b c d) (e f)))
      (finding lst maximizing (length lst)))
=> (B C D)

;; The rough equivalent in LOOP:
(loop with max-lst = nil
      with max-key = 0
      for lst in '((a) (b c d) (e f))
      for key = (length lst)
      do
      (when (> key max-key)
        (setf max-lst lst
              max-key key))
      finally (return max-lst))
=> (B C D)

https://common-lisp.net/project/iterate/ 第一个例子

求一个区间内x^2 - 4x + 1的最小值:

(iter (for x from -5 to 5 by 1/100)
      (finding x minimizing (1+ (* x (- x 4)))))
2

©Common Lisp 食谱第 198 页

next-iteration

它就像“继续”而循环没有它。

iter 也有 first-iteration-p(if-first-time then else)

https://web.archive.org/web/20170713081006/https://items.sjbach.com/211/comparing-loop-and-iterate

发电机

generatenext。生成器是惰性的,当明确指出时,它会转到下一个值。

(iter (for i in '(1 2 3 4 5))
      (generate c in-string "black")
      (if (oddp i) (next c))
      (format t "~a " c))
b b l l a 
NIL

https://sites.google.com/site/sabraonthehill/loop-v-iter

previous

(iter (for el in '(a b c d e))
      (for prev-el previous el)
      (collect (list el prev-el)))
=> ((A NIL) (B A) (C B) (D C) (E D))

虽然可以通过loop的并行绑定and实现:

(loop for el in '(a b c d e)
      and prev-el = nil then el  
      collect (list el prev-el))

更多条款

in-string

<块引用>

LOOP 提供收集、nconcing 和附加功能。 ITERATE 具有这些以及 adjoiningunioningnunioningaccumulating

(iter (for el in '(a b c a d b))
      (adjoining el))
=> (A B C D)

adjoin 是一个集合操作)

LOOP 有求和、计数、最大化和最小化。 ITERATE 还包括 multiplyingreducing。减少是广义的减少构建器:

(iter (with dividend = 100)
      (for divisor in '(10 5 2))
      (reducing divisor by #'/ initial-value dividend))
=> 1

https://web.archive.org/web/20170713105315/https://items.sjbach.com/280/extending-the-iterate-macro

它是可扩展的

(defmacro dividing-by (num &keys (initial-value 0))
  `(reducing ,num by #'/ initial-value ,initial-value))
 
(iter (for i in '(10 5 2))
      (dividing-by i :initial-value 100))
=> 1

但还有更多。

https://common-lisp.net/project/iterate/doc/Rolling-Your-Own.html#Rolling-Your-Own

https://web.archive.org/web/20170713105315/https://items.sjbach.com/280/extending-the-iterate-macro 在附录中,我们看到两个 loop 扩展示例。但它们真的不可移植,代码中充满了#+(or allegro clisp-aloop cmu openmcl sbcl scl) (ansi-loop::add-loop-path …sb-loop::add-loop-path

迭代中缺少的东西

没有像循环的 and 那样的并行绑定,而是 not needed?

我可能在这里失踪了。


但这还不是全部,还有更多不同之处。