递归与在Common Lisp中使用”apply”的比较?

huangapple go评论65阅读模式
英文:

Recursion vs apply in Common Lisp?

问题

当我阅读代码以学习目的时,我经常看到这样的函数:

(defun min-list (lst)
  (cond ((endp (rest lst)) (first lst))
	(t
	 (min (first lst) (min-list (rest lst))))))

如果我在我的项目中编写这个函数,我会使用 apply 来写:

(defun min-list2 (lst)
  (cond ((endp (rest lst)) (first lst))
	(t
	 (apply #'min lst)))))

当我使用 time 测试这两种变体时,它们似乎执行相同。

这有关系吗?

英文:

When I am reading code for learning purposes, I often see functions like this:

(defun min-list (lst)
  (cond ((endp (rest lst)) (first lst))
	(t
	 (min (first lst) (min-list (rest lst))))))

If I were writing this function in my project, I would have written it with apply.

(defun min-list2 (lst)
  (cond ((endp (rest lst)) (first lst))
	(t
	 (apply #'min lst))))))

When I test these two variations with time, they seem to perform the same.

Does it matter?

答案1

得分: 7

他们使用不同的风格,有不同的限制。

递归变体,如所示,受堆栈空间的限制(如果列表太长,将在某个时候导致堆栈溢出)。可以重写它以使其成为尾递归,大多数CL实现将优化为几乎不增长堆栈的循环,但对于可移植代码来说并不保证。

apply 变体受 call-arguments-limit 限制,根据标准,它至少保证为50,尽管大多数实现都要高得多。通常最好明确使用 reduce 代替。

另一种也是惯用的解决方案是直接使用 loopdo 或某些库,如 iteratefor 进行循环,这些通常是性能最好的(在需要性能的情况下)。

英文:

They use different styles with different limitations.

The recursion variant, as it is written there, is limited by the space for the stack (you get a stack overflow at some point if the list is too long). It is possible to rewrite it to be tail recursive, which in most CL implementations will be optimized to more-or-less a loop that doesn't grow the stack, but that's not guaranteed for portable code.

The apply variant is limited by call-arguments-limit, which is only guaranteed to be at least 50 by the standard, although most implementations have it much higher. It is usually better to explicitly use reduce instead.

Another, also idiomatic, solution is direct looping using loop, do, or some library such as iterate or for, and these are usually the most performant (in situations where that matters).

huangapple
  • 本文由 发表于 2023年6月19日 18:40:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76505835.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定