koans on types and clos
- types are complicated, not sure how to look up documentation for it would they show up in apropos all? - list formatted types - like array vector can specify type of element, rank / dimentions (not sure there's variancy over the element type?) - clos - similar to structure for structured you get separate functions to get slots, use setf to set generalized variables with classes, I can use generic function to create #'make-instance and access slots with (#'slot-value instance 'slot-name) but there could be defined accessor, reader, writer, and :initarg to name slot to have handle to set value in constructor now that's a lot
This commit is contained in:
parent
c85aa1bbe5
commit
b7bccb9cfb
|
@ -18,17 +18,25 @@
|
||||||
;; A class definition lists all the slots of every instance.
|
;; A class definition lists all the slots of every instance.
|
||||||
(color speed))
|
(color speed))
|
||||||
|
|
||||||
|
;; what's the difference with defstruct?
|
||||||
|
(defstruct struct-racecar
|
||||||
|
color speed)
|
||||||
|
(setq my-struct-racecar (make-struct-racecar :color :red :speed 45))
|
||||||
|
(struct-racecar-color my-struct-racecar)
|
||||||
|
|
||||||
|
;; they have generic setters and accessort, ok
|
||||||
(define-test defclass
|
(define-test defclass
|
||||||
;; Class instances are constructed via MAKE-INSTANCE.
|
;; Class instances are constructed via MAKE-INSTANCE.
|
||||||
(let ((car-1 (make-instance 'racecar))
|
(let ((car-1 (make-instance 'racecar))
|
||||||
(car-2 (make-instance 'racecar)))
|
(car-2 (make-instance 'racecar)))
|
||||||
;; Slot values can be set via SLOT-VALUE.
|
;; Slot values can be set via SLOT-VALUE.
|
||||||
(setf (slot-value car-1 'color) :red)
|
(setf (slot-value car-1 'color) :red)
|
||||||
(setf (slot-value car-1 'speed) 220)
|
(setf (slot-value car-1 'speed) 220)
|
||||||
(setf (slot-value car-2 'color) :blue)
|
(setf (slot-value car-2 'color) :blue)
|
||||||
(setf (slot-value car-2 'speed) 240)
|
(setf (slot-value car-2 'speed) 240)
|
||||||
(assert-equal ____ (slot-value car-1 'color))
|
(assert-equal :red (slot-value car-1 'color))
|
||||||
(assert-equal ____ (slot-value car-2 'speed))))
|
(assert-equal 240 (slot-value car-2 'speed))))
|
||||||
|
;; so, using #'slot-value and #'make-instance
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
@ -44,18 +52,28 @@
|
||||||
((color :reader color :writer (setf color))
|
((color :reader color :writer (setf color))
|
||||||
(speed :accessor speed)))
|
(speed :accessor speed)))
|
||||||
|
|
||||||
|
(setq my-ship (make-instance 'spaceship))
|
||||||
|
(setf (color my-ship) :green)
|
||||||
|
(color my-ship)
|
||||||
|
|
||||||
;;; Specifying a reader function named COLOR is equivalent to
|
;;; Specifying a reader function named COLOR is equivalent to
|
||||||
;;; (DEFMETHOD COLOR ((OBJECT SPACECSHIP)) ...)
|
;;; (DEFMETHOD COLOR ((OBJECT SPACECSHIP)) ...)
|
||||||
;;; Specifying a writer function named (SETF COLOR) is equivalent to
|
;;; Specifying a writer function named (SETF COLOR) is equivalent to
|
||||||
;;; (DEFMETHOD (SETF COLOR) (NEW-VALUE (OBJECT SPACECSHIP)) ...)
|
;;; (DEFMETHOD (SETF COLOR) (NEW-VALUE (OBJECT SPACECSHIP)) ...)
|
||||||
;;; Specifying an accessor function performs both of the above.
|
;;; Specifying an accessor function performs both of the above.
|
||||||
|
|
||||||
|
;; I don't understand what (defmethod (setf color) ...) means
|
||||||
|
;; is that two atom name? wtf
|
||||||
|
;; nope - function-name::= {symbol | (setf symbol)}
|
||||||
|
;; http://www.lispworks.com/documentation/HyperSpec/Body/m_defmet.htm
|
||||||
|
;; still not quite understand it, lots of complicated things, about different forms
|
||||||
|
|
||||||
(define-test accessors
|
(define-test accessors
|
||||||
(let ((ship (make-instance 'spaceship)))
|
(let ((ship (make-instance 'spaceship)))
|
||||||
(setf (color ship) :orange
|
(setf (color ship) :orange
|
||||||
(speed ship) 1000)
|
(speed ship) 1000)
|
||||||
(assert-equal ____ (color ship))
|
(assert-equal :orange (color ship))
|
||||||
(assert-equal ____ (speed ship))))
|
(assert-equal 1000 (speed ship))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
@ -66,8 +84,10 @@
|
||||||
|
|
||||||
(define-test initargs
|
(define-test initargs
|
||||||
(let ((bike (make-instance 'bike :color :blue :speed 30)))
|
(let ((bike (make-instance 'bike :color :blue :speed 30)))
|
||||||
(assert-equal ____ (color bike))
|
(assert-equal :blue (color bike))
|
||||||
(assert-equal ____ (speed bike))))
|
(assert-equal 30 (speed bike))))
|
||||||
|
;; oh, so that's for defining initial values in the constructor
|
||||||
|
;; i guess
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
|
|
@ -18,30 +18,30 @@
|
||||||
|
|
||||||
(define-test typep
|
(define-test typep
|
||||||
;; TYPEP returns true if the provided object is of the provided type.
|
;; TYPEP returns true if the provided object is of the provided type.
|
||||||
(true-or-false? ____ (typep "hello" 'string))
|
(true-or-false? t (typep "hello" 'string))
|
||||||
(true-or-false? ____ (typep "hello" 'array))
|
(true-or-false? t (typep "hello" 'array))
|
||||||
(true-or-false? ____ (typep "hello" 'list))
|
(true-or-false? nil (typep "hello" 'list))
|
||||||
(true-or-false? ____ (typep "hello" '(simple-array character (5))))
|
(true-or-false? t (typep "hello" '(simple-array character (5))))
|
||||||
(true-or-false? ____ (typep '(1 2 3) 'list))
|
(true-or-false? t (typep '(1 2 3) 'list))
|
||||||
(true-or-false? ____ (typep 99 'integer))
|
(true-or-false? t (typep 99 'integer))
|
||||||
(true-or-false? ____ (typep nil 'NULL))
|
(true-or-false? t (typep nil 'NULL))
|
||||||
(true-or-false? ____ (typep 22/7 'ratio))
|
(true-or-false? t (typep 22/7 'ratio))
|
||||||
(true-or-false? ____ (typep 4.0 'float))
|
(true-or-false? t (typep 4.0 'float))
|
||||||
(true-or-false? ____ (typep #\a 'character))
|
(true-or-false? t (typep #\a 'character))
|
||||||
(true-or-false? ____ (typep #'length 'function)))
|
(true-or-false? t (typep #'length 'function)))
|
||||||
|
|
||||||
(define-test type-of
|
(define-test type-of
|
||||||
;; TYPE-OF returns a type specifier for the object.
|
;; TYPE-OF returns a type specifier for the object.
|
||||||
(assert-equal ____ (type-of '()))
|
(assert-equal 'NULL (type-of '()))
|
||||||
(assert-equal ____ (type-of 4/6)))
|
(assert-equal 'ratio (type-of 4/6)))
|
||||||
|
|
||||||
(define-test overlapping-types
|
(define-test overlapping-types
|
||||||
;; Because Lisp types are mathematical sets, they are allowed to overlap.
|
;; Because Lisp types are mathematical sets, they are allowed to overlap.
|
||||||
(let ((thing '()))
|
(let ((thing '()))
|
||||||
(true-or-false? ____ (typep thing 'list))
|
(true-or-false? t (typep thing 'list))
|
||||||
(true-or-false? ____ (typep thing 'atom))
|
(true-or-false? t (typep thing 'atom))
|
||||||
(true-or-false? ____ (typep thing 'null))
|
(true-or-false? t (typep thing 'null))
|
||||||
(true-or-false? ____ (typep thing 't))))
|
(true-or-false? t (typep thing 't))))
|
||||||
|
|
||||||
(define-test fixnum-versus-bignum
|
(define-test fixnum-versus-bignum
|
||||||
;; In Lisp, integers are either fixnums or bignums. Fixnums are handled more
|
;; In Lisp, integers are either fixnums or bignums. Fixnums are handled more
|
||||||
|
@ -54,20 +54,20 @@
|
||||||
(integer-2 most-positive-fixnum)
|
(integer-2 most-positive-fixnum)
|
||||||
(integer-3 (1+ most-positive-fixnum))
|
(integer-3 (1+ most-positive-fixnum))
|
||||||
(integer-4 (1- most-negative-fixnum)))
|
(integer-4 (1- most-negative-fixnum)))
|
||||||
(true-or-false? ____ (typep integer-1 'fixnum))
|
(true-or-false? t (typep integer-1 'fixnum))
|
||||||
(true-or-false? ____ (typep integer-1 'bignum))
|
(true-or-false? nil (typep integer-1 'bignum))
|
||||||
(true-or-false? ____ (typep integer-2 'fixnum))
|
(true-or-false? t (typep integer-2 'fixnum))
|
||||||
(true-or-false? ____ (typep integer-2 'bignum))
|
(true-or-false? nil (typep integer-2 'bignum))
|
||||||
(true-or-false? ____ (typep integer-3 'fixnum))
|
(true-or-false? nil (typep integer-3 'fixnum))
|
||||||
(true-or-false? ____ (typep integer-3 'bignum))
|
(true-or-false? t (typep integer-3 'bignum))
|
||||||
(true-or-false? ____ (typep integer-4 'fixnum))
|
(true-or-false? nil (typep integer-4 'fixnum))
|
||||||
(true-or-false? ____ (typep integer-4 'bignum))
|
(true-or-false? t (typep integer-4 'bignum))
|
||||||
;; Regardless of whether an integer is a fixnum or a bignum, it is still
|
;; Regardless of whether an integer is a fixnum or a bignum, it is still
|
||||||
;; an integer.
|
;; an integer.
|
||||||
(true-or-false? ____ (typep integer-1 'integer))
|
(true-or-false? t (typep integer-1 'integer))
|
||||||
(true-or-false? ____ (typep integer-2 'integer))
|
(true-or-false? t (typep integer-2 'integer))
|
||||||
(true-or-false? ____ (typep integer-3 'integer))
|
(true-or-false? t (typep integer-3 'integer))
|
||||||
(true-or-false? ____ (typep integer-4 'integer))))
|
(true-or-false? t (typep integer-4 'integer))))
|
||||||
|
|
||||||
(define-test subtypep
|
(define-test subtypep
|
||||||
(assert-true (typep 1 'bit))
|
(assert-true (typep 1 'bit))
|
||||||
|
@ -76,10 +76,10 @@
|
||||||
(assert-true (typep 2 'integer))
|
(assert-true (typep 2 'integer))
|
||||||
;; The function SUBTYPEP attempts to answer whether one type specifier
|
;; The function SUBTYPEP attempts to answer whether one type specifier
|
||||||
;; represents a subtype of the other type specifier.
|
;; represents a subtype of the other type specifier.
|
||||||
(true-or-false? ____ (subtypep 'bit 'integer))
|
(true-or-false? t (subtypep 'bit 'integer))
|
||||||
(true-or-false? ____ (subtypep 'vector 'array))
|
(true-or-false? t (subtypep 'vector 'array))
|
||||||
(true-or-false? ____ (subtypep 'string 'vector))
|
(true-or-false? t (subtypep 'string 'vector))
|
||||||
(true-or-false? ____ (subtypep 'null 'list)))
|
(true-or-false? t (subtypep 'null 'list)))
|
||||||
|
|
||||||
(define-test list-type-specifiers
|
(define-test list-type-specifiers
|
||||||
;; Some type specifiers are lists; this way, they carry more information than
|
;; Some type specifiers are lists; this way, they carry more information than
|
||||||
|
@ -88,64 +88,66 @@
|
||||||
(assert-true (typep (make-array 42) '(vector * 42)))
|
(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 42 :element-type 'bit) '(vector bit 42)))
|
||||||
(assert-true (typep (make-array '(4 2)) '(array * (4 2))))
|
(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? t (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? nil (typep (make-array '(3 2 1)) '(simple-array t (1 2 3)))))
|
||||||
|
|
||||||
(define-test list-type-specifiers-hierarchy
|
(define-test list-type-specifiers-hierarchy
|
||||||
;; Type specifiers that are lists also follow hierarchy.
|
;; Type specifiers that are lists also follow hierarchy.
|
||||||
(true-or-false? ____ (subtypep '(simple-array t (3 3)) '(simple-array t *)))
|
(true-or-false? t (subtypep '(simple-array t (3 3)) '(simple-array t *)))
|
||||||
(true-or-false? ____ (subtypep '(vector double-float 100) '(vector * 100)))
|
(true-or-false? t (subtypep '(vector double-float 100) '(vector * 100)))
|
||||||
(true-or-false? ____ (subtypep '(vector double-float 100) '(vector double-float *)))
|
(true-or-false? t (subtypep '(vector double-float 100) '(vector double-float *)))
|
||||||
(true-or-false? ____ (subtypep '(vector double-float 100) '(vector * *)))
|
(true-or-false? t (subtypep '(vector double-float 100) '(vector * *)))
|
||||||
(true-or-false? ____ (subtypep '(vector double-float 100) '(array * *)))
|
(true-or-false? t (subtypep '(vector double-float 100) '(array * *)))
|
||||||
(true-or-false? ____ (subtypep '(vector double-float 100) t)))
|
(true-or-false? t (subtypep '(vector double-float 100) t)))
|
||||||
|
|
||||||
(define-test type-coercion
|
(define-test type-coercion
|
||||||
(assert-true (typep 0 'integer))
|
(assert-true (typep 0 'integer))
|
||||||
(true-or-false? ____ (typep 0 'short-float))
|
(true-or-false? nil (typep 0 'short-float))
|
||||||
(true-or-false? ____ (subtypep 'integer 'short-float))
|
(true-or-false? nil (subtypep 'integer 'short-float))
|
||||||
(true-or-false? ____ (subtypep 'short-float 'integer))
|
(true-or-false? nil (subtypep 'short-float 'integer))
|
||||||
;; The function COERCE makes it possible to convert values between some
|
;; The function COERCE makes it possible to convert values between some
|
||||||
;; standard types.
|
;; 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
|
(define-test atoms-are-anything-thats-not-a-cons
|
||||||
;; In Lisp, an atom is anything that is not a cons cell. The function ATOM
|
;; In Lisp, an atom is anything that is not a cons cell. The function ATOM
|
||||||
;; returns true if its object is an atom.
|
;; returns true if its object is an atom.
|
||||||
(true-or-false? ____ (atom 4))
|
(true-or-false? t (atom 4))
|
||||||
(true-or-false? ____ (atom '(1 2 3 4)))
|
(true-or-false? nil (atom '(1 2 3 4)))
|
||||||
(true-or-false? ____ (atom '(:foo . :bar)))
|
(true-or-false? nil (atom '(:foo . :bar)))
|
||||||
(true-or-false? ____ (atom 'symbol))
|
(true-or-false? t (atom 'symbol))
|
||||||
(true-or-false? ____ (atom :keyword))
|
(true-or-false? t (atom :keyword))
|
||||||
(true-or-false? ____ (atom #(1 2 3 4 5)))
|
(true-or-false? t (atom #(1 2 3 4 5)))
|
||||||
(true-or-false? ____ (atom #\A))
|
(true-or-false? t (atom #\A))
|
||||||
(true-or-false? ____ (atom "string"))
|
(true-or-false? t (atom "string"))
|
||||||
(true-or-false? ____ (atom (make-array '(4 4)))))
|
(true-or-false? t (atom (make-array '(4 4)))))
|
||||||
|
|
||||||
(define-test functionp
|
(define-test functionp
|
||||||
;; The function FUNCTIONP returns true if its arguments is a function.
|
;; The function FUNCTIONP returns true if its arguments is a function.
|
||||||
(assert-true (functionp (lambda (a b c) (+ a b c))))
|
(assert-true (functionp (lambda (a b c) (+ a b c))))
|
||||||
(true-or-false? ____ (functionp #'make-array))
|
(true-or-false? t (functionp #'make-array))
|
||||||
(true-or-false? ____ (functionp 'make-array))
|
(true-or-false? nil (functionp 'make-array)) ; I didn't get this one, looks like that's not function
|
||||||
(true-or-false? ____ (functionp (lambda (x) (* x x))))
|
; how's that in Elisp though?
|
||||||
(true-or-false? ____ (functionp '(lambda (x) (* x x))))
|
; in Elisp both #' and ' over function is a function, cool
|
||||||
(true-or-false? ____ (functionp '(1 2 3)))
|
(true-or-false? t (functionp (lambda (x) (* x x))))
|
||||||
(true-or-false? ____ (functionp t)))
|
(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
|
(define-test other-type-predicates
|
||||||
;; Lisp defines multiple type predicates for standard types..
|
;; Lisp defines multiple type predicates for standard types..
|
||||||
(true-or-false? ____ (numberp 999))
|
(true-or-false? t (numberp 999))
|
||||||
(true-or-false? ____ (listp '(9 9 9)))
|
(true-or-false? t (listp '(9 9 9)))
|
||||||
(true-or-false? ____ (integerp 999))
|
(true-or-false? t (integerp 999))
|
||||||
(true-or-false? ____ (rationalp 9/99))
|
(true-or-false? t (rationalp 9/99))
|
||||||
(true-or-false? ____ (floatp 9.99))
|
(true-or-false? t (floatp 9.99))
|
||||||
(true-or-false? ____ (stringp "nine nine nine"))
|
(true-or-false? t (stringp "nine nine nine"))
|
||||||
(true-or-false? ____ (characterp #\9))
|
(true-or-false? t (characterp #\9))
|
||||||
(true-or-false? ____ (bit-vector-p #*01001)))
|
(true-or-false? t (bit-vector-p #*01001)))
|
||||||
|
|
||||||
(define-test guess-that-type
|
(define-test guess-that-type
|
||||||
;; Fill in the blank with a type specifier that satisfies the following tests.
|
;; Fill in the blank with a type specifier that satisfies the following tests.
|
||||||
(let ((type ____))
|
(let ((type '(simple-array array (5 3 *)))) ; this needs reallife context for me to get
|
||||||
(assert-true (subtypep type '(simple-array * (* 3 *))))
|
(assert-true (subtypep type '(simple-array * (* 3 *))))
|
||||||
(assert-true (subtypep type '(simple-array * (5 * *))))
|
(assert-true (subtypep type '(simple-array * (5 * *))))
|
||||||
(assert-true (subtypep type '(simple-array array *)))
|
(assert-true (subtypep type '(simple-array array *)))
|
||||||
|
|
Loading…
Reference in New Issue