cons
build pairs, not lists. Lisp interpreters uses a ‘dot’ to visually separate the elements in the pair. So (cons 1 2)
will print (1 . 2)
. car
and cdr
respectively return the first and second elements of a pair. Lists are built on top of pairs. If the cdr
of a pair points to another pair, that sequence is treated as a list. The cdr
of the last pair will point to a special object called null
(represented by '()
) and this tells the interpreter that it has reached the end of the list. For example, the list '(a b c)
is constructed by evaluating the following expression:
> (cons 'a (cons 'b (cons 'c '()))) (a b c)
The list
procedure provides a shortcut for creating lists:
> (list 'a 'b 'c) (a b c)
The expression (cons '(a b c) '())
creates a pair whose first element is a list.
Your remove-dup
procedure is creating a pair at the else
clause. Instead, it should create a list by recursively calling remove-dup
and putting the result as the second element of the pair. I have cleaned up the procedure a bit:
(define (remove-dup lst) (if (>= (length lst) 2) (if (eq? (car lst) (cadr lst)) (cons (car lst) (remove-dup (cddr lst))) (cons (car lst) (remove-dup (cdr lst)))) lst))
Tests:
> (remove-dup '(a b c)) (a b c) > (remove-dup '(a a b c)) (a b c) > (remove-dup '(a a b b c c)) (a b c)
Also see section 2.2 (Hierarchical Data and the Closure Property) in SICP.
For completeness, here is a version of remove-dup
that removes all identical adjacent elements:
(define (remove-dup lst) (if (>= (length lst) 2) (let loop ((f (car lst)) (r (cdr lst))) (cond ((and (not (null? r))(eq? f (car r))) (loop f (cdr r))) (else (cons (car lst) (remove-dup r))))) lst))
I have read so many posts about the blogger lovers however this post is really a good piece of writing, keep it up
whoah this blog is wonderful i really like reading your articles. Keep up the great paintings! You realize, a lot of people are hunting round for this info, you could help them greatly.