Q: is there a predicate function for dotted pairs?

In other words, is there a function that distinguishes between dotted pairs and 2-element proper lists:

(some-predicate-p '(a . b))             ; => t
(some-predicate-p '(a   b))             ; => nil

The broader context: I need to access the second element of a pair of values, and would like the function to "do the right thing" when it's fed either a dotted pair or a 2-element proper list:

(cdr  '(a . b))                           ; => b
(cadr '(a   b))                           ; => b

Since cdr and cadr cannot be dropped in interchangeably between proper and improper lists:

(cadr '(a . b))                           ; => error
(cdr  '(a   b))                           ; => (b)
  • (and (cdr x) (atom (cdr x))) FWIW, this is a duplicate of this StackOverflow question, except that here you are testing only one cons.
    – Drew
    Apr 3, 2015 at 17:08

3 Answers 3


Here is a simple test for a dotted pair (your question):

(and (cdr x) (atom (cdr x)))

And here is a test for a dotted list (of any length):

(let ((last  (last x))) (and (cdr last) (atom (cdr last))))

Got it: helped along by @abo-abo's answer, the following predicate function detects dotted pairs:

(defun dotted-p (x)
  "Returns `t' if X is a dotted-pair."
  (not (consp (cdr x))))

(dotted-p '(a . b))                     ; => t
(dotted-p '(a   b))                     ; => nil
  • 3
    The only issue I could see here is that '(a . nil) be considered a dotted pair when really it just a 1 element proper list (equivilant to '(a)), If you wanted to account for this, and also for full type safety, you could use this is your function body (and (consp x) (cdr x) (not (consp (cdr x)))) Apr 3, 2015 at 14:24
  • 1
    @JordonBiondo: good point on the edge case. I think, for my specific use, I'd want to leave it as is, but the more general case should probably work as you're suggesting.
    – Dan
    Apr 3, 2015 at 14:26
  • I disagree. (cons a nil) is by definition a dotted pair, even though it can also be regarded as a one-element list. But I would certainly include the (consp x) condition as suggested by @JordonBiondo.
    – tripleee
    Apr 10, 2015 at 10:09

There isn't such a function to my knowledge, but you can use something like this:

(defun codr (x)
  (let ((y (cdr x)))
    (if (consp y)
        (car y)

But it's better to just know what kind of data you're expecting.

  • Thanks, although this function return the same value (b) when used on either a dotted-pair or a proper list: (codr '(a b)) => b and (codr '(a . b)) => b. Still, +1 because it pointed me in the right direction.
    – Dan
    Apr 3, 2015 at 13:57
  • And I agree that it's better to know the type of data to expect, but it's for end-user use and I'd like to allow people to use either version as their tastes dictate.
    – Dan
    Apr 3, 2015 at 14:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.