As nuntius says, your code is failing in the T condition of the cond clause when processing '(2 3). Your code says (cons (rdouble '(2 3)) (cons '(2 3) (rdouble -the-rest-))).
Code: Select all
(t (cons (rdouble (car struct)) (cons (car struct)
(rdouble (cdr struct))
Its interesting to see that in this clause you call rdouble on the first (car struct), but not on the second. Its sort of like you believe its an atom, but you're not willing to commit. If you were convinced that (car struct) was an atom, you could just write: (list* (car struct) (car struct) (rdouble (cdr struct))).
The case of (listp (car struct)) is different... because you DO recurse with rdouble ... but you actually don't want two results. Otherwise (list* (rdouble (car struct)) (rdouble (car struct)) (rdouble (cdr struct))) would work for both cases.
Code: Select all
(defun rdouble (i)
(unless (null i)
(if (listp (car i))
(cons (rdouble (car i)) (rdouble (cdr i)))
(list* (car i) (car i) (rdouble (cdr i))))))
(rdouble '(1 2 3)) ==> (1 1 2 2 3 3)
(rdouble '(1 (2 3) 4)) ==> (1 1 (2 2 3 3) 4 4)
(rdouble '(1 (2 3 (4 5)) 6)) ==> (1 1 (2 2 3 3 (4 4 5 5)) 6 6)
I wrote a accumulator-style version of this. I actually wrote it first, because being able to just dump two copies of the value onto an accumulation list just appealed to me.
Code: Select all
(defun rdouble (acc i)
(when (null i) (return-from rdouble (nreverse acc)))
(if (listp (car i))
(rdouble (cons (rdouble nil (car i)) acc) (cdr i))
(rdouble (list* (car i) (car i) acc) (cdr i))))
(rdouble nil '(1 2 3)) ==> (1 1 2 2 3 3)
(rdouble nil '(1 (2 3) 4)) ==> (1 1 (2 2 3 3) 4 4)
(rdouble nil '(1 (2 3 (4 5)) 6)) ==> (1 1 (2 2 3 3 (4 4 5 5)) 6 6)