20 Circular Data
Books & Authors
Books have: title : String author : Author
Authors have: name : String books : [Listof Book]
;; A Book is (book% String Author) ;; An Author is (author% String [Listof Book])
But this is wrong: the Rose has written a book, but the author object doesn’t know about it.
Do we need books to know the author? Yes.
;; A Book is (book% String Author) (define-class book% (fields title author)) ;; An Author is (author% String [Listof Book]) (define-class author% (fields name books)) (define rose (author% "Rose" empty)) (define reign (book% "Reign of Roquet" rose))
reign rose
Question: Does reign contain a copy of rose, or are they all the same rose? Answer: always the same, because we use the name rose, we didn’t construct a new one.
(define rose (author% "Rose" empty)) (define reign (book% "Reign of Roquet" rose)) (rose . add-book reign)
How does it print?
> rose #0=(object:author% "Rose" (list (object:book% "Reign of Roquet" #0#)))
> reign #0=(object:book% "Reign of Roquet" (object:author% "Rose" '(#0#)))
See graph-style printing.
But every times we construct a book with an author, we want to use add-book. So, let’s use the constructor.
(constructor (t a) (fields t a) (send a add-book this))
In the first expression, we cannot use this, and we must produce the result using fields. Later, we can use this, and we get the desired result.