TheNotMe
TheNotMe

Reputation: 1058

Checking of list of symbols has the dot symbol?

I have a list of the form '(x y . rest) (of the form of lambda with optional number of arguments). I need to check whether I have such a case, but I seem to fail to check that. What I was planning to do is search if . is a member of the list.

> (memq '\. '(x y z . rest))
Exception in memq: improper list (x y z . rest)
Type (debug) to enter the debugger.

> (memq . '(x y z . rest))
Exception: invalid syntax (x y z . rest)
Type (debug) to enter the debugger.

> (memv '\. '(x y z \. rest))
(\x2E; rest) ;this worked but my input is of the form '(x y z . rest) and not '(x y z \. rest)

Upvotes: 1

Views: 422

Answers (3)

Óscar López
Óscar López

Reputation: 236034

The . symbol is not part of the list, it's just a convention to print an improper list (one that does not end in an empty list). To test if we have an improper list, try this using built-in procedures:

(define (atom? x)
  (and (not (null? x))
       (not (pair? x))))

(define (improper-list? lst)
  (or (atom? lst)
      (not (list? lst))))

It works as expected:

(improper-list? 1)
=> #t
(improper-list? '())
=> #f
(improper-list? '(1 2 3))
=> #f
(improper-list? '(1 2 . x))
=> #t

Upvotes: 1

Joshua Taylor
Joshua Taylor

Reputation: 85873

There's no . element in your list. Rather, it's a notation that's used when the last cdr in a list is not the empty list. That's been described in other questions, too, though. For instance, have a look at Dot notation in scheme.

As to checking for improper lists, the other two answers are correct, and take similar approaches. However, I think specifying a proper list is a bit cleaner, and that it makes for a nicer definition to define proper-list? and then define improper-list? in terms of it:

(define (proper-list? x)
  ;; a proper list is either the empty list (), or a pair
  ;; whose cdr is a proper list.
  (or (null? x)
      (and (pair? x)
           (proper-list? (cdr x)))))

(define (improper-list? x)
  ;; an improper list is anything that is not a proper list
  (not (proper-list? x)))

Upvotes: 1

C. K. Young
C. K. Young

Reputation: 223083

The list (x y z . rest) does not have a dot symbol in it. It's actually an improper list, made this way: (cons 'x (cons 'y (cons 'z 'rest))).

To test for an improper list, you can do something like this:

(define (improper-list? x)
  (cond ((null? x) #f)
        ((pair? x) (improper-list? (cdr x)))
        (else #t)))

Upvotes: 1

Related Questions