XPost: comp.lang.scheme
Gareth McCaughan wrote:
It's not a better algorithm. The point is that because it's
more concise you are less likely to get lost in details, and
therefore more likely to be able to spot algorithmic improvements.
If you write
(loop for x from a to b by d collect x)
rather than
(do ((j a (+ j d))
(result nil))
((>= j b) (nreverse result))
(push j result))
Bad. Very bad.
(do ((x 20 (+ x 2))
(r '() (cons x r)))
((> x 30) (reverse r)))
===>
(20 22 24 26 28 30)
Shorter:
(do ((x 30 (- x 2))
(r '() (cons x r)))
((< x 20) r))
And is "nreverse" actually faster than "reverse"?
On page 222 in "ANSI Common Lisp" Paul Graham writes:
"In Lisp implementations with bad garbage collectors, programs that
cons a lot tend to run slowly. Until recently, most Lisp
implementations have had bad garbage collectors, and so it has become
a tradition that efficient programs should cons as little as possible.
Recent developments have turned this conventional wisdom on its head.
Some implementations now have such sophisticated garbage colletors
that it is faster to cons up new objects and throw them away than it
is to recycle them."
then
- it's about half as much code, and 1/4 as many lines with
most people's indentation conventions;
- it's therefore twice as fast to type
- it takes quite a lot less than half as long to *write*
(or at least it does for me; I found that I had to think
for the best part of a second at a couple of places while
writing the iterative version)
- it's quicker to read
Testing:
(loop for x from 20 to 30 by 2 collect x)
(20 22 24 26 28 30)
Shorter:
Gauche Scheme
Function: unfold end-test key gen-next-seed seed
(use srfi-1) ;; unfold
;; pa$ is partial application (currying).
;; Using + for identity.
(unfold (pa$ < 30) + (pa$ + 2) 20)
===>
(20 22 24 26 28 30)
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)