1

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)
TheNotMe
  • 1,048
  • 2
  • 17
  • 33
  • Have a look at *improper lists* in [SRFI-1](http://srfi.schemers.org/srfi-1/srfi-1.html#ImproperLists). – uselpa Nov 18 '14 at 16:17
  • Have a look at [Dot notation in scheme](http://stackoverflow.com/q/20216711/1281433). What you actually need to look for is whether the last `cdr` in the chain is the empty list or something else. – Joshua Taylor Nov 18 '14 at 16:41
  • 2
    While we're talking about SRFI 1, it provides a `dotted-list?` predicate that seems like exactly what the OP is seeking. – C. K. Young Nov 18 '14 at 18:46

3 Answers3

1

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)))
C. K. Young
  • 219,335
  • 46
  • 382
  • 435
1

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
Community
  • 1
  • 1
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • I like my definition better, since it aligns with the SRFI 1 definition of an improper list, which also counts standalone atoms (which are improper lists of length 0). – C. K. Young Nov 18 '14 at 16:24
  • @ChrisJester-Young Ok, got it. I believe it's fixed now :P – Óscar López Nov 18 '14 at 16:55
  • Uh, I think `(improper-list? 1)` should be true. If you think inductively, it will make sense: an improper list is: 1. an atom that isn't an empty list, or 2. a pair where the cdr points to an improper list. This also makes sense when you think of the lambda syntax for declaring a function that takes 1+ arguments, vs one that takes 0+ arguments. – C. K. Young Nov 18 '14 at 18:44
  • @ChrisJester-Young Mmm, I misunderstood the definition then :( . _Now_ it's fixed. – Óscar López Nov 18 '14 at 18:49
1

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)))
Community
  • 1
  • 1
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353