In the following code:
(define l (cons 1 2))
l
(list? l)
(pair? l)
(list-ref l 0) ; works;
(list-ref l 1) ; DOES NOT WORK;
Output:
'(1 . 2)
#f
#t
1
Error: list-ref: index reaches a non-pair
index: 1
in: '(1 . 2)
Why (list-ref l 0) works if l is not a list. Otherwise, why (list-ref l 1) does not work. This behavior seems to be inconsistent and confusion creating.
The functions car
and cdr
also work, returning 1 and 2, respectively. Why should cdr
work if this is not a list. One would expect car
to return 1.2
and not just 1.
From the documentation :
The
lst
argument need not actually be a list;lst
must merely start with a chain of at least(add1 pos)
pairs.
This means the lst
argument is allowed to be an improper list as long as the index is smaller than the index of the first pair whose cdr
is a non-pair.
A list is simply a lot of pairs linked together terminating in an empty list. For example, (list 1 2 3)
is equivalent to (cons 1 (cons 2 (cons 3 '())))
.
There's no reason to loop through the entire list to check if l
is a list, so as long as it looks like a list, scheme doesn't care if it terminates in an empty list. list-ref
is basically defined as so:
(define (list-ref lyst index)
(cond ((= index 0) (car index))
(else (list-ref (cdr lyst) (- index 1)))))
So of course it will encounter an error when it tries to run (car 2)
As for the other question, car
and cdr
simply return the first element in a pair and the second element in a pair respectively.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.