Reputation: 9
I was wondering what (cons? list-name)
does. Does it just check that list-name
is not a non-empty list? Is it just like the opposite of (empty? list-name)
? If so, then is it not better to just say (empty? list-name)
and then say else
instead of cons?
? For example:
(define (f list-name)
(cond
[(empty? list-name) empty]
[(cons? list-name) "do something]))
Upvotes: 0
Views: 353
Reputation: 53911
cons?
checks whether the value is a cons
cell, e.g., something that's (cons foo bar)
for some foo
and bar
.
> (cons? 1)
#f
> (cons? '())
#f
> (cons? (list 1 2 3))
#t
> (cons? (cons 1 2))
#t
If (cons? a)
is true, then it is safe to use car
and cdr
on a
.
This isn't the opposite of empty?
since empty?
is true if and only if the argument is the empty list, so (empty? 1) == (cons? 1) == #f
.
Sidenote: Please don't put PLEASE HELP!!
or similar in your question titles, everyone here is happy to help, but it's a bit obnoxious to read. Just something to keep in mind in the future. Welcome to SO.
Upvotes: 1
Reputation: 85913
jozefg's answer is right in pointing out that (cons? x)
is not the same as (not (empty? x))
, in general, because there are things (e.g., numbers) that are neither cons cells nor the empty list.
However, your variable was list-name
, so you may have some reason to expect that its value is, in fact a list. A list, in Scheme, is either:
car
is the first
element of a list and whose cdr
is the rest
of the list.Because of this, if you're writing a function that requires a list be passed in, then it does make sense to simply check for the trivial case (the empty list) with empty?
, and to assume, since you've required a list, that anything that doesn't match that case is a cons cell on which you can call cdr
and cdr
. This is because while
(cons? x) == (not (empty? x))
is not true of values in general, it is true for lists. That is, if you already know that lst
is a list, then
(cons? lst) == (not (empty? lst))
is true. There are a number of functions that do the same thing when we're talking about lists and cons cells. E.g., empty?
and null?
do the same thing, but they signal a slightly different intent on the part of the programmer. Similarly, car
and cdr
do the same thing as first
and rest
, but car
and cdr
signal that you might be treating something as a pair of two things, whereas first
and rest
clearly signal the intent that you're working with a list.
Your code, since it seems to expect a list, should probably be the following, since, for a list, if it's not the empty list, it must be a cons.
(define (f lst)
(cond
[(empty? lst) empty]
[else "do something]))
More generally, the code you write should depend on what kind of input you expect. E.g., in the first case, it's fine to check for empty, and assume a cons otherwise, because you're expecting a list. In the second case, you have to check for all the different kinds of things you might see.
(define (frob-list lst)
(cond
[(empty? lst) empty] ; arg is ()
[else ...])) ; arg is (x . y)
(define (frob-object obj)
(cond
[(null? obj) ...] ; arg is ()
[(cons? obj) ...] ; arg is (x . y)
[(number? obj) ...] ; arg is r
... ; arg is ...
[else ...])) ; else ...
Upvotes: 1