# Predicate function for dotted pairs?

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 '15 at 17:08

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
``````
• 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))))` – Jordon Biondo Apr 3 '15 at 14:24
• @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 '15 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 '15 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)
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 '15 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 '15 at 14:00