简体   繁体   中英

Why list-ref works with pair

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM