Reputation: 2849
I am a beginner in Lisp. I have two functions
, a defparameter
, and a defstruct
. Every time a book is passed to inputBook
I would like the title of the book (the string) to become the name of the defparameter
. Is this possible?
I have tried to hard code a string in like below where it says "MobyDick" but I get an error. So is this even possible?
I tried to simply use the parameter passed title
but if you try to pass another book into the function, they are both assigned to title
but the last one passed will print, not the first and not both. So how can I do it so that I have as many "books" without a list or a hash table?
If the latter is not possible, how could I alter the code so that a defparameter
would be created (unique) to any number of books and accessible through the getAuthor
function? Does that make sense? (Please see the functions below.)
(defstruct book()
(title) ;;title of the book, type string
(author) ;;author of the book, type string
(date)) ;; date of the book, type string or int
(defun inputBook(title author month year)
(defparameter "MobyDick" ;;I want this to use the parameter title
(make-book :title title
:author author
:date '(month year))))
(defun getAuthor (book)
(write (book-author book)))
Many many thanks in advance! Also, I am a beginner beginner. I have been learning through googling and I am stumped here.
Upvotes: 0
Views: 338
Reputation:
You probably want something which looks like this, rather than some madness of top-level variables.
(defvar *books* (make-hash-table))
(defun bookp (title)
(nth-value 1 (gethash title *books*)))
(defun remove-book (title)
(remhash title *books*))
(defun book (title)
(nth-value 0 (gethash title *books*)))
(defun (setf book) (new title)
(setf (gethash title *books*) new))
Then, for instance:
> (setf (book 'moby) (make-book ...))
> (book 'moby)
> (bookp 'moby)
> (remove-book 'moby)
Upvotes: 4
Reputation: 139251
Using symbols with arbitrary names has the typical drawback: you can overwrite the values of existing symbols. Thus it would be useful to have a separate package for it, which does not import symbols from other packages.
Better would be to have a hash table, which would map from a string to the book object.
Sketch of code with symbols:
(defstruct book
(title) ;; title of the book, type string
(author) ;; author of the book, type string
(date)) ;; date of the book, type list
(defun input-book (title author month year)
(setf (symbol-value (intern title))
(make-book :title title
:author author
:date (list month year))))
Example:
CL-USER 52 > (input-book "Lisp Style & Design"
"Molly M. Miller, Eric Benson"
1 1990)
#S(BOOK :TITLE "Lisp Style & Design"
:AUTHOR "Molly M. Miller, Eric Benson"
:DATE (1 1990))
CL-USER 53 > (book-author (symbol-value '|Lisp Style & Design|))
"Molly M. Miller, Eric Benson"
CL-USER 54 > (book-author |Lisp Style & Design|)
"Molly M. Miller, Eric Benson"
Upvotes: 2