I’ve been learning Lisp for several months now, but this summer I decided to really buckle down and put some effort into it. I definitely like Lisp, and I don’t feel like I even know very much of it. It feels very clean to me; it almost feels more like doing math than programming. I haven’t gotten too far with doing AI in Lisp yet, because I’ve spent most of my time getting to know the language. Things like defun, let, do, dolist, dotimes seem pretty standard for a language, just with different names.
However, things like lambda and defmacro really opened my mind up! These concepts were so different from anything I knew previously that for a while after I read them I though “Man, no one would ever use these because there are better ways to do the things these can do.” What was exciting was when I realized how I didn’t fully grasp their capabilities, and suddenly was able to imagine new things I could do with the power of lambda and especially defmacro.
I’m thinking of a couple projects to do. One of them came out of the Paradigms of Artificial Intelligence Programming book I have. The other one I came up with on my own. My idea is to have a “dungeon solver” where there is a map in some data structure (most likely a list, but we’ll see) that contains zeros for open space, ones for walls, and a goal. Initially I think I’ll just have a little guy randomly walking around the dungeon looking for the goal. Later I may add some more intelligence to the system, such as not going back to places already been unless necessary.
Below I’ve got some code I wrote that deals with finding all the factors of a number and also determining if two numbers are coprimes. Lastly there is a function that finds primes up to a given number you supply. It is not the fastest way to do it, but since I had the factors function already it was so tempting to write the find-primes function that I just went ahead and did it. Thanks, thanks, thanks to Jon Rowe for helping me learn Lisp. Hes awesome, I highly recommend him if you’re looking for a tutor. Alright, heres the code (check the end of the post for a neatly formatted file)!
(defun factors (num)
"This function will find the factors of the argument num."
(let ((l '()))
(do ((current 1 (1+ current)))
((> current (/ num current)))
(if (= 0 (mod num current))
(if (= current (/ num current))
(setf l (append l (list current)))
(setf l (append l (list current (/ num current)))))))
(sort l #'< ))) (defun coprimesp (num1 num2) "Returns t if numbers are coprimes, nil otherwise." (let ((flag t)) (dolist (atom1 (rest (factors num1))) (dolist (atom2 (rest (factors num2))) (if (= atom1 atom2) (setf flag nil)))) flag)) (defun find-primes (top) "Finds primes starting at one and searching up to given number, top." (let ((l '())) (dotimes (x top) (if (= 2 (length (factors x))) (setf l (append l (list x))))) l))
I’m using Lisp in a Box to code all this. Please let me know if you know how to make it so the REPL doesn’t limit output like it does here:
CL-USER> (find-primes 1000)
(2 3 5 7 11 13 17 19 23 29 …)
Also, if you’re an emacs pro and know how to make emacs collapse parenthesis please leave a comment or email me! I’d like to turn this:
(defun find-primes (top)
(let ((l ‘()))
(dotimes (x top)
(if (= 2 (length (factors x)))
(setf l (append l (list x)))))
into something more like this:
(defun find-primes ()
( ( (()))
This would really help a lot with parenthesis matching. Well thats it for this post, have a great summer and please leave comments!
(For some reason the code formatting isn’t working well with wordpress, so I’ve included this file with nice formatting.)