This program was taken from Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp by Peter Norvig, 1992, Morgan Kaufmann Publishers, Inc. If I compile and load it into a debug window, how would I use it?
; This function returns a random element of the list choices
(defun random-elt (choices)
"Choose an element from a list at random."
;; elt returns the (n + 1)th element of the list choices
;; random returns a random integer no large than the number of
;; elements in the list choices
(elt choices (random (length choices))))
; This function returns a random element of the given set and returns
; it in a list
(defun one-of (set)
"Pick one element of set, and make a list of it."
(list (random-elt set)))
; Define a sentence as a noun-phrase + verb phrase
(defun sentence () (append (noun-phrase) (verb-phrase)))
; Define a noun phrase as an article + noun
(defun noun-phrase () (append (Article) (Noun)))
; Define a verb phrase as a verb + a noun phrase
(defun verb-phrase () (append (Verb) (noun-phrase)))
; This function returns a randomly selected article
(defun Article () (one-of '(the a)))
; This function returns a randomly selected noun
(defun Noun () (one-of '(man ball woman table)))
; This function returns a randomly selected verb
(defun Verb () (one-of '(hit took saw liked)))
Looking at that code I see the only function not used in another is sentence. If you enter (sentence) you'll get a random sentence like:
(sentence) ;==> (THE WOMAN TOOK A TABLE)
Typically I would edit the file using something like SLIME/Emacs, Clozure CL, LispWorks, Allegro CL ... or anything other which has an editor which can talk to Common Lisp.
If you put the code in a buffer, then compile the buffer. In SLIME/Emacs use control-c control-k or meta-x slime-compile-and-load-file. This compiles the whole file and loads the compiled code into the running inferior Common Lisp.
In the LispWorks IDE I would just go into the buffer menu and execute compile.
Then go to the listener (aka REPL) and execute (sentence). Page 34 to 38 in Norvig's excellent book explain the code and how to use it in detail.
Related
I want to define a function in racket that reads a racket code from an input file (for example "input.txt"), and runs the racket code and display the output. I tried doing this with the “read” function. But it only reads the first expression.
What you probably want is load. However it's mildly fiddly to get load to print the values of individual forms. Here is a simpler and probably not completely correct version of load which does this:
(define (load/print path
#:namespace (namespace (current-namespace))
#:printer (printer println)
#:suppress-void (suppress-void #t))
;; If the file starts with #lang &c this will let it be read, but the
;; printing won't generally be helpful in that case as it will be
;; read usually as a single (module ...) form.
(parameterize ([read-accept-reader #t]
[read-accept-lang #t])
(call-with-input-file
path
(λ (in)
(for ([form (in-port (λ (p) (read-syntax path p)) in)])
(call-with-values
(thunk (eval form namespace))
(λ vals
(for ([v (in-list vals)])
(unless (and suppress-void (void? v))
(printer v))))))
path))))
So given a file containing
1
(values 2 3 4)
"foo"
> (load/print "/path/to/my/file")
1
2
3
4
"foo"
"/tmp/file.rkt"
I've been trying to write a recursive loop in clojure that will print me out the very last number in the list. The point is not that I need to get the last number (for which I'm sure there's a built in function for that) but that I want to better understand recursion and macros in clojure. So I have this macro...
(defmacro loop-do [the-list]
`(if (= (count '~the-list) 1)
(println (first '~the-list))
(loop-do (rest '~the-list))))
But I get a stackoverflow error. What am I doing wrong?
How will people use your macro?
Somewhere, someone will call:
(loop-do list)
As a piece of code, those are only two symbols in a list. The first one is recognized as your macro, and the second one, list, is a symbol that represents a variable that will be bound at runtime. But your macro only knows that this is a symbol.
The same goes for:
(loop-do (compute-something))
The argument is a form, but you do not want to get the last element of that form, only the last element of the list obtained after evaluating the code.
So: you only know that in your macro, the-list will be bound to an expression that, at runtime, will have to be a list. You cannot use the-list as-if it was a list itself: neither (count 'list) nor (count '(compute-something)) does what you want.
You could expand into (count list) or (count (compute-something)), though, but the result would only be computed at runtime. The job of the macro is only to produce code.
Recursive macros
Macros are not recursive: they expand into recursive calls.
(and a b c)
might expand as:
(let [a0 a] (if a0 a0 (and b c)))
The macroexpansion process is a fixpoint that should terminate, but the macro does not call itself (what would that mean, would you expand the code while defining the macro?). A macro that is "recursive" as-in "expands into recursive invocations" should have a base case where it does not expand into itself (independently of what will, or will not, happen at runtime).
(loop-do x)
... will be replaced by:
(loop-do (rest 'x))
... and that will be expanded again.
That's why the comments say the size actually grows, and that's why you have a stackoverflow error: macroexpansion never finds a fixpoint.
Debugging macros
You have a stackoverflow error. How do you debug that?
Use macroexpand-1, which only performs one pass of macroexpansion:
(macroexpand-1 '(loop-do x))
=> (if (clojure.core/= (clojure.core/count (quote x)) 1)
(clojure.core/println (clojure.core/first (quote x)))
(user/loop-do (clojure.core/rest (quote x))))
You can see that the generated code still contains a call to usr/loop-do , but that the argument is (clojure.core/rest (quote x)). That's the symptom you should be looking for.
I want to print just the characters from a LISP list, and I need to verify if an atom is not a number, in CLisp. How can I do this?
Here’s how to loop through a list and check for things that aren’t numbers:
(loop for thing in list
do (if (numberp thing)
(format nil “I’m a number: ~a~%” thing)
(format nil “Not a number!~%”)
format is analogous to printf in C. And loop is a macro for iteration in Common Lisp. Explaining how that works beside saying “read the keywords as in English and guess what they mean” is beyond the scope of this answer and there are plenty of explanations of loop online, for example the “Loop for black belts” chapter of Peter Seibel’s Practical Common Lisp with is available free online.
Here is how one can write only the characters in a list. For the sake of variety this one explicitly defines a function and uses higher order list manipulation functions instead of explicit loops. Thus it is probably slower.
(defun print-characters (list)
(let ((chars (remove-if-not #’characterp list)))
(mapc #’write-char chars)))
remove-if-not returns a new list with the same contents as the input except it only includes the elements for which the predicate (in this case characterp) returns true. characterp returns true if and only if its input is a character.
mapc applies a function to each element of a list, discarding the return value. In this case write-char which when called with one argument writes a character to *standard-output*.
I'm assuming you're asking: "given a list of items, how do I filter out only the numbers in the list?"
If yes, here's a sample session:
Given a list:
CL-USER 11 > (setq mylist '(4 "foo" 10 'bar 2.5 "baz"))
(4 "foo" 10 (QUOTE BAR) 2.5 "baz")
To get all the numbers:
CL-USER 13 > (remove-if-not #'numberp mylist)
(4 10 2.5)
And (for completeness) to do the opposite (i.e. remove the numbers):
CL-USER 14 > (remove-if #'numberp mylist)
("foo" (QUOTE BAR) "baz")
I am trying to learn common lisp through paradigms of artificial intelligence. one of the exercises in the book was to define a function that would return the last name of a given list without a certain suffix or word. As an example if the list contained bruce banner, phd it would return banner. here is my solution, however this would still return the last element regardless if it was a suffix or not
(Defun last-name (name)
(if (member (last name) *suffix*)
(Last-name (butlast name))
(last name)))
where
(defparameter *suffix* '( MD PHD DR))
a similar exercise was presented in the book omitting a prefix in a list using 'rest' instead of 'butlast' and returning the first element. That worked perfectly fine.
(defparameter *titles* '( Mr MRS MS SIR MADAM DR ADMIRAL MAJOR GENRAL ))
(Defun first-name (name)
(if (member (first name) *titles*)
(first-name (rest name))
(first name)))
I am not sure if I am missing anything in the last-name function or if my logic is incorrect. Any help is greatly appreciated!
Apologies if the text is long, it is my first post and I was not sure what level of detail I should include.
Thank you.
The reason is that last does not return the last element of a list, but a list containing the last element. That is:
(last '(bruce banner phd))
;; -> (PHD), not PHD
Actually, last gets an optional argument n after the list, argument which is set to 1 by default, and returns a list with the last n elements of the first parameter (see the manual).
So the function member does not return true.
Try to change the function in:
(defun last-name (name)
(if (member (car (last name)) *suffix*)
(Last-name (butlast name))
(car (last name))))
Can someone explain why I get different results for the following simple program with sbcl and clisp? Is what I am doing undefined by the language, or is one of the two lisp interpreters wrong?
; Modify the car of the passed-in list
(defun modify (a) (setf (car a) 123))
; Create a list and print car before and after calling modify
(defun testit () (let ((a '(0)))
(print (car a))
(modify a)
(print (car a))))
(testit)
SBCL (version 1.0.51) produces:
0
0
CLISP (version 2.49) produces (what I would expect):
0
123
I agree with Seth's and Vsevolod's comments in that this behavior is due to your modification of literal data. Try using (list 0) instead of '(0). Questions relating to this come up relatively frequently, so I'll quote the HyperSpec here.
3.7.1 Modification of Literal Objects:
The consequences are undefined if literal objects are destructively
modified.
The definition of "literal":
literal adj. (of an object) referenced directly in a program rather
than being computed by the program; that is, appearing as data in a
quote form, or, if the object is a self-evaluating object, appearing
as unquoted data. ``In the form (cons "one" '("two")), the expressions
"one", ("two"), and "two" are literal objects.''
Note that often (in many implementations), if you modify literal values, you'll really modify them in the code itself – writing self modifying code. Your example code will not work as you expect.
Your example code in CCL:
CL-USER> (defun modify (a) (setf (car a) 123))
MODIFY
CL-USER> (defun testit ()
(let ((a '(0)))
(print (car a))
(modify a)
(print (car a))))
TESTIT
CL-USER> (testit)
0
123
123
CL-USER> (testit)
123
123
123
Take a look at the second evaluation of testit, where the let itself really already contains the modified value, thus the first print also yields 123.
Also see: Lisp, cons and (number . number) difference, where I explained this in more detail, or the question linked in Vsevolod's comment above.