2
votes

I've just started learning Racket and I have to check if an argument is a dotted pair.

I have tried this:

(pair? '(a . 1))

And returns #t.

(pair? '('(a b c) . 1))

And returns #t.

(pair? '(a b c))

And returns #t. But I want to get #f in this case.

Is there another procedure like pair? to get true only when I pass it as argument a dotted pair?

Maybe I will have to implement a procedure that check if it is not a list before I check if it is a pair.

UPDATE
I only need to check that '(a . 1) is a dotted pair and any list is not a dotted pair.

2
(not (list? lst)) should do itleppie
@leppie But that would return #t for '(1 2 . 3) as well. I believe the author is looking for dotted pairs only.merlyn
@merlyn But (1 2 . 3) is (1 . (2 . 3)), a dotted pair.molbdnilo

2 Answers

4
votes

If we are pedantic a dotted pair is nothing more than a notation, a way to write a pair. The expression ’(a . d) evaluates to value namely a cons cell.

When a function is applied to some arguments, the arguments are values. This means that a function can not receive a dotted pair - it can receive a cons cell.

Okay - but can a function know whether a value is a cons cell or a list? Depends on what you mean. A list is represented as either null (the empty list) or as a cons cell, whose second element is a list.

The predicate pair? will therefore return true for all lists (except the empty list). Now we can check that a cons cell is not the first cons cells of a list by writing (and (pair? x) (not (list? x))).

3
votes

I am not aware of a built-in function to filter dotted pairs. But implementing one should be simple. Just check if the argument is a list with more than one element and that cdr of the list is not a pair itself.

Here's a sample implementation.

(define (not-list-dotted-pair? x)
  (and
    (pair? x)
    (not (null? (cdr x)))
    (not (pair? (cdr x)))))