Re: remove all occurence of list
- From: Lauri Alanko <la@xxxxxx>
- Date: 7 Feb 2006 20:14:17 GMT
In article <43E8ED61.5D7DB104@xxxxxxxxxxxxx>,
Andre <andre@xxxxxxxxxxxxx> wrote:
This statement is often repeated, but it is not necessarily true. From the
reference implementation of SRFI-1 (Olin Shivers):
;;; A note on recursion and iteration/reversal:
;;; Many iterative list-processing algorithms naturally compute the elements
;;; of the answer list in the wrong order (left-to-right or head-to-tail) from
;;; the order needed to cons them into the proper answer (right-to-left, or
;;; tail-then-head). One style or idiom of programming these algorithms, then,
;;; loops, consing up the elements in reverse order, then destructively
;;; reverses the list at the end of the loop. I do not do this. The natural
;;; and efficient way to code these algorithms is recursively. This trades off
;;; intermediate temporary list structure for intermediate temporary stack
;;; structure. In a stack-based system, this improves cache locality and
;;; lightens the load on the GC system. Don't stand on your head to iterate!
;;; Recurse, where natural.
I don't buy this. Traversing lists tail-recursively is not only an
efficiency issue, it's about limiting your stack space requirements.
Although nowadays platforms are much more flexible about the amount of
stack space available, I still don't think it's a good idea to use
stack in a linear proportion to the length of an arbitrary list.
Moreover, if the list-traversal function captures a continuation (as
is quite possible if it e.g. calls a callback that happens to call
call/cc), then the recursive approach may be much more expensive if
call/cc is implemented by copying the entire stack. If heap were used
(as in the iterative approach), then the context would be shared and
not copied automatically.
Finally, I note that the reference implementation for SRFI-1 uses the
recursive solution even when returning multiple values, resulting in
the style I just questioned in a previous post:
(define (span pred lis)
(check-arg procedure? pred 'span)
(let recur ((lis lis))
(if (null-list? lis) (values '() '())
(let ((x (car lis)))
(if (pred x)
(receive (prefix suffix) (recur (cdr lis))
(values (cons x prefix) suffix))
(values '() lis))))))
For this to be really efficient over the iterative solution, the
multiple return values should be returned directly in the stack
without doing heap allocations.
In short, Shivers' approach puts too many constraints on the
implementation for it to be useful as a general rule of thumb in
Scheme programming.
Lauri
.
- Follow-Ups:
- Re: remove all occurence of list
- From: Marcin 'Qrczak' Kowalczyk
- Re: remove all occurence of list
- From: Abdulaziz Ghuloum
- Re: remove all occurence of list
- References:
- remove all occurence of list
- From: seb
- Re: remove all occurence of list
- From: netytan
- Re: remove all occurence of list
- From: netytan
- Re: remove all occurence of list
- From: Andre
- remove all occurence of list
- Prev by Date: Re: Learning Scheme
- Next by Date: Re: women in comp sci
- Previous by thread: Re: remove all occurence of list
- Next by thread: Re: remove all occurence of list
- Index(es):
Relevant Pages
|