tags:

views:

552

answers:

5

I have a function that takes a list that either has two or three elements.

;; expecting either ((a b c) d) or ((a b c) d e)
(define (has-third-item ls)
      (if (null? (caddr ls))
          false
          true)
      )

But this code fails with

mcar: expects argument of type <mutable-pair>; given ()

on the (null? (caddr ls)) expression.

I also tried

(eq? '() (caddr ls))

but it didn't work either. How do I tell if there's a third item or not?

+8  A: 

You don't want caddr, you want (if (null? (cddr ls)) ... Or just use length to find the length of the list, and compare it to the value you're interested in.

The '() that terminates a list will always be in the cdr position of a pair, so looking for it in the car position (which cad+r will do) isn't going to be productive.

Jay Kominek
+4  A: 

The problem is that if you have a list with two or fewer items, you can't take the caddr of it. Try this:

(define (has-third-item lst)
  (<= 3 (length lst)))

There could be some cases where taking the length of the list can be inefficient (such as the list containing millions of items); in this case, we can test to see if the list has length zero, one, or two by hand:

(define (has-third-item lst)
  (not (or (null? lst)
           (null? (cdr lst))
           (null? (cddr lst)))))

edit: Regarding the two other answers, while taking the cddr may work in this case as the input domain consists of list with either two or three elements, has-third-item would still fail for lists with zero or one. In the interest of generality, I suggest going with a solution that works for any domain.

Kyle Cronin
+1  A: 

Provided you know your list has either two or three elements (as you say it has), you can do

(define (has-third-item? l)
  (not (null? (cddr l))))

You're checking whether the second cons cell (cddr l) has a cdr or not. You don't have to check whether l itself is null or l has only one element, unless you want a more generic function.

Fabien
A: 

try...

(and l (cdr l)(cddr l))
Mike Dunlavey
A: 

Why not use (third ls)

Will return the third element or NIL if none is present.

John McAleely