diff --git a/koans-solved/clos.lisp b/koans-solved/clos.lisp index 2429352e..25a37a6e 100644 --- a/koans-solved/clos.lisp +++ b/koans-solved/clos.lisp @@ -27,15 +27,22 @@ (setf (slot-value car-1 'speed) 220) (setf (slot-value car-2 'color) :blue) (setf (slot-value car-2 'speed) 240) - (assert-equal ____ (slot-value car-1 'color)) - (assert-equal ____ (slot-value car-2 'speed)))) + (assert-equal :red (slot-value car-1 'color)) + (assert-equal 240 (slot-value car-2 'speed)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Common Lisp predefines the symbol SPEED in the COMMON-LISP package, which +;;; means that we cannot define a function named after it. The function SHADOW +;;; creates a new symbol with the same name in the current package and shadows +;;; the predefined one within the current package. + +(shadow 'speed) + (defclass spaceship () ;; It is possible to define reader, writer, and accessor functions for slots. ((color :reader color :writer (setf color)) - (speed :accessor color))) + (speed :accessor speed))) ;;; Specifying a reader function named COLOR is equivalent to ;;; (DEFMETHOD COLOR ((OBJECT SPACECSHIP)) ...) @@ -47,20 +54,20 @@ (let ((ship (make-instance 'spaceship))) (setf (color ship) :orange (speed ship) 1000) - (assert-equal ____ (color ship)) - (assert-equal ____ (speed ship)))) + (assert-equal :orange (color ship)) + (assert-equal 1000 (speed ship)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defclass bike () ;; It is also possible to define initial arguments for slots. ((color :reader color :initarg :color) - (speed :reader color :initarg :color))) + (speed :reader speed :initarg :speed))) (define-test initargs (let ((bike (make-instance 'bike :color :blue :speed 30))) - (assert-equal ____ (color bike)) - (assert-equal ____ (speed bike)))) + (assert-equal :blue (color bike)) + (assert-equal 30 (speed bike)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -84,15 +91,15 @@ :favorite-lisp-implementation :sbcl)) (adam (make-instance 'c-programmer :name :adam - :favorite-c-compiler :llvm))) - (assert-equal ____ (person-name jack)) - (assert-equal ____ (person-name bob)) - (assert-equal ____ (favorite-lisp-implementation bob)) - (assert-equal ____ (person-name adam)) - (assert-equal ____ (favorite-c-compiler adam)) - (true-or-false? ____ (typep bob 'person)) - (true-or-false? ____ (typep bob 'lisp-programmer)) - (true-or-false? ____ (typep bob 'c-programmer)))) + :favorite-c-compiler :clang))) + (assert-equal :jack (person-name jack)) + (assert-equal :bob (person-name bob)) + (assert-equal :sbcl (favorite-lisp-implementation bob)) + (assert-equal :adam (person-name adam)) + (assert-equal :clang (favorite-c-compiler adam)) + (true-or-false? t (typep bob 'person)) + (true-or-false? t (typep bob 'lisp-programmer)) + (true-or-false? nil (typep bob 'c-programmer)))) ;;; This includes multiple inheritance. @@ -103,13 +110,13 @@ :name :zenon :favorite-lisp-implementation :clisp :favorite-c-compiler :gcc))) - (assert-equal ____ (person-name zenon)) - (assert-equal ____ (favorite-lisp-implementation zenon)) - (assert-equal ____ (favorite-c-compiler zenon)) - (true-or-false? ____ (typep zenon 'person)) - (true-or-false? ____ (typep zenon 'lisp-programmer)) - (true-or-false? ____ (typep zenon 'c-programmer)) - (true-or-false? ____ (typep zenon 'embeddable-common-lisp-programmer)))) + (assert-equal :zenon (person-name zenon)) + (assert-equal :clisp (favorite-lisp-implementation zenon)) + (assert-equal :gcc (favorite-c-compiler zenon)) + (true-or-false? t (typep zenon 'person)) + (true-or-false? t (typep zenon 'lisp-programmer)) + (true-or-false? t (typep zenon 'c-programmer)) + (true-or-false? t (typep zenon 'clisp-programmer)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -133,17 +140,17 @@ (define-test greeting-chatbot () (let ((chatbot (make-instance 'greeting-chatbot :version "1.0.0"))) - (true-or-false? ____ (typep chatbot 'greeting-mixin)) - (true-or-false? ____ (typep chatbot 'chatbot)) - (true-or-false? ____ (typep chatbot 'greeting-chatbot)) - (assert-equal ____ (greet chatbot "Tom")) - (assert-equal ____ (greeted-people chatbot)) - (assert-equal ____ (greet chatbot "Sue")) - (assert-equal ____ (greet chatbot "Mark")) - (assert-equal ____ (greet chatbot "Kate")) - (assert-equal ____ (greet chatbot "Mark")) - (assert-equal ____ (greeted-people chatbot)) - (assert-equal ____ (version chatbot)))) + (true-or-false? t (typep chatbot 'greeting-mixin)) + (true-or-false? t (typep chatbot 'chatbot)) + (true-or-false? t (typep chatbot 'greeting-chatbot)) + (assert-equal "Hello, Tom." (greet chatbot "Tom")) + (assert-equal '("Tom") (greeted-people chatbot)) + (assert-equal "Hello, Sue." (greet chatbot "Sue")) + (assert-equal "Hello, Mark." (greet chatbot "Mark")) + (assert-equal "Hello, Kate." (greet chatbot "Kate")) + (assert-equal "Hello, Mark." (greet chatbot "Mark")) + (assert-equal '("Kate" "Mark" "Sue" "Tom") (greeted-people chatbot)) + (assert-equal "1.0.0" (version chatbot)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -168,7 +175,7 @@ (antonio (make-instance 'italian)) (roy (make-instance 'stereotypical-person)) (mary (make-instance 'another-stereotypical-person))) - (assert-equal ____ (stereotypical-food james)) - (assert-equal ____ (stereotypical-food antonio)) - (assert-equal ____ (stereotypical-food roy)) - (assert-equal ____ (stereotypical-food mary)))) + (assert-equal :burger (stereotypical-food james)) + (assert-equal :pasta (stereotypical-food antonio)) + (assert-equal :burger (stereotypical-food roy)) + (assert-equal :pasta (stereotypical-food mary)))) diff --git a/koans-solved/format.lisp b/koans-solved/format.lisp index 39d0e6fa..7297b31c 100644 --- a/koans-solved/format.lisp +++ b/koans-solved/format.lisp @@ -22,63 +22,88 @@ (define-test format-basic ;; If there are no format directives in the string, FORMAT will return ;; a string that is STRING= to its format control. - (assert-equal ____ (format nil "Lorem ipsum dolor sit amet"))) + (assert-equal "Lorem ipsum dolor sit amet" + (format nil "Lorem ipsum dolor sit amet"))) (define-test format-aesthetic ;; The ~A format directive creates aesthetic output. - (assert-equal ____ (format nil "This is the number ~A" 42)) - (assert-equal ____ (format nil "This is the keyword ~A" :foo)) - (assert-equal ____ (format nil "~A evaluates to ~A" - '(/ 24 (- 3 (/ 8 3))) - (/ 24 (- 3 (/ 8 3))))) - (assert-equal ____ (format nil "This is the character ~A" #\C)) - (assert-equal ____ (format nil "In a ~A" "galaxy far far away"))) + (assert-equal "This is the number 42" + (format nil "This is the number ~A" 42)) + (assert-equal "This is the keyword FOO" + (format nil "This is the keyword ~A" :foo)) + (assert-equal "(/ 24 (- 3 (/ 8 3))) evaluates to 72" + (format nil "~A evaluates to ~A" + '(/ 24 (- 3 (/ 8 3))) + (/ 24 (- 3 (/ 8 3))))) + (assert-equal "This is the character C" + (format nil "This is the character ~A" #\C)) + (assert-equal "In a galaxy far far away" + (format nil "In a ~A" "galaxy far far away"))) (define-test format-standard ;; The ~S format directive prints objects with escape characters. ;; Not all Lisp objects require to be escaped. - (assert-equal ____ (format nil "This is the number ~S" 42)) - (assert-equal ____ (format nil "~S evaluates to ~S" - '(/ 24 (- 3 (/ 8 3))) - (/ 24 (- 3 (/ 8 3))))) + (assert-equal "This is the number 42" (format nil "This is the number ~S" 42)) + (assert-equal "(/ 24 (- 3 (/ 8 3))) evaluates to 72" + (format nil "~S evaluates to ~S" + '(/ 24 (- 3 (/ 8 3))) + (/ 24 (- 3 (/ 8 3))))) ;; Keywords are printed with their leading colon. - (assert-equal ____ (format nil "This is the keyword ~S" :foo)) + (assert-equal "This is the keyword :FOO" + (format nil "This is the keyword ~S" :foo)) ;; Characters are printed in their #\X form. The backslash will need to be ;; escaped inside the printed string, just like in "#\\X". - (assert-equal ____ (format nil "This is the character ~S" #\C)) + (assert-equal "This is the character #\\C" + (format nil "This is the character ~S" #\C)) ;; Strings include quote characters, which must be escaped: ;; such a string might look in code like "foo \"bar\"". - (assert-equal ____ (format nil "In a ~S" "galaxy far far away"))) + (assert-equal "In a \"galaxy far far away\"" + (format nil "In a ~S" "galaxy far far away"))) (define-test format-radix ;; The ~B, ~O, ~D, and ~X radices print numbers in binary, octal, decimal, and ;; hexadecimal notation. - (assert-equal ____ (format nil "This is the number ~B" 42)) - (assert-equal ____ (format nil "This is the number ~O" 42)) - (assert-equal ____ (format nil "This is the number ~D" 42)) - (assert-equal ____ (format nil "This is the number ~X" 42)) + (assert-equal "This is the number 101010" + (format nil "This is the number ~B" 42)) + (assert-equal "This is the number 52" + (format nil "This is the number ~O" 42)) + (assert-equal "This is the number 42" + (format nil "This is the number ~D" 42)) + (assert-equal "This is the number 2A" + (format nil "This is the number ~X" 42)) ;; We can specify a custom radix by using the ~R directive. - (assert-equal ____ (format nil "This is the number ~3R" 42)) + (assert-equal "This is the number 1120" + (format nil "This is the number ~3R" 42)) ;; It is possible to print whole forms this way. (let ((form '(/ 24 (- 3 (/ 8 3)))) (result (/ 24 (- 3 (/ 8 3))))) - (assert-equal ____ (format nil "~B evaluates to ~B" form result)) - (assert-equal ____ (format nil "~O evaluates to ~O" form result)) - (assert-equal ____ (format nil "~D evaluates to ~D" form result)) - (assert-equal ____ (format nil "~X evaluates to ~X" form result)) - (assert-equal ____ (format nil "~3R evaluates to ~3R" form result)))) + (assert-equal "(/ 11000 (- 11 (/ 1000 11))) evaluates to 1001000" + (format nil "~B evaluates to ~B" form result)) + (assert-equal "(/ 30 (- 3 (/ 10 3))) evaluates to 110" + (format nil "~O evaluates to ~O" form result)) + (assert-equal "(/ 24 (- 3 (/ 8 3))) evaluates to 72" + (format nil "~D evaluates to ~D" form result)) + (assert-equal "(/ 18 (- 3 (/ 8 3))) evaluates to 48" + (format nil "~X evaluates to ~X" form result)) + (assert-equal "(/ 220 (- 10 (/ 22 10))) evaluates to 2200" + (format nil "~3R evaluates to ~3R" form result)))) (define-test format-iteration ;; The ~{ and ~} directives iterate over a list. - (assert-equal ____ (format nil "~{[~A]~}" '(1 2 3 4 5 6))) - (assert-equal ____ (format nil "~{[~A ~A]~}" '(1 2 3 4 5 6))) + (assert-equal "[1][2][3][4][5][6]" (format nil "~{[~A]~}" '(1 2 3 4 5 6))) + (assert-equal "[1 2][3 4][5 6]" (format nil "~{[~A ~A]~}" '(1 2 3 4 5 6))) ;; The directive ~^ aborts iteration when no more elements remain. - (assert-equal ____ (format nil "~{[~A]~^, ~}" '(1 2 3 4 5 6)))) + (assert-equal "[1], [2], [3], [4], [5], [6]" + (format nil "~{[~A]~^, ~}" '(1 2 3 4 5 6)))) (define-test format-case ;; The ~( and ~) directives adjust the string case. - (assert-equal ____ (format nil "~(~A~)" "The QuIcK BROWN fox")) + (assert-equal "the quick brown fox" + (format nil "~(~A~)" "The QuIcK BROWN fox")) ;; Some FORMAT directives can be further adjusted with the : and @ modifiers. - (assert-equal ____ (format nil "~:(~A~)" "The QuIcK BROWN fox")) - (assert-equal ____ (format nil "~@(~A~)" "The QuIcK BROWN fox")) - (assert-equal ____ (format nil "~:@(~A~)" "The QuIcK BROWN fox"))) + (assert-equal "The Quick Brown Fox" + (format nil "~:(~A~)" "The QuIcK BROWN fox")) + (assert-equal "The quick brown fox" + (format nil "~@(~A~)" "The QuIcK BROWN fox")) + (assert-equal "THE QUICK BROWN FOX" + (format nil "~:@(~A~)" "The QuIcK BROWN fox"))) diff --git a/koans-solved/scoring-project.lisp b/koans-solved/scoring-project.lisp index 33aea48a..9cb34ff8 100644 --- a/koans-solved/scoring-project.lisp +++ b/koans-solved/scoring-project.lisp @@ -49,8 +49,23 @@ ;;; ;;; Your goal is to write the scoring function for Greed. +(defun score-once (&rest dice) + (let ((sorted (sort (copy-list dice) #'<))) + (cond ((search '(1 1 1) sorted) (list 1000 (remove 1 sorted :count 3))) + ((search '(2 2 2) sorted) (list 200 (remove 2 sorted :count 3))) + ((search '(3 3 3) sorted) (list 300 (remove 3 sorted :count 3))) + ((search '(4 4 4) sorted) (list 400 (remove 4 sorted :count 3))) + ((search '(5 5 5) sorted) (list 500 (remove 5 sorted :count 3))) + ((search '(6 6 6) sorted) (list 600 (remove 6 sorted :count 3))) + ((find 5 sorted) (list 50 (remove 5 sorted :count 1))) + ((find 1 sorted) (list 100 (remove 1 sorted :count 1))) + (t (list 0 '()))))) + (defun score (&rest dice) - ____) + (loop for current-dice = dice then remaining-dice + for (score remaining-dice) = (apply #'score-once current-dice) + sum score + while remaining-dice)) (define-test score-of-an-empty-list-is-zero (assert-equal 0 (score))) diff --git a/koans-solved/type-checking.lisp b/koans-solved/type-checking.lisp index 62c6c11a..8afb5e29 100644 --- a/koans-solved/type-checking.lisp +++ b/koans-solved/type-checking.lisp @@ -18,30 +18,30 @@ (define-test typep ;; TYPEP returns true if the provided object is of the provided type. - (true-or-false? ____ (typep "hello" 'string)) - (true-or-false? ____ (typep "hello" 'array)) - (true-or-false? ____ (typep "hello" 'list)) - (true-or-false? ____ (typep "hello" '(simple-array character (5)))) - (true-or-false? ____ (typep '(1 2 3) 'list)) - (true-or-false? ____ (typep 99 'integer)) - (true-or-false? ____ (typep nil 'NULL)) - (true-or-false? ____ (typep 22/7 'ratio)) - (true-or-false? ____ (typep 4.0 'float)) - (true-or-false? ____ (typep #\a 'character)) - (true-or-false? ____ (typep #'length 'function))) + (true-or-false? t (typep "hello" 'string)) + (true-or-false? t (typep "hello" 'array)) + (true-or-false? nil (typep "hello" 'list)) + (true-or-false? t (typep "hello" '(simple-array character (5)))) + (true-or-false? t (typep '(1 2 3) 'list)) + (true-or-false? t (typep 99 'integer)) + (true-or-false? t (typep nil 'NULL)) + (true-or-false? t (typep 22/7 'ratio)) + (true-or-false? t (typep 4.0 'float)) + (true-or-false? t (typep #\a 'character)) + (true-or-false? t (typep #'length 'function))) (define-test type-of ;; TYPE-OF returns a type specifier for the object. - (assert-equal ____ (type-of '())) - (assert-equal ____ (type-of 4/6))) + (assert-equal 'null (type-of '())) + (assert-equal 'ratio (type-of 4/6))) (define-test overlapping-types ;; Because Lisp types are mathematical sets, they are allowed to overlap. (let ((thing '())) - (true-or-false? ____ (typep thing 'list)) - (true-or-false? ____ (typep thing 'atom)) - (true-or-false? ____ (typep thing 'null)) - (true-or-false? ____ (typep thing 't)))) + (true-or-false? t (typep thing 'list)) + (true-or-false? t (typep thing 'atom)) + (true-or-false? t (typep thing 'null)) + (true-or-false? t (typep thing 't)))) (define-test fixnum-versus-bignum ;; In Lisp, integers are either fixnums or bignums. Fixnums are handled more @@ -54,20 +54,20 @@ (integer-2 most-positive-fixnum) (integer-3 (1+ most-positive-fixnum)) (integer-4 (1- most-negative-fixnum))) - (true-or-false? ____ (typep integer-1 'fixunm)) - (true-or-false? ____ (typep integer-1 'bignum)) - (true-or-false? ____ (typep integer-2 'fixnum)) - (true-or-false? ____ (typep integer-2 'bignum)) - (true-or-false? ____ (typep integer-3 'fixnum)) - (true-or-false? ____ (typep integer-3 'bignum)) - (true-or-false? ____ (typep integer-4 'fixnum)) - (true-or-false? ____ (typep integer-4 'bignum)) + (true-or-false? t (typep integer-1 'fixnum)) + (true-or-false? nil (typep integer-1 'bignum)) + (true-or-false? t (typep integer-2 'fixnum)) + (true-or-false? nil (typep integer-2 'bignum)) + (true-or-false? nil (typep integer-3 'fixnum)) + (true-or-false? t (typep integer-3 'bignum)) + (true-or-false? nil (typep integer-4 'fixnum)) + (true-or-false? t (typep integer-4 'bignum)) ;; Regardless of whether an integer is a fixnum or a bignum, it is still ;; an integer. - (true-or-false? ____ (typep integer-1 'integer)) - (true-or-false? ____ (typep integer-2 'integer)) - (true-or-false? ____ (typep integer-3 'integer)) - (true-or-false? ____ (typep integer-4 'integer)))) + (true-or-false? t (typep integer-1 'integer)) + (true-or-false? t (typep integer-2 'integer)) + (true-or-false? t (typep integer-3 'integer)) + (true-or-false? t (typep integer-4 'integer)))) (define-test subtypep (assert-true (typep 1 'bit)) @@ -76,9 +76,10 @@ (assert-true (typep 2 'integer)) ;; The function SUBTYPEP attempts to answer whether one type specifier ;; represents a subtype of the other type specifier. - (true-or-false? ____ (subtypep 'bit 'integer)) - (true-or-false? ____ (subtypep (type-of 1) (type-of 2))) - (true-or-false? ____ (subtypep (type-of 2) (type-of 1)))) + (true-or-false? t (subtypep 'bit 'integer)) + (true-or-false? t (subtypep 'vector 'array)) + (true-or-false? t (subtypep 'string 'vector)) + (true-or-false? t (subtypep 'null 'list))) (define-test list-type-specifiers ;; Some type specifiers are lists; this way, they carry more information than @@ -87,66 +88,66 @@ (assert-true (typep (make-array 42) '(vector * 42))) (assert-true (typep (make-array 42 :element-type 'bit) '(vector bit 42))) (assert-true (typep (make-array '(4 2)) '(array * (4 2)))) - (true-or-false? ____ (typep (make-array '(3 3)) '(simple-array t (3 3)))) - (true-or-false? ____ (typep (make-array '(3 2 1)) '(simple-array t (1 2 3))))) + (true-or-false? t (typep (make-array '(3 3)) '(simple-array t (3 3)))) + (true-or-false? nil (typep (make-array '(3 2 1)) '(simple-array t (1 2 3))))) (define-test list-type-specifiers-hierarchy ;; Type specifiers that are lists also follow hierarchy. - (true-or-false? ____ (subtypep '(simple-array t (3 3)) '(simple-array t *))) - (true-or-false? ____ (subtypep '(vector double-float 100) '(vector * 100))) - (true-or-false? ____ (subtypep '(vector double-float 100) '(vector double-float *))) - (true-or-false? ____ (subtypep '(vector double-float 100) '(vector * *))) - (true-or-false? ____ (subtypep '(vector double-float 100) '(array number *))) - (true-or-false? ____ (subtypep '(vector double-float 100) t))) + (true-or-false? t (subtypep '(simple-array t (3 3)) '(simple-array t *))) + (true-or-false? t (subtypep '(vector double-float 100) '(vector * 100))) + (true-or-false? t (subtypep '(vector double-float 100) '(vector double-float *))) + (true-or-false? t (subtypep '(vector double-float 100) '(vector * *))) + (true-or-false? t (subtypep '(vector double-float 100) '(array * *))) + (true-or-false? t (subtypep '(vector double-float 100) t))) (define-test type-coercion (assert-true (typep 0 'integer)) - (true-or-false? ____ (typep 0 'short-float)) - (true-or-false? ____ (subtypep 'integer 'short-float)) - (true-or-false? ____ (subtypep 'short-float 'integer)) + (true-or-false? nil (typep 0 'short-float)) + (true-or-false? nil (subtypep 'integer 'short-float)) + (true-or-false? nil (subtypep 'short-float 'integer)) ;; The function COERCE makes it possible to convert values between some ;; standard types. - (true-or-false? ____ (typep (coerce 0 'short-float) 'short-float))) + (true-or-false? t (typep (coerce 0 'short-float) 'short-float))) (define-test atoms-are-anything-thats-not-a-cons ;; In Lisp, an atom is anything that is not a cons cell. The function ATOM ;; returns true if its object is an atom. - (true-or-false? ____ (atom 4)) - (true-or-false? ____ (atom '(1 2 3 4))) - (true-or-false? ____ (atom '(:foo . :bar))) - (true-or-false? ____ (atom 'symbol)) - (true-or-false? ____ (atom :keyword)) - (true-or-false? ____ (atom #(1 2 3 4 5))) - (true-or-false? ____ (atom #\A)) - (true-or-false? ____ (atom "string")) - (true-or-false? ____ (atom (make-array '(4 4))))) + (true-or-false? t (atom 4)) + (true-or-false? nil (atom '(1 2 3 4))) + (true-or-false? nil (atom '(:foo . :bar))) + (true-or-false? t (atom 'symbol)) + (true-or-false? t (atom :keyword)) + (true-or-false? t (atom #(1 2 3 4 5))) + (true-or-false? t (atom #\A)) + (true-or-false? t (atom "string")) + (true-or-false? t (atom (make-array '(4 4))))) (define-test functionp ;; The function FUNCTIONP returns true if its arguments is a function. (assert-true (functionp (lambda (a b c) (+ a b c)))) - (true-or-false? ____ (functionp #'make-array)) - (true-or-false? ____ (functionp 'make-array)) - (true-or-false? ____ (functionp (lambda (x) (* x x)))) - (true-or-false? ____ (functionp '(lambda (x) (* x x)))) - (true-or-false? ____ (functionp '(1 2 3))) - (true-or-false? ____ (functionp t))) + (true-or-false? t (functionp #'make-array)) + (true-or-false? nil (functionp 'make-array)) + (true-or-false? t (functionp (lambda (x) (* x x)))) + (true-or-false? nil (functionp '(lambda (x) (* x x)))) + (true-or-false? nil (functionp '(1 2 3))) + (true-or-false? nil (functionp t))) (define-test other-type-predicates ;; Lisp defines multiple type predicates for standard types.. - (true-or-false? ____ (numberp 999)) - (true-or-false? ____ (listp '(9 9 9))) - (true-or-false? ____ (integerp 999)) - (true-or-false? ____ (rationalp 9/99)) - (true-or-false? ____ (floatp 9.99)) - (true-or-false? ____ (stringp "nine nine nine")) - (true-or-false? ____ (characterp #\9)) - (true-or-false? ____ (bit-vector-p #*01001))) + (true-or-false? t (numberp 999)) + (true-or-false? t (listp '(9 9 9))) + (true-or-false? t (integerp 999)) + (true-or-false? t (rationalp 9/99)) + (true-or-false? t (floatp 9.99)) + (true-or-false? t (stringp "nine nine nine")) + (true-or-false? t (characterp #\9)) + (true-or-false? t (bit-vector-p #*01001))) (define-test guess-that-type ;; Fill in the blank with a type specifier that satisfies the following tests. - (let ((type ____)) - (assert-true (subtypep type '(simple-array t (* 3 *)))) - (assert-true (subtypep type '(simple-array t (5 * *)))) + (let ((type '(simple-array array (5 3 *)))) + (assert-true (subtypep type '(simple-array * (* 3 *)))) + (assert-true (subtypep type '(simple-array * (5 * *)))) (assert-true (subtypep type '(simple-array array *))) (assert-true (typep (make-array '(5 3 9) :element-type 'string) type)) (assert-true (typep (make-array '(5 3 33) :element-type 'vector) type)))) diff --git a/koans/clos.lisp b/koans/clos.lisp index 2429352e..44822d6f 100644 --- a/koans/clos.lisp +++ b/koans/clos.lisp @@ -32,10 +32,17 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Common Lisp predefines the symbol SPEED in the COMMON-LISP package, which +;;; means that we cannot define a function named after it. The function SHADOW +;;; creates a new symbol with the same name in the current package and shadows +;;; the predefined one within the current package. + +(shadow 'speed) + (defclass spaceship () ;; It is possible to define reader, writer, and accessor functions for slots. ((color :reader color :writer (setf color)) - (speed :accessor color))) + (speed :accessor speed))) ;;; Specifying a reader function named COLOR is equivalent to ;;; (DEFMETHOD COLOR ((OBJECT SPACECSHIP)) ...) @@ -55,7 +62,7 @@ (defclass bike () ;; It is also possible to define initial arguments for slots. ((color :reader color :initarg :color) - (speed :reader color :initarg :color))) + (speed :reader speed :initarg :speed))) (define-test initargs (let ((bike (make-instance 'bike :color :blue :speed 30))) @@ -84,7 +91,7 @@ :favorite-lisp-implementation :sbcl)) (adam (make-instance 'c-programmer :name :adam - :favorite-c-compiler :llvm))) + :favorite-c-compiler :clang))) (assert-equal ____ (person-name jack)) (assert-equal ____ (person-name bob)) (assert-equal ____ (favorite-lisp-implementation bob)) @@ -109,7 +116,7 @@ (true-or-false? ____ (typep zenon 'person)) (true-or-false? ____ (typep zenon 'lisp-programmer)) (true-or-false? ____ (typep zenon 'c-programmer)) - (true-or-false? ____ (typep zenon 'embeddable-common-lisp-programmer)))) + (true-or-false? ____ (typep zenon 'clisp-programmer)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/koans/scoring-project.lisp b/koans/scoring-project.lisp index 9e2e35d8..33aea48a 100644 --- a/koans/scoring-project.lisp +++ b/koans/scoring-project.lisp @@ -50,7 +50,7 @@ ;;; Your goal is to write the scoring function for Greed. (defun score (&rest dice) - ) + ____) (define-test score-of-an-empty-list-is-zero (assert-equal 0 (score))) diff --git a/koans/type-checking.lisp b/koans/type-checking.lisp index 62c6c11a..09a3b14f 100644 --- a/koans/type-checking.lisp +++ b/koans/type-checking.lisp @@ -54,7 +54,7 @@ (integer-2 most-positive-fixnum) (integer-3 (1+ most-positive-fixnum)) (integer-4 (1- most-negative-fixnum))) - (true-or-false? ____ (typep integer-1 'fixunm)) + (true-or-false? ____ (typep integer-1 'fixnum)) (true-or-false? ____ (typep integer-1 'bignum)) (true-or-false? ____ (typep integer-2 'fixnum)) (true-or-false? ____ (typep integer-2 'bignum)) @@ -77,8 +77,9 @@ ;; The function SUBTYPEP attempts to answer whether one type specifier ;; represents a subtype of the other type specifier. (true-or-false? ____ (subtypep 'bit 'integer)) - (true-or-false? ____ (subtypep (type-of 1) (type-of 2))) - (true-or-false? ____ (subtypep (type-of 2) (type-of 1)))) + (true-or-false? ____ (subtypep 'vector 'array)) + (true-or-false? ____ (subtypep 'string 'vector)) + (true-or-false? ____ (subtypep 'null 'list))) (define-test list-type-specifiers ;; Some type specifiers are lists; this way, they carry more information than @@ -96,7 +97,7 @@ (true-or-false? ____ (subtypep '(vector double-float 100) '(vector * 100))) (true-or-false? ____ (subtypep '(vector double-float 100) '(vector double-float *))) (true-or-false? ____ (subtypep '(vector double-float 100) '(vector * *))) - (true-or-false? ____ (subtypep '(vector double-float 100) '(array number *))) + (true-or-false? ____ (subtypep '(vector double-float 100) '(array * *))) (true-or-false? ____ (subtypep '(vector double-float 100) t))) (define-test type-coercion @@ -145,8 +146,8 @@ (define-test guess-that-type ;; Fill in the blank with a type specifier that satisfies the following tests. (let ((type ____)) - (assert-true (subtypep type '(simple-array t (* 3 *)))) - (assert-true (subtypep type '(simple-array t (5 * *)))) + (assert-true (subtypep type '(simple-array * (* 3 *)))) + (assert-true (subtypep type '(simple-array * (5 * *)))) (assert-true (subtypep type '(simple-array array *))) (assert-true (typep (make-array '(5 3 9) :element-type 'string) type)) (assert-true (typep (make-array '(5 3 33) :element-type 'vector) type)))) diff --git a/test-framework.lisp b/test-framework.lisp index 718ce5ad..2540a6ea 100644 --- a/test-framework.lisp +++ b/test-framework.lisp @@ -154,7 +154,7 @@ (defmacro assert-true (form) "Assert whether the form is true." - `(expand-assert :result ,form ,(notnot form) t)) + `(expand-assert :result ,form (notnot ,form) t)) ;;; Run the tests