parent
fd03924c10
commit
ce9c7ac999
|
@ -27,42 +27,42 @@
|
||||||
;; ...or by using the function CONS.
|
;; ...or by using the function CONS.
|
||||||
(names (cons "Matthew" (cons "Mark" (cons "Margaret" '())))))
|
(names (cons "Matthew" (cons "Mark" (cons "Margaret" '())))))
|
||||||
;; Try filling in the below blanks in different ways.
|
;; Try filling in the below blanks in different ways.
|
||||||
(assert-equal ____ fruits)
|
(assert-equal (cons 'orange (cons 'pomello (cons 'clementine nil))) fruits)
|
||||||
(assert-equal ____ some-evens)
|
(assert-equal '(2 . (4 . (6 . nil))) some-evens)
|
||||||
(assert-equal ____ long-numbers)
|
(assert-equal (list 16487302 3826700034 10000000) long-numbers)
|
||||||
(assert-equal ____ names)))
|
(assert-equal '("Matthew" "Mark" "Margaret") names)))
|
||||||
|
|
||||||
(define-test cons-tructing-lists
|
(define-test cons-tructing-lists
|
||||||
;; The function CONS can be used to add new elements at the beginning of
|
;; The function CONS can be used to add new elements at the beginning of
|
||||||
;; an existing list.
|
;; an existing list.
|
||||||
(let ((nums '()))
|
(let ((nums '()))
|
||||||
(setf nums (cons :one nums))
|
(setf nums (cons :one nums))
|
||||||
(assert-equal ____ nums)
|
(assert-equal '(:one) nums)
|
||||||
(setf nums (cons :two nums))
|
(setf nums (cons :two nums))
|
||||||
(assert-equal ____ nums)
|
(assert-equal '(:two :one) nums)
|
||||||
;; Lists can contain anything, even objects of different types.
|
;; Lists can contain anything, even objects of different types.
|
||||||
(setf nums (cons 333 nums))
|
(setf nums (cons 333 nums))
|
||||||
(assert-equal ____ nums)
|
(assert-equal '(333 :two :one) nums)
|
||||||
;; Lists can contain other lists, too.
|
;; Lists can contain other lists, too.
|
||||||
(setf nums (cons (list "some" "strings") nums))
|
(setf nums (cons (list "some" "strings") nums))
|
||||||
(assert-equal ____ nums)))
|
(assert-equal '(("some" "strings") 333 :two :one) nums)))
|
||||||
|
|
||||||
(define-test car-and-cdr
|
(define-test car-and-cdr
|
||||||
;; We may use functions CAR and CDR (or, alternatively, FIRST and REST) to
|
;; We may use functions CAR and CDR (or, alternatively, FIRST and REST) to
|
||||||
;; access the two slots of a cons cell.
|
;; access the two slots of a cons cell.
|
||||||
(let ((x (cons 1 2)))
|
(let ((x (cons 1 2)))
|
||||||
(assert-equal ____ (car x))
|
(assert-equal 1 (car x))
|
||||||
(assert-equal ____ (cdr x)))
|
(assert-equal 2 (cdr x)))
|
||||||
;; Calls to CAR and CDR are often intertwined to extract data from a nested
|
;; Calls to CAR and CDR are often intertwined to extract data from a nested
|
||||||
;; cons structure.
|
;; cons structure.
|
||||||
(let ((structure '((1 2) (("foo" . "bar")))))
|
(let ((structure '((1 2) (("foo" . "bar")))))
|
||||||
(assert-equal ____ (car structure))
|
(assert-equal '(1 2) (car structure))
|
||||||
(assert-equal ____ (car (cdr structure)))
|
(assert-equal '(("foo". "bar")) (car (cdr structure)))
|
||||||
(assert-equal ____ (cdr (car (car (cdr structure)))))
|
(assert-equal "bar" (cdr (car (car (cdr structure)))))
|
||||||
;; Lisp defines shorthand functions for up to four such nested calls.
|
;; Lisp defines shorthand functions for up to four such nested calls.
|
||||||
(assert-equal ____ (car structure))
|
(assert-equal '(1 2) (car structure))
|
||||||
(assert-equal ____ (cadr structure))
|
(assert-equal '(("foo" . "bar")) (cadr structure))
|
||||||
(assert-equal ____ (cdaadr structure))))
|
(assert-equal "bar" (cdaadr structure))))
|
||||||
|
|
||||||
(define-test push-pop
|
(define-test push-pop
|
||||||
;; PUSH and POP are macros similar to SETF, as both of them operate on places.
|
;; PUSH and POP are macros similar to SETF, as both of them operate on places.
|
||||||
|
@ -70,49 +70,49 @@
|
||||||
;; PUSH sets the value of the place to a new cons cell containing some value
|
;; PUSH sets the value of the place to a new cons cell containing some value
|
||||||
;; in its CAR.
|
;; in its CAR.
|
||||||
(push 0 place)
|
(push 0 place)
|
||||||
(assert-equal ____ place)
|
(assert-equal '(0 10 20 30 40) place)
|
||||||
;; POP removes a single cons cell from a place, sets the place to its CDR,
|
;; POP removes a single cons cell from a place, sets the place to its CDR,
|
||||||
;; and returns the value from its CAR.
|
;; and returns the value from its CAR.
|
||||||
(let ((value (pop place)))
|
(let ((value (pop place)))
|
||||||
(assert-equal ____ value)
|
(assert-equal 0 value)
|
||||||
(assert-equal ____ place))
|
(assert-equal '(10 20 30 40) place))
|
||||||
;; The return value of POP can be discarded to simply "remove" a single cons
|
;; The return value of POP can be discarded to simply "remove" a single cons
|
||||||
;; cell from a place.
|
;; cell from a place.
|
||||||
(pop place)
|
(pop place)
|
||||||
(let ((value (pop place)))
|
(let ((value (pop place)))
|
||||||
(assert-equal ____ value)
|
(assert-equal 20 value)
|
||||||
(assert-equal ____ place))))
|
(assert-equal '(30 40) place))))
|
||||||
|
|
||||||
(define-test append-nconc
|
(define-test append-nconc
|
||||||
;; The functions APPEND and NCONC appends one list to the end of another.
|
;; The functions APPEND and NCONC appends one list to the end of another.
|
||||||
;; While APPEND creates new lists, NCONC modifies existing ones; therefore
|
;; While APPEND creates new lists, NCONC modifies existing ones; therefore
|
||||||
;; APPEND can be used on literals, but NCONC needs fresh lists.
|
;; APPEND can be used on literals, but NCONC needs fresh lists.
|
||||||
(assert-equal ____ (append '(:a :b) '(:c)))
|
(assert-equal '(:a :b :c) (append '(:a :b) '(:c)))
|
||||||
(assert-equal ____ (nconc (list :a :b) (list :c)))
|
(assert-equal (list :a :b :c) (nconc (list :a :b) (list :c)))
|
||||||
(let ((list-1 (list 1 2 3))
|
(let ((list-1 (list 1 2 3))
|
||||||
(list-2 (list 4 5 6)))
|
(list-2 (list 4 5 6)))
|
||||||
;; Both APPEND and NCONC return the appended list, but the interesting part
|
;; Both APPEND and NCONC return the appended list, but the interesting part
|
||||||
;; is what happens when we try to use the original variables passed to them.
|
;; is what happens when we try to use the original variables passed to them.
|
||||||
(assert-equal ____ (append list-1 list-2))
|
(assert-equal (list 1 2 3 4 5 6) (append list-1 list-2))
|
||||||
(assert-equal ____ list-1)
|
(assert-equal (list 1 2 3) list-1)
|
||||||
(assert-equal ____ list-2)
|
(assert-equal (list 4 5 6) list-2)
|
||||||
(assert-equal ____ (nconc list-1 list-2))
|
(assert-equal (list 1 2 3 4 5 6) (nconc list-1 list-2))
|
||||||
(assert-equal ____ list-1)
|
(assert-equal (list 1 2 3 4 5 6) list-1)
|
||||||
(assert-equal ____ list-2)))
|
(assert-equal (list 4 5 6) list-2)))
|
||||||
|
|
||||||
(define-test accessing-list-elements
|
(define-test accessing-list-elements
|
||||||
(let ((noms '("peanut" "butter" "and" "jelly")))
|
(let ((noms '("peanut" "butter" "and" "jelly")))
|
||||||
;; Common Lisp defines accessor functions for lists: FIRST, SECOND, ...,
|
;; Common Lisp defines accessor functions for lists: FIRST, SECOND, ...,
|
||||||
;; up to TENTH.
|
;; up to TENTH.
|
||||||
(assert-equal "peanut" (first noms))
|
(assert-equal "peanut" (first noms))
|
||||||
(assert-equal ____ (second noms))
|
(assert-equal "butter" (second noms))
|
||||||
(assert-equal ____ (fourth noms))
|
(assert-equal "jelly" (fourth noms))
|
||||||
;; The function LAST returns the last cons cell of a list.
|
;; The function LAST returns the last cons cell of a list.
|
||||||
(assert-equal ____ (last noms))
|
(assert-equal '("jelly") (last noms))
|
||||||
;; The function NTH returns the n-th element of a list.
|
;; The function NTH returns the n-th element of a list.
|
||||||
(assert-equal "butter" (nth 1 noms))
|
(assert-equal "butter" (nth 1 noms))
|
||||||
(assert-equal ____ (nth 0 noms))
|
(assert-equal "peanut" (nth 0 noms))
|
||||||
(assert-equal ____ (nth 3 noms))))
|
(assert-equal "jelly" (nth 3 noms))))
|
||||||
|
|
||||||
(define-test cons-tructing-improper-lists
|
(define-test cons-tructing-improper-lists
|
||||||
;; A proper list is a list whose final CDR ends with NIL.
|
;; A proper list is a list whose final CDR ends with NIL.
|
||||||
|
@ -122,25 +122,25 @@
|
||||||
(x (list* 1 2 3 4 5))
|
(x (list* 1 2 3 4 5))
|
||||||
;; ...or pass them as literals via dot notation.
|
;; ...or pass them as literals via dot notation.
|
||||||
(y '(6 7 8 9 . 0)))
|
(y '(6 7 8 9 . 0)))
|
||||||
(assert-equal ____ (last x))
|
(assert-equal '(4 . 5) (last x))
|
||||||
(assert-equal ____ (last y)))
|
(assert-equal '(9 . 0) (last y)))
|
||||||
;; We can create a cyclic list by changing the last CDR of a list to refer to
|
;; We can create a cyclic list by changing the last CDR of a list to refer to
|
||||||
;; another cons cell
|
;; another cons cell
|
||||||
(let ((list (list 1 2 3 4 5))
|
(let ((list (list 1 2 3 4 5))
|
||||||
(cyclic-list (list 1 2 3 4 5)))
|
(cyclic-list (list 1 2 3 4 5)))
|
||||||
(setf (cdr (last cyclic-list)) cyclic-list)
|
(setf (cdr (last cyclic-list)) cyclic-list)
|
||||||
;; Function LIST-LENGTH returns NIL if a list is cyclic.
|
;; Function LIST-LENGTH returns NIL if a list is cyclic.
|
||||||
(assert-equal ____ (list-length list))
|
(assert-equal 5 (list-length list))
|
||||||
(assert-equal ____ (list-length cyclic-list))
|
(assert-equal nil (list-length cyclic-list))
|
||||||
;; Many Lisp functions operate only on proper lists.
|
;; Many Lisp functions operate only on proper lists.
|
||||||
;; The function NTH is not one of them; it can be used to retrieve elements
|
;; The function NTH is not one of them; it can be used to retrieve elements
|
||||||
;; of cyclic lists.
|
;; of cyclic lists.
|
||||||
(assert-equal ____ (nth 101 cyclic-list))))
|
(assert-equal 2 (nth 101 cyclic-list))))
|
||||||
|
|
||||||
(define-test slicing-lists
|
(define-test slicing-lists
|
||||||
;; The function SUBSEQ returns a subsequence of a list.
|
;; The function SUBSEQ returns a subsequence of a list.
|
||||||
(let ((noms (list "peanut" "butter" "and" "jelly")))
|
(let ((noms (list "peanut" "butter" "and" "jelly")))
|
||||||
(assert-equal ____ (subseq noms 0 1))
|
(assert-equal '("peanut" )(subseq noms 0 1))
|
||||||
(assert-equal ____ (subseq noms 0 2))
|
(assert-equal '("peanut" "butter" )(subseq noms 0 2))
|
||||||
(assert-equal ____ (subseq noms 2 2))
|
(assert-equal '() (subseq noms 2 2))
|
||||||
(assert-equal ____ (subseq noms 2))))
|
(assert-equal '("and" "jelly") (subseq noms 2))))
|
||||||
|
|
Loading…
Reference in New Issue