Re: is there a more concise or efficient way to code this fn ?

From: Tayssir John Gabbour (tayss_temp2_at_yahoo.com)
Date: 03/10/04


Date: 9 Mar 2004 23:40:05 -0800

David Sletten <david@slytobias.com> wrote in message news:<Nwe3c.18392$rD5.4263@twister.socal.rr.com>...
> Lowell Kirsh wrote:
> > My code is below - it works fine, but I have a gut feeling it could be
> > better, especially in its readability.
> >
> > (defun remove-consecutives (list &optional (test #'eql))
> > "Remove consecutive elements of a list.
> > i.e. (remove-consecutives '(0 0 1 2 2 3)) => (0 1 2 3)"
> > (labels ((help (list acc)
> > (cond ((null list)
> > (nreverse acc))
> > ((funcall test (car list) (car acc))
> > (help (cdr list) acc))
> > (t
> > (help (cdr list) (cons (car list) acc))))))
> > (help (cdr list) (list (car list)))))
>
> Your code is fine and no less concise than any recursive version I can
> think of. The alternatives that others have suggested are probably more
> efficient (as well as being quite concise) since they are
> iterative--unless you know that your compiler is properly tail-recursive
> (you have written it correctly to take advantage of tail recursion, but
> Common Lisp doesn't guarantee that a compiler will cooperate).

I personally would use this to bang out code, but I know it's not the
sort of thing common lispers love...

(defun remove-consecutives (list &optional (test #'eql))
  (fold-right (lambda (item accum)
                (if (and (consp accum)
                         (funcall test item (first accum)))
                    accum
                    (cons item accum)))
              list))

Where fold-right is predefined in my environment as...

(defun fold-right (fun list &optional (init nil))
  "f(x1, f(x2, ... f(xn, init)))"
  (if (null list)
      init
      (funcall fun (car list)
                   (fold-right fun (cdr list) init))))

A couple test cases check out...

(equal '(0 1 2 3 nil)
       (remove-consecutives '(0 0 1 2 2 3 nil)))

(equal '(0 1 2 3 nil)
       (remove-consecutives '(0 0 1 2 2 3 nil nil)))

(equal '(nil 0 1 2 3 nil)
       (remove-consecutives '(nil nil 0 0 1 2 2 3 nil nil)))

After all, why explicitly accumulate a data structure when lisp
already has a nice invisible function stack? ;) Seriously, Duane
Rettig kindly explains the tradeoffs in
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=4u14u8ejg.fsf%40franz.com

But I am an arrogant codemonkey who does not think the rules apply to
him. Of course I would likely not do this if I were responsible for
someone else's needs. However, lisp represents for me a liberation
for my personal uses, and I would not use it if I had to tiptoe around
some compiler in order to create the best notation. My real version
of fold-right even uses the "nil?" macro because "null" is too
irregular and I won't put up with that crap.



Relevant Pages

  • Re: Making Lisp popular - can it be done?
    ... “hack” for recursion. ... We already have to think about how to do tail ... (recur (dec n) ... experience with implementing Lisp, ...
    (comp.lang.lisp)
  • Re: kernel stack challenge
    ... > infinite loop, and eventually ... Separate logical copy of LISP program is for each ... subsystem we protect. ... > recursion is at all interesting or useful.... ...
    (Linux-Kernel)
  • Re: How to make mod_lisp faster than php?
    ... In the Lisp group, the first fellow will answer, "I know my opinion, ... There seem to be various levels of acceptance of deep recursion ... It's possible that Scheme is here because a standard implementation of call/cc which puts stack frames on the heap yields this property. ... I think that implies tail recursion, ...
    (comp.lang.lisp)
  • Re: Program compression
    ... problems to be solved much more concisely than with Lisp. ... is competitively concise. ... let's say you have a text string which contains the notation ...
    (comp.programming)
  • Re: Beginners Question on an exercise from Grahams ACL
    ... > just been taught and to exercise my brain on them - not with some other ... Recursion might be more worthwhile as a separate item to learn, ... than binding up lisp and recursion into a single package of pain. ... Alternate places than lisp materials might teach it better, ...
    (comp.lang.lisp)