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
- Next message: Ray Dillinger: "Re: Scheme macros"
- Previous message: Barry Margolin: "Re: DEFUN list argument"
- In reply to: David Sletten: "Re: is there a more concise or efficient way to code this fn ?"
- Next in thread: Pascal Costanza: "Re: is there a more concise or efficient way to code this fn ?"
- Reply: Pascal Costanza: "Re: is there a more concise or efficient way to code this fn ?"
- Reply: Marcus Breiing: "Re: is there a more concise or efficient way to code this fn ?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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.
- Next message: Ray Dillinger: "Re: Scheme macros"
- Previous message: Barry Margolin: "Re: DEFUN list argument"
- In reply to: David Sletten: "Re: is there a more concise or efficient way to code this fn ?"
- Next in thread: Pascal Costanza: "Re: is there a more concise or efficient way to code this fn ?"
- Reply: Pascal Costanza: "Re: is there a more concise or efficient way to code this fn ?"
- Reply: Marcus Breiing: "Re: is there a more concise or efficient way to code this fn ?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|