Reputation: 1058
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
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
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
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